Skip to content

feat(ocsf): emit AI inference events via ai_operation profile on ApiActivity [6003], bump schema to v1.8.0 - #2664

Open
zanetworker wants to merge 1 commit into
NVIDIA:mainfrom
zanetworker:feat/ocsf-ai-operation
Open

feat(ocsf): emit AI inference events via ai_operation profile on ApiActivity [6003], bump schema to v1.8.0#2664
zanetworker wants to merge 1 commit into
NVIDIA:mainfrom
zanetworker:feat/ocsf-ai-operation

Conversation

@zanetworker

@zanetworker zanetworker commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Emit OCSF events when the inference proxy routes model calls through inference.local. Uses the official ai_operation profile (introduced in OCSF v1.8.0) on ApiActivity [6003], which is the schema-correct class for this profile in v1.8.0.

No agent sandbox in the market produces AI-specific OCSF events today.

Related Issues

Approach

The OCSF ai_operation profile attaches AI metadata to existing event classes rather than defining a new class. In v1.8.0, ApiActivity [6003] officially supports the profile. An inference call IS an API activity, and in Splunk CIM, ApiActivity maps to the "Change" data model, naturally separating inference events from regular HTTP proxy traffic (which stays on HttpActivity [4002] / "Web").

Why not HttpActivity? HttpActivity [4002] only gets ai_operation in v1.9.0 (released Aug 3, 2026). No SIEM consumer supports v1.9.0 yet. ApiActivity has it in v1.8.0.

Why not a custom event class? The earlier approach used a custom AIOperationEvent with class_uid 7001, which conflicts with the official OCSF remediation_activity class. The profile-based approach avoids this and composes with existing SIEM data models.

Changes

openshell-ocsf crate:

  • objects/ai_model.rsAiModel struct (name, ai_provider, version, uid) matching the official OCSF ai_model object
  • events/base_event.rsai_model: Option<AiModel> field on BaseEventData (profile attachment point)
  • events/api_activity.rsApiActivityEvent struct with api_operation, http_request/response, endpoints, actor, action/disposition
  • builders/api_activity.rsApiActivityBuilder with .ai_model() method that adds ai_operation to metadata profiles
  • format/shorthand.rsAPI:INFERENCE [INFO] claude-3-haiku via anthropic 701ms [POST /v1/messages]
  • lib.rs — bump OCSF_VERSION to "1.8.0", re-export new types
  • validation/schema.rs — skip profile-gated required fields in schema validation
  • Vendor OCSF v1.8.0 schemas: api_activity class, ai_model object, ai_operation profile

openshell-supervisor-network crate:

  • proxy.rsemit_ai_inference() builds an ApiActivity event with ai_operation profile after inference calls complete
  • Buffered path: emits with model + token counts from response body
  • Streaming path: emits with model + latency (token counts not available without accumulating SSE chunks)

Event Shape

Shorthand (openshell.log):

OCSF API:INFERENCE [INFO] claude-haiku-4-5-20251001 via https://api.anthropic.com/v1 848ms [POST /v1/messages]

JSONL (openshell-ocsf.log):

{
  "class_uid": 6003,
  "class_name": "API Activity",
  "metadata": { "version": "1.8.0", "profiles": ["container", "host", "ai_operation"] },
  "ai_model": { "name": "claude-haiku-4-5-20251001", "ai_provider": "https://api.anthropic.com/v1" },
  "api_operation": "POST /v1/messages",
  "unmapped": { "latency_ms": 848, "input_tokens": 12, "output_tokens": 5 }
}

Scope

  • In scope: Inference calls routed through inference.local (the governed path where the supervisor terminates TLS, injects provider credentials, and has full request/response visibility)
  • Out of scope: Direct CONNECT tunnels to LLM provider hosts (proxy can't inspect encrypted payload; these are either policy-blocked or explicit opt-outs of AI observability)
  • Out of scope: SIEM backward compatibility for v1.1/v1.3 consumers (tracked in feat: Configurable OCSF schema version for SIEM compatibility (v1.1/v1.3) #2662 as a configurable serialization concern; the downgrade filter strips profile fields for older targets)

Testing

  • cargo test -p openshell-ocsf — 134 passed, 0 failed
  • cargo test -p openshell-supervisor-network — 1061 passed, 0 failed
  • cargo clippy --workspace -- -D warnings — clean
  • E2E on Kubernetes cluster — sandbox with ai-profile-v5 supervisor image, inference call to claude-haiku-4-5-20251001 via inference.local, verified API:INFERENCE event in shorthand log with model name, provider, and latency

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Unit tests added
  • E2E verified on cluster

@copy-pr-bot

copy-pr-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@johntmyers

Copy link
Copy Markdown
Collaborator

We vendor in the 1.7 schema. If we are going to support 1.8 events we should update the schema too. Also, what is the plan when inference does not go through inference.local?

@zanetworker

zanetworker commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

@johntmyers I updated the schema as well, added some feedback also to the related issue #2662 on configurability

@zanetworker
zanetworker force-pushed the feat/ocsf-ai-operation branch from 557d553 to 81a4619 Compare August 11, 2026 19:33
@zanetworker zanetworker changed the title feat(ocsf): emit AI Operation events from inference proxy (class_uid 7001) feat(ocsf): emit AI inference events via ai_operation profile on ApiActivity [6003] Aug 11, 2026
@zanetworker zanetworker changed the title feat(ocsf): emit AI inference events via ai_operation profile on ApiActivity [6003] feat(ocsf): emit AI inference events via ai_operation profile on ApiActivity [6003], bump schema to v1.8.0 Aug 11, 2026
@zanetworker

Copy link
Copy Markdown
Contributor Author

@johntmyers addressing both questions:

Schema version: Bumped to v1.8.0 with vendored schemas. The ai_operation profile on ApiActivity [6003] is schema-correct in v1.8.0. Backward compatibility for older SIEM consumers is tracked in #2662 as a configurable downgrade filter (field-level scoping posted there).

Inference outside inference.local: This PR scopes to the inference.local interception path where the supervisor terminates TLS, injects provider credentials, and has full request/response visibility (model, tokens, latency). For direct CONNECT tunnels to LLM providers, the proxy can't inspect the encrypted payload — it can only infer the provider from the hostname, not the model or token usage. Direct calls are either policy-blocked or explicit opt-outs of AI observability. A partial event based on hostname pattern matching (provider only, no model/tokens) has limited value and could be misleading, so keeping it out of scope for now.

@zanetworker

Copy link
Copy Markdown
Contributor Author

Related: #2717 adds a configurable schema version downgrade filter for SIEM backward compatibility (v1.1/v1.3). That PR strips the ai_model and ai_operation profile fields added here when targeting older schema versions, so customers running Splunk CIM or AWS Security Lake get clean events without the v1.8 additions. The two PRs are independent and can be merged in either order.

@johntmyers johntmyers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gator-agent

PR Review Status

Thanks @zanetworker. I checked your schema-vendoring update and the inference.local-only scope you explained in response to @johntmyers. The v1.8.0 schema is now present, and excluding opaque direct CONNECT traffic is consistent with the stated interception boundary. The implementation still has five blocking correctness and observability issues.

Validation: Project-valid implementation of linked issue #2663, with clear operator value and maintainer/author scope discussion.
Head SHA: 81a4619318871e249d5a199877de064ccaf08d04
Base SHA: 0310cbed6c809e8950fc513d0a25c2ec03946198
Merge base SHA: 4cb77a900ebd6b789d2b68daaba4830866833b1c
Patch ID: 75e9ff7ed1b1aa724dc2e3f9cf897fb068a68b72
Gator payload: 4
Review mode: initial
Previous reviewed SHA: none
Review budget exhausted: no
Maintainer decision required: no

Blocking findings:

  • GATOR-81a46193-01: Emitted API Activity records do not conform to the vendored OCSF v1.8.0 class contract.
  • GATOR-81a46193-02: Failed and truncated inference attempts are reported as successful or omitted.
  • GATOR-81a46193-03: Audit telemetry can identify the caller-supplied or wrong route model/provider instead of the selected route.
  • GATOR-81a46193-04: Untrusted model text can forge single-line logs and amplify log volume.
  • GATOR-81a46193-05: Published observability docs still promise OCSF v1.7.0 and omit class 6003.

Carried findings:

  • None

Non-blocking suggestions:

  • None

Docs: Missing updates for the global OCSF schema-version change and new operator-facing API Activity event.

Next state: gator:in-review

Comment thread crates/openshell-ocsf/src/builders/api_activity.rs Outdated
Comment thread crates/openshell-supervisor-network/src/proxy.rs Outdated
Comment thread crates/openshell-supervisor-network/src/proxy.rs Outdated
Comment thread crates/openshell-ocsf/src/format/shorthand.rs Outdated
Comment thread crates/openshell-ocsf/src/lib.rs
@johntmyers johntmyers added the gator:in-review Gator is reviewing or awaiting PR review feedback label Aug 13, 2026
@zanetworker
zanetworker force-pushed the feat/ocsf-ai-operation branch from 81a4619 to 134561a Compare August 14, 2026 09:41

@johntmyers johntmyers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gator-agent

PR Review Status

Thanks @zanetworker. I reviewed the update at the new head and checked it against all five prior findings. The OCSF class-shape fix and bounded/control-safe log rendering are resolved. Three existing obligations remain; no new blocking finding was introduced by this delta.

Validation: Project-valid implementation of accepted issue #2663, scoped to inference.local observability.
Head SHA: 134561a8de3ec2d3ff974801a546580c4e02dfaf
Base SHA: c4b500a7de64d0b66e3ee8098f58d14299092162
Merge base SHA: 4cb77a900ebd6b789d2b68daaba4830866833b1c
Patch ID: d93b93d1e3e43dda44c8b956728ebc20cc1756a5
Gator payload: 4
Review mode: follow_up
Previous reviewed SHA: 81a4619318871e249d5a199877de064ccaf08d04
Review budget exhausted: no
Maintainer decision required: no

Blocking findings:

  • No new blocking findings.

Carried findings:

  • GATOR-81a46193-02: Partially resolved. Router errors and terminal stream failures are now recorded, but a normally completed streaming HTTP 4xx/5xx response is still emitted as successful because resp.status is not included in stream_status.
  • GATOR-81a46193-03: Partially resolved. Caller-supplied model attribution is removed, but telemetry still reads routes.first() instead of the protocol-compatible route the router selects.
  • GATOR-81a46193-05: Partially resolved. The docs now state OCSF v1.8.0, but both published event-class inventories still omit API Activity [6003] / API:INFERENCE and its operator-facing event shape.

Resolved findings:

  • GATOR-81a46193-01: Resolved by modeling the required API, actor, and source endpoint fields with a valid activity/type.
  • GATOR-81a46193-04: Resolved by bounded, control-safe rendering and model normalization.

Docs: Still incomplete for the new API Activity [6003] event inventory and example/field contract.

Next state: gator:in-review

@zanetworker
zanetworker force-pushed the feat/ocsf-ai-operation branch from 134561a to 3dec98d Compare August 14, 2026 10:12

@johntmyers johntmyers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gator-agent

PR Review Status

Thanks @zanetworker. I reviewed the new head and checked the three carried obligations against the focused delta. The streaming HTTP status fix resolves GATOR-81a46193-02, and the API Activity inventory, event shape, and shorthand documentation resolve GATOR-81a46193-05. One existing route-attribution obligation remains; no new blocking finding was introduced by this delta.

Validation: Project-valid implementation of accepted issue #2663, scoped to inference.local observability.
Head SHA: 3dec98d7ac086a40a501dda98be4f682405b62e2
Base SHA: c4b500a7de64d0b66e3ee8098f58d14299092162
Merge base SHA: 4cb77a900ebd6b789d2b68daaba4830866833b1c
Patch ID: f59fc77cf61d1bb5ae448ba83f671daa4a56cc70
Gator payload: 4
Review mode: follow_up
Previous reviewed SHA: 134561a8de3ec2d3ff974801a546580c4e02dfaf
Review budget exhausted: yes — three finding-bearing rounds; future autonomous review is Critical-only
Maintainer decision required: no

Blocking findings:

  • No new blocking findings.

Carried findings:

  • GATOR-81a46193-03: Still unresolved. Selecting the first protocol-compatible route improves the previous attribution, but when that candidate fails and the router succeeds with a later compatible candidate, the event still records the first candidate's model/provider. Reachability: a supported multi-candidate inference.local request with two compatible routes where the first backend fails. Impact: audit, governance, and usage telemetry identifies the wrong model/provider. PR ownership: this PR introduces this model/provider telemetry. Reproducer: configure two compatible routes with distinct identities, make route A unavailable and route B successful, then compare the backend used with the emitted class-6003 event. Requested change: return or capture the route that actually produced the buffered/streaming response and pass that exact identity to emit_ai_inference, with a fallback regression test for both paths.

Resolved findings:

  • GATOR-81a46193-02: Resolved by treating non-2xx streaming responses as failure in the emitted event.
  • GATOR-81a46193-05: Resolved by documenting API Activity [6003], API:INFERENCE, the event shape, and shorthand output.

Docs: Fern documentation now covers the operator-facing event; no navigation change is needed for the existing observability pages.

Next state: gator:in-review

…ctivity

Apply the official OCSF ai_operation profile (introduced in v1.8.0) to
ApiActivity [6003] events when the inference proxy routes a model call
through inference.local. Attaches an ai_model object (name, ai_provider)
and puts token counts and latency in unmapped fields.

ApiActivity [6003] is the schema-correct class for the ai_operation
profile in v1.8.0 (HttpActivity only gets it in v1.9.0). In Splunk CIM,
ApiActivity maps to the "Change" data model, naturally separating
inference events from regular HTTP proxy traffic.

Changes:
- Add AiModel object and ai_model field on BaseEventData
- Add ApiActivityEvent struct and ApiActivityBuilder
- Add emit_ai_inference in proxy.rs using ApiActivity with ai_operation
- Vendor OCSF v1.8.0 schemas including api_activity class, ai_model
  object, and ai_operation profile definitions
- Bump OCSF_VERSION to 1.8.0
- Update schema validation to skip profile-gated required fields

Shorthand: API:INFERENCE [INFO] claude-3-haiku via anthropic 701ms [POST /v1/messages]

Splunk/SIEM backward compatibility (v1.1/v1.3 CIM mapping) is tracked
separately in NVIDIA#2662 as a configurable serialization concern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@zanetworker
zanetworker force-pushed the feat/ocsf-ai-operation branch from 3dec98d to 278cdaf Compare August 14, 2026 10:38
@johntmyers johntmyers added the test:e2e Requires end-to-end coverage label Aug 14, 2026
@github-actions

Copy link
Copy Markdown

Label test:e2e applied, but pull-request/2664 does not exist yet. A maintainer needs to comment /ok to test 278cdaf07e01bb2e9f21c4564593fbad57918aea to mirror this PR. Once the mirror exists, re-apply the label or re-run Branch E2E Checks from the Actions tab.

@johntmyers johntmyers left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gator-agent

PR Review Status

Thanks @zanetworker. I reviewed the route-identity update at the new head against the remaining durable obligation. Both buffered and streaming successful responses now carry the model and endpoint from the route that actually produced the response, resolving the prior attribution issue. The bounded Critical-only review found no newly introduced Critical defect.

Validation: Project-valid implementation of accepted issue #2663, scoped to inference.local observability.
Head SHA: 278cdaf07e01bb2e9f21c4564593fbad57918aea
Base SHA: c4b500a7de64d0b66e3ee8098f58d14299092162
Merge base SHA: 4cb77a900ebd6b789d2b68daaba4830866833b1c
Patch ID: 85e23ff1f81ed7586a3f25588af53b9d661ab6a6
Gator payload: 4
Review mode: critical_only
Previous reviewed SHA: 3dec98d7ac086a40a501dda98be4f682405b62e2
Review budget exhausted: yes
Maintainer decision required: no

Blocking findings:

  • No blocking findings remain.

Carried findings:

  • None. GATOR-81a46193-03 is resolved by propagating the route identity from the successful buffered or streaming router response into the API Activity event.

Docs: Fern documentation already covers API Activity [6003], API:INFERENCE, the event shape, and shorthand output; no navigation change is needed.

Tests: Applied test:e2e. The current-head E2E Label Help workflow is queued, but the required test workflow has not yet been confirmed queued, running, or complete.

Next state: gator:in-review pending current-head E2E dispatch confirmation.

@johntmyers

Copy link
Copy Markdown
Collaborator

/ok to test 278cdaf

@johntmyers johntmyers removed the gator:in-review Gator is reviewing or awaiting PR review feedback label Aug 14, 2026
@johntmyers johntmyers added gator:watch-pipeline Gator is monitoring PR CI/CD status gator:approval-needed Gator completed review; maintainer approval needed and removed gator:watch-pipeline Gator is monitoring PR CI/CD status labels Aug 14, 2026
@johntmyers johntmyers added gator:merge-ready and removed gator:approval-needed Gator completed review; maintainer approval needed labels Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gator:merge-ready test:e2e Requires end-to-end coverage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Emit OCSF v1.8.0 ai_operation events from inference proxy

2 participants