diff --git a/CHANGELOG.md b/CHANGELOG.md index b992eff93..0efffb254 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -57,6 +57,8 @@ Thankyou! --> ### Deprecated 1. Deprecated `is_src_dst_assignment_known` dictionary attribute and its usage in `Network Activity` in favour of `initiator_id`. [#1598](https://github.com/ocsf/ocsf-schema/pull/1598) +1. Deprecated `message` attribute in the `http_response` object. The `code` and `status` attributes already convey the HTTP status code and reason phrase. [#1616](https://github.com/ocsf/ocsf-schema/pull/1616) + ### Misc 1. Added static anti-pattern detection, LLM-to-static learning pipeline, and deprecated attribute filtering to the automated PR review workflows. [#1599](https://github.com/ocsf/ocsf-schema/pull/1599) diff --git a/dictionary.json b/dictionary.json index 4c5f1e496..2f7c263da 100644 --- a/dictionary.json +++ b/dictionary.json @@ -145,7 +145,7 @@ }, "activity_id": { "caption": "Activity ID", - "description": "The normalized identifier of the activity that triggered the event.", + "description": "The normalized identifier of the activity that triggered the event. Each event class defines its own set of activity values. Use 0 (Unknown) when the activity cannot be determined. Use 99 (Other) when the activity does not match any defined value, in which case activity_name must be populated with the source-specific label.", "sibling": "activity_name", "type": "integer_t", "enum": { @@ -164,7 +164,7 @@ }, "activity_name": { "caption": "Activity", - "description": "The event activity name, as defined by the activity_id.", + "description": "The event activity name, as defined by the activity_id. When activity_id is 99 (Other), this attribute must contain the source-specific activity label. For all other activity_id values, this must match the caption defined for that activity_id enum value.", "type": "string_t" }, "actor": { @@ -1070,12 +1070,12 @@ }, "category_name": { "caption": "Category", - "description": "The event category name, as defined by category_uid value.", + "description": "The event category name, as defined by the category_uid value. The value must match the caption defined for the corresponding category_uid enum value (e.g., \"Findings\" for category_uid: 2).", "type": "string_t" }, "category_uid": { "caption": "Category ID", - "description": "The category unique identifier of the event.", + "description": "The category unique identifier of the event. Each event class belongs to exactly one category. Producers and mappers must set this to the category defined by the event class being used.", "sibling": "category_name", "type": "integer_t" }, @@ -1196,12 +1196,12 @@ }, "class_name": { "caption": "Class", - "description": "The event class name, as defined by class_uid value.", + "description": "The event class name, as defined by the class_uid value. The value must match the caption defined for the corresponding class_uid (e.g., \"Detection Finding\" for class_uid: 2004).", "type": "string_t" }, "class_uid": { "caption": "Class ID", - "description": "The unique identifier of a class. A class describes the attributes available in an event.", + "description": "The unique identifier of a class. A class describes the attributes available in an event. Producers and mappers must set this to the uid defined in the event class definition. For example, Detection Finding is 2004.", "sibling": "class_name", "type": "integer_t" }, @@ -1529,7 +1529,7 @@ }, "count": { "caption": "Count", - "description": "The number of times that events in the same logical group occurred during the event Start Time to End Time period.", + "description": "The count of a grouped or aggregated item. See specific usage.", "type": "integer_t" }, "countermeasures": { @@ -3935,7 +3935,7 @@ }, "logged_time": { "caption": "Logged Time", - "description": "

The time when the logging system collected and logged the event.

This attribute is distinct from the event time in that event time typically contain the time extracted from the original event. Most of the time, these two times will be different.", + "description": "The time when a system in the event pipeline collected and logged the event. See specific usage.", "type": "timestamp_t" }, "loggers": { @@ -4088,7 +4088,7 @@ }, "message": { "caption": "Message", - "description": "The description of the event/finding, as defined by the source.", + "description": "The descriptive message associated with the event or object. See specific usage.", "type": "string_t" }, "message_context": { @@ -4122,7 +4122,7 @@ }, "metadata": { "caption": "Metadata", - "description": "The metadata associated with the event or a finding.", + "description": "The metadata object describes the event producer, schema version, and processing information. Producers and mappers must populate metadata.product to identify the data source, and metadata.version to indicate the OCSF schema version used. Consumers rely on this to interpret the event correctly.", "type": "metadata" }, "metadata_endpoint": { @@ -4331,7 +4331,7 @@ }, "observables": { "caption": "Observables", - "description": "The observables associated with the event or a finding.", + "description": "The observables array surfaces key indicators and entities from the event or finding in a single, consistent location for downstream correlation and detection. Each entry references an attribute path within the event (e.g., src_endpoint.ip) along with its type and value, enabling consumers to extract IOCs without parsing the full event structure.", "type": "observable", "references": [ { @@ -4487,7 +4487,7 @@ }, "original_time": { "caption": "Original Time", - "description": "The original event time as reported by the event source. For example, the time in the original format from system event log such as Syslog on Unix/Linux and the System event file on Windows. Omit if event is generated instead of collected via logs.", + "description": "The original event time as reported by the event source, preserved as a pass-through string in its native format (e.g., Syslog timestamp, Windows event time). This is not normalized to timestamp_t — the normalized equivalent is the base event time attribute. Omit if the event is generated rather than collected via logs.", "type": "string_t" }, "os": { @@ -4895,7 +4895,7 @@ }, "processed_time": { "caption": "Processed Time", - "description": "The event processed time, such as an ETL operation.", + "description": "The time when the event was processed by an intermediate system, such as an ETL pipeline or event processor. See specific usage.", "type": "timestamp_t" }, "product": { @@ -5226,17 +5226,17 @@ }, "raw_data": { "caption": "Raw Data", - "description": "The raw event/finding data as received from the source.", + "description": "The original event/finding data as received from the source, before normalization into OCSF. Populate this with the verbatim log line, JSON payload, or other native format for forensic and debugging purposes. This field is not intended for structured querying — use the normalized OCSF attributes instead.", "type": "string_t" }, "raw_data_hash": { "caption": "Raw Data Hash", - "description": "The hash, which describes the content of the raw_data field.", + "description": "A fingerprint (hash) of the raw_data content. Use this to verify the integrity of the original event data or to deduplicate events.", "type": "fingerprint" }, "raw_data_size": { "caption": "Raw Data Size", - "description": "The size of the raw data which was transformed into an OCSF event, in bytes.", + "description": "The size of the original event data (as captured in raw_data) in bytes, before OCSF normalization. Useful for metering and capacity planning.", "type": "long_t" }, "raw_header": { @@ -5952,7 +5952,7 @@ }, "severity": { "caption": "Severity", - "description": "The event/finding severity, normalized to the caption of the severity_id value. In the case of 'Other', it is defined by the source.", + "description": "The event/finding severity label, normalized to the caption of the severity_id value. When severity_id is 99 (Other), this attribute must contain the source-specific severity label. For all other values, this should match the caption defined for that severity_id enum value (e.g., \"High\" for severity_id: 4).", "type": "string_t" }, "severity_id": { @@ -6268,28 +6268,28 @@ }, "status": { "caption": "Status", - "description": "The event status, normalized to the caption of the status_id value. In the case of 'Other', it is defined by the event source.", + "description": "The status label, normalized to the caption of the status_id value. When status_id is 99 (Other), this attribute must contain a source-specific status label. See specific usage.", "type": "string_t" }, "status_code": { "caption": "Status Code", - "description": "The event status code, as reported by the event source.

For example, in a Windows Failed Authentication event, this would be the value of 'Failure Code', e.g. 0x18.", + "description": "The source-specific status or error code. This preserves the original code for detailed troubleshooting beyond what status_id conveys. See specific usage.", "type": "string_t" }, "status_detail": { "caption": "Status Detail", - "description": "The status detail contains additional information about the event/finding outcome.", + "description": "Additional context about the outcome, beyond the normalized status_id and source-specific status_code. See specific usage.", "type": "string_t" }, "status_details": { "caption": "Status Details", - "description": "A list of descriptions, containing additional information about the event/finding status.", + "description": "A list of descriptions providing additional context about the outcome. See specific usage.", "type": "string_t", "is_array": true }, "status_id": { "caption": "Status ID", - "description": "The normalized identifier of the event status.", + "description": "The normalized status identifier. See specific usage.", "sibling": "status", "type": "integer_t", "enum": { @@ -6297,12 +6297,6 @@ "caption": "Unknown", "description": "The status is unknown." }, - "1": { - "caption": "Success" - }, - "2": { - "caption": "Failure" - }, "99": { "caption": "Other", "description": "The status is not mapped. See the status attribute, which contains a data source specific value." @@ -6600,7 +6594,7 @@ }, "time": { "caption": "Event Time", - "description": "The normalized event occurrence time or the finding creation time.", + "description": "The normalized event occurrence time. See specific usage.", "type": "timestamp_t" }, "timespan": { @@ -6610,7 +6604,7 @@ }, "timezone_offset": { "caption": "Timezone Offset", - "description": "The number of minutes that the reported event time is ahead or behind UTC, in the range -1,080 to +1,080.", + "description": "The number of minutes that the reported event time is ahead or behind UTC, in the range -1,080 to +1,080. This allows consumers to reconstruct the local time at the event source. For example, US Eastern Standard Time is -300. Populate this when the source provides local time zone information.", "type": "integer_t" }, "title": { @@ -6787,12 +6781,12 @@ }, "type_name": { "caption": "Type Name", - "description": "The event/finding type name, as defined by the type_uid.", + "description": "The event/finding type name, combining the class and activity (e.g., \"Detection Finding: Create\"). The value must match the class_name and activity_name joined by \": \".", "type": "string_t" }, "type_uid": { "caption": "Type ID", - "description": "The event/finding type ID. It identifies the event's semantics and structure. The value is calculated by the logging system as: class_uid * 100 + activity_id.", + "description": "The event/finding type ID. It identifies the event's semantics and structure. Producers and mappers must compute this as class_uid * 100 + activity_id. It uniquely identifies the combination of event class and activity across the entire schema. For example, Detection Finding: Create is 200401.", "sibling": "type_name", "type": "long_t" }, @@ -6845,7 +6839,7 @@ }, "unmapped": { "caption": "Unmapped Data", - "description": "The attributes that are not mapped to the event schema. The names and values of those attributes are specific to the event source.", + "description": "A container for source-specific attributes that do not map to any defined OCSF attribute. Use this to preserve valuable source data that would otherwise be lost during normalization. The keys and values are specific to the event source. Consumers should not rely on a stable structure within this field.", "type": "object" }, "untruncated_size": { diff --git a/events/base_event.json b/events/base_event.json index 559bc9088..eb36d0e07 100644 --- a/events/base_event.json +++ b/events/base_event.json @@ -54,16 +54,17 @@ } }, "count": { + "description": "The number of events aggregated into this single record. Only populate for aggregate events. When set, start_time and end_time should also be provided to define the aggregation window.", "group": "occurrence", "requirement": "optional" }, "duration": { - "description": "The event duration or aggregate time, the amount of time the event covers from start_time to end_time in milliseconds.", + "description": "The elapsed time of the aggregation window in milliseconds, from start_time to end_time. Only populate for aggregate events (count > 1). The value should equal end_time - start_time.", "group": "occurrence", "requirement": "optional" }, "end_time": { - "description": "The end time of a time period, or the time of the most recent event included in the aggregate event.", + "description": "The time of the most recent event in an aggregate (count > 1). Do not populate for discrete, point-in-time events — use time alone. Subclasses such as findings may redefine this for their own time-range semantics.", "group": "occurrence", "requirement": "optional" }, @@ -72,6 +73,7 @@ "requirement": "optional" }, "message": { + "description": "A human-readable description of the event, as defined by the source. This should be a concise, meaningful summary suitable for display in a UI or alert notification — not a raw log line. For example: \"User john_doe logged in from 10.0.0.1.\" rather than a raw syslog string.", "group": "primary", "requirement": "recommended" }, @@ -104,27 +106,42 @@ "requirement": "required" }, "start_time": { - "description": "The start time of a time period, or the time of the least recent event included in the aggregate event.", + "description": "The time of the earliest event in an aggregate (count > 1). Do not populate for discrete, point-in-time events — use time alone. Subclasses such as findings may redefine this for their own time-range semantics.", "group": "occurrence", "requirement": "optional" }, "status": { + "description": "The event status label, normalized to the caption of the status_id value. When status_id is 99 (Other), this attribute must contain the source-specific status label. For all other values, this must match the caption defined for that status_id enum value (e.g., \"Success\" for status_id: 1).", "group": "primary", "requirement": "recommended" }, "status_code": { + "description": "The source-specific status or error code as reported by the event source. For example, a Windows logon failure code (0x18), an HTTP response code (403), or an AWS API error code. This preserves the original code for detailed troubleshooting beyond what status_id conveys.", "group": "primary", "requirement": "recommended" }, "status_detail": { + "description": "A human-readable description providing additional context about the event outcome. Use this to convey details that go beyond the normalized status_id and source-specific status_code, such as a failure reason or error message. For example: \"Account locked after 5 failed attempts.\".", "group": "primary", "requirement": "recommended" }, "status_id": { + "description": "The normalized status of the event outcome. Use this family of attributes to convey the outcome of the activity described by the event. Producers should map their source outcome to 1 (Success) or 2 (Failure). Use 0 (Unknown) when the outcome cannot be determined, and 99 (Other) with a populated status string when the source value does not map cleanly.", "group": "primary", - "requirement": "recommended" + "requirement": "recommended", + "enum": { + "1": { + "caption": "Success", + "description": "The activity completed successfully." + }, + "2": { + "caption": "Failure", + "description": "The activity failed." + } + } }, "time": { + "description": "The primary timestamp of the event — when the activity actually occurred at the source. This does not capture when the event record was created or serialized by the source system; for event lifecycle timestamps such as ingestion and processing, use metadata.logged_time and metadata.processed_time respectively, or the equivalent attributes in the metadata.loggers array when recording pipeline stages. For aggregate events (count > 1), set this to start_time (the earliest OCSF time in the aggregate) to preserve causal ordering and consistent timeline alignment. Note: finding classes redefine time as the finding creation time rather than the activity occurrence time. This must be a UTC epoch value in milliseconds (e.g., 1776881335332). Mappers should use the most precise and authoritative timestamp available from the source.", "group": "occurrence", "requirement": "required" }, diff --git a/events/findings/finding.json b/events/findings/finding.json index 7e649624a..c98f19e1b 100644 --- a/events/findings/finding.json +++ b/events/findings/finding.json @@ -9,7 +9,7 @@ "profiles/incident.json" ], "activity_id": { - "description": "The normalized identifier of the finding activity.", + "description": "The normalized identifier of the finding activity. Use 1 (Create) when a finding is first generated, 2 (Update) when an existing finding is modified (e.g., severity change, new evidence), and 3 (Close) when a finding is resolved or dismissed.", "enum": { "1": { "caption": "Create", @@ -26,7 +26,7 @@ } }, "activity_name": { - "description": "The finding activity name, as defined by the activity_id." + "description": "The finding activity name, as defined by the activity_id. When activity_id is 99 (Other), this must contain the source-specific activity label." }, "comment": { "description": "A user provided comment about the finding.", @@ -55,7 +55,7 @@ "profile": null }, "end_time": { - "description": "The time of the most recent event included in the finding.", + "description": "The time of the most recent event or finding that contributed to this finding.", "requirement": "optional" }, "finding_info": { @@ -63,16 +63,19 @@ "requirement": "required" }, "start_time": { - "description": "The time of the least recent event included in the finding.", + "description": "The time of the earliest event or finding that contributed to this finding.", "requirement": "optional" }, + "time": { + "description": "The finding creation time — when the finding was first generated, not when the underlying activity occurred. For the time range of contributing events, use start_time and end_time." + }, "status": { - "description": "The normalized status of the Finding set by the consumer normalized to the caption of the status_id value. In the case of 'Other', it is defined by the source.", + "description": "The finding lifecycle status label, normalized to the caption of the status_id value. When status_id is 99 (Other), this must contain the source-specific status label.", "group": "context", "requirement": "optional" }, "status_id": { - "description": "The normalized status identifier of the Finding, set by the consumer.", + "description": "The normalized finding lifecycle status identifier. Unlike the status of an activity event, which indicates the success or failure of the activity, finding status tracks the review and triage workflow: whether the finding is new, being investigated, suppressed, or resolved. Producers should set this to reflect the current state of the finding in their system (e.g., 1 for newly created findings, 4 when remediated).", "group": "context", "requirement": "recommended", "enum": { diff --git a/events/findings/incident_finding.json b/events/findings/incident_finding.json index 169d7f740..685174d1c 100644 --- a/events/findings/incident_finding.json +++ b/events/findings/incident_finding.json @@ -7,7 +7,7 @@ "name": "incident_finding", "attributes": { "activity_id": { - "description": "The normalized identifier of the Incident activity.", + "description": "The normalized identifier of the incident activity. Use 1 (Create) when an incident is first opened, 2 (Update) when an existing incident is modified (e.g., new findings added, priority changed, assignee updated), and 3 (Close) when the incident is resolved.", "requirement": "required", "enum": { "1": { @@ -25,7 +25,7 @@ } }, "activity_name": { - "description": "The Incident activity name, as defined by the activity_id.", + "description": "The incident activity name, as defined by the activity_id. When activity_id is 99 (Other), this must contain the source-specific activity label.", "requirement": "optional" }, "assignee": { @@ -68,7 +68,7 @@ "requirement": "recommended" }, "end_time": { - "description": "The time of the most recent event included in the incident.", + "description": "The time of the most recent event or finding that contributed to this incident.", "requirement": "optional" }, "finding_info_list": { @@ -105,16 +105,19 @@ "requirement": "recommended" }, "start_time": { - "description": "The time of the least recent event included in the incident.", + "description": "The time of the earliest event or finding that contributed to this incident.", "requirement": "optional" }, + "time": { + "description": "The incident creation time — when the incident was first opened, not when the underlying activity occurred. For the time range of contributing events, use start_time and end_time." + }, "status": { - "description": "The normalized status of the Incident normalized to the caption of the status_id value. In the case of 'Other', it is defined by the source.", + "description": "The incident lifecycle status label, normalized to the caption of the status_id value. When status_id is 99 (Other), this must contain the source-specific status label.", "group": "primary", "requirement": "recommended" }, "status_id": { - "description": "The normalized status identifier of the Incident.", + "description": "The normalized incident lifecycle status identifier. This tracks the incident management workflow from initial triage through resolution. Producers should set this to reflect the current state in their incident management system.", "group": "primary", "requirement": "required", "enum": { diff --git a/extensions/windows/objects/query_evidence.json b/extensions/windows/objects/query_evidence.json index db5e41987..c620eebe0 100644 --- a/extensions/windows/objects/query_evidence.json +++ b/extensions/windows/objects/query_evidence.json @@ -9,7 +9,7 @@ "requirement": "recommended" }, "reg_value": { - "description": "The registry key object describes a Windows registry value.", + "description": "The registry value object describes a Windows registry value.", "group": "primary", "requirement": "recommended" } diff --git a/objects/http_response.json b/objects/http_response.json index 89cd8ffa9..d076db668 100644 --- a/objects/http_response.json +++ b/objects/http_response.json @@ -28,6 +28,10 @@ "requirement": "optional" }, "message": { + "@deprecated": { + "since": "1.9.0", + "message": "Redundant with the code and status attributes, which together convey the HTTP status code and its reason phrase. Use code for the numeric value and status for the human-readable label." + }, "requirement": "optional" }, "status": { diff --git a/objects/logger.json b/objects/logger.json index 0fb553074..59958ee52 100644 --- a/objects/logger.json +++ b/objects/logger.json @@ -37,6 +37,7 @@ "requirement": "optional" }, "logged_time": { + "description": "The time when this logger received and logged the event. For the last logger in the pipeline, this value should match metadata.logged_time.", "requirement": "recommended" }, "name": { diff --git a/objects/metadata.json b/objects/metadata.json index 67be34dcf..7a25626a6 100644 --- a/objects/metadata.json +++ b/objects/metadata.json @@ -59,9 +59,11 @@ "requirement": "optional" }, "logged_time": { + "description": "The ultimate logged time in the event pipeline — when the event reached its final destination (e.g., SIEM, data lake). If loggers is populated, this should match the logged_time of the last entry in the loggers array. This is distinct from time (when the activity occurred) and processed_time (when an intermediate system processed the event).", "requirement": "optional" }, "loggers": { + "description": "An ordered array of Logger objects describing each hop in the event pipeline between the source and its final destination. Each entry captures the logging product, device, and timestamps (logged_time, transmit_time) at that stage. The last entry's logged_time should match metadata.logged_time.", "requirement": "optional" }, "modified_time": { @@ -76,6 +78,7 @@ "requirement": "recommended" }, "processed_time": { + "description": "The time when the event was processed by an intermediate system (e.g., ETL pipeline, event processor) before reaching its final destination. Can be used with logged_time to calculate queuing duration via total_queued_duration.", "requirement": "optional" }, "product": { diff --git a/objects/response.json b/objects/response.json index b388d5408..751a88020 100644 --- a/objects/response.json +++ b/objects/response.json @@ -25,6 +25,7 @@ "requirement": "optional" }, "message": { + "description": "The response message provided by the service or API.", "requirement": "recommended" } } diff --git a/profiles/datetime.json b/profiles/datetime.json index c099fe122..49ce4fe80 100644 --- a/profiles/datetime.json +++ b/profiles/datetime.json @@ -1,7 +1,13 @@ { "caption": "Date/Time", - "description": "This profile defines date/time attributes as defined in RFC-3339. For example 1985-04-12T23:20:50.52Z.", + "description": "When applied, this profile adds a sibling attribute of data type datetime_t (RFC-3339 string) wherever a timestamp_t attribute appears in the event class. This provides human-readable date/time representations alongside the epoch-millisecond timestamps. For example, time (timestamp_t) would gain a time_dt (datetime_t) sibling such as \"1985-04-12T23:20:50.52Z\".", "meta": "profile", "name": "datetime", + "references": [ + { + "description": "RFC-3339", + "url": "https://www.rfc-editor.org/rfc/rfc3339.html" + } + ], "attributes": {} -} \ No newline at end of file +} diff --git a/profiles/host.json b/profiles/host.json index 54cec3e1e..aa8d182b2 100644 --- a/profiles/host.json +++ b/profiles/host.json @@ -1,6 +1,6 @@ { "caption": "Host", - "description": "The attributes that identify host/device attributes.", + "description": "Adds host and actor context to event classes. Apply this profile when the event originates from or is observed on a specific host or device, and when the initiating user, process, or service is known. All event classes include this profile by default through the base event.", "meta": "profile", "name": "host", "annotations": { @@ -8,9 +8,11 @@ }, "attributes": { "actor": { + "description": "The user, process, or service that initiated the activity on the host. For system-level events this is typically a process; for IAM events it is typically a user or role.", "requirement": "optional" }, "device": { + "description": "The host or device where the activity was observed. Populate with details such as hostname, IP address, OS, and hardware identifiers when available from the source.", "requirement": "recommended" } }