spec_change: agent_id as the correlation key for OCSF ai_agent.instance_uid (§3.1, §5.2) - #270
spec_change: agent_id as the correlation key for OCSF ai_agent.instance_uid (§3.1, §5.2)#270rabbidave wants to merge 1 commit into
Conversation
…ce_uid Section 5.3.1 already binds agent_id to "the authenticated workload subject for the current session" for gateway runtime-session binding. This makes the same binding explicit and normative for OCSF-emitting runtime-evidence producers: when such a producer emits an ai_agent- bearing event (e.g. Agent Inventory Info [5050]) for a manifest-governed session, ai_agent.instance_uid MUST equal this manifest's agent_id. Verification results gain an optional runtime_correlation_key field (section 5.2) that echoes agent_id back, so a runtime-evidence consumer doesn't need to re-parse the manifest to get the join key. fields_verified is untouched -- it stays boot-time-only per section 7.2; this does not make the manifest a runtime monitor. Worked example uses real output from the reference implementation (rabbidave/ws4-secure-design-agentic-systems@1e35ab5): AgentIdentity now feeds a proper OCSF ai_agent object (uid/instance_uid/version/charter/ token_fingerprint) instead of the flat, model-conflated agent_uid that implementation used before. Does not split agent_id into separate stable/instance fields -- flagged as an open question for reviewers rather than decided here. Closes agentrust-io#269.
imran-siddique
left a comment
There was a problem hiding this comment.
Reviewed this properly against the OCSF schema rather than on the description alone. The problem you identified is real and worth fixing: there is no defined join key between a manifest and OCSF runtime evidence, and picking one is overdue. Your reasoning for choosing instance_uid over version and charter is right, both are static across a session and useless as per-event join keys. Keeping fields_verified boot-time-only per section 7.2 is also correct.
Three things block it as written.
1. The MUST contradicts what OCSF says the field is. From objects/ai_agent.json in ocsf-schema main:
uid: "The stable logical identifier for the agent, assigned by the agent's authoritative source"instance_uid: "Identifier for a specific running instance or session of the agent, distinct from the stable logical uid. An instance is a single materialization of the agent."
OCSF makes the distinctness explicit. Section 3.1 immediately above your addition says the /agent/<name>/<instance> path structure is "a convention, not a requirement", so a conformant agent_id may legitimately be stable and carry no instance scope at all. In that configuration your MUST forces a stable identifier into a field OCSF defines as the non-stable one, and the worked example populates uid, instance_uid and session_uid with the same string, which erases the distinction OCSF created the field to express. A consumer can then no longer separate "every run of payments-processor" from "this run".
You flag the overload as a known open question and defer the split. That is the reason not to freeze it as MUST now: if a later revision splits the field, it breaks a normative requirement rather than refining an informative one.
2. The carrier class does not exist in OCSF. Agent Inventory Info [5050] is not in ocsf-schema main. There is no agent_inventory_info.json under events/discovery/, and no occurrence of 5050 anywhere in the repository. The ai_agent object is real, the class you cite as carrying it is not, at least not in core OCSF. If it comes from an extension, say which, because normative text in this spec cannot depend on an event class that core OCSF has not assigned.
3. runtime_correlation_key should be dropped. It is a verbatim copy of agent_id, defined as always present, and explicitly does not affect result or fields_verified. The consumer that reads it has just verified the manifest, so it already holds agent_id. That is zero information gain inside a signed structure, and it introduces a failure mode that does not otherwise exist: two signed copies of the same identity that an implementation can make disagree. The sentence "A verifier that has no runtime-evidence consumers MAY omit populating downstream consumption of this field, but the field itself is always present" is also not usable as normative text, since it permits and forbids in one breath.
On sourcing. The worked example and the reference implementation are both rabbidave/ws4-secure-design-agentic-systems@1e35ab5. One personal implementation is not enough to anchor a MUST that binds every OCSF-emitting producer.
What would land. Either of these works:
- Make it informative. A crosswalk section stating that where a producer emits
ai_agentfor a manifest-governed session,instance_uidis the intended join key, withuidcarrying the stable manifest-level identity. That is close to the non-normative pointer in #268 and needs none of the above resolved. - Keep it normative but scope it to a profile that declares OCSF emission in scope, and resolve stable versus instance first: bind
ai_agent.uidto the stable identity andinstance_uidto the session-scoped value, which is what OCSF's own definitions ask for. That likely does need theagent_idsplit you deferred.
Worth raising in the CoSAI WS4 stream either way, since section 3.1 already defers the canonical @context URL to WS4, and an OCSF correlation mapping belongs in the same venue rather than being settled here first.
Mirrors agentrust-io/trace-spec#120. The rule that normative spec changes need an organizational sponsor is applied in review but written down nowhere, so contributors meet it for the first time on their own PR, after doing the work. #270 is a live example: a normative MUST binding agent_id to OCSF ai_agent.instance_uid, authored individually, where the authorship question only surfaced at review. No change in practice. It also writes down that anyone may propose a normative change, that proposals are judged on the argument alone, and that a Maintainer carries the PR when an accepted proposal has no sponsor, all of which was already true and equally unwritten. Calls out explicitly that informative crosswalks and mappings to external schemas need no sponsor, since that is the path a proposal like #270 can take today. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes #269. Companion to the non-normative pointer in #268 (that one is deliberately untouched by this PR).
What this changes:
agent_id== "the authenticated workload subject for the current session") — extended here to OCSF-emitting runtime-evidence producers. When such a producer emits anai_agent-bearing event for a manifest-governed session,ai_agent.instance_uidMUST equal this manifest'sagent_id.runtime_correlation_keyto the verification result, echoingagent_idso a runtime-evidence consumer doesn't need to re-parse the manifest for the join key.fields_verifiedis untouched — stays boot-time-only per §7.2.[Unreleased] / Addedentry per repo convention.Why
instance_uidand notversion/charter: both are static across a session (agent code/config revision, durable role doc) — not usable as a per-event join key. They stay useful as secondary context once an instance is already identified.Worked example (§5.2) uses real output from rabbidave/ws4-secure-design-agentic-systems@1e35ab5:
AgentIdentitynow feeds OCSF's actualai_agentobject (uid/instance_uid/version/charter/token_fingerprint) instead of the flat, model-conflatedagent_uidthat implementation used before this fix. The OCSF event block in the example is unmodified output from that code, not hand-authored.Known open question, not resolved here:
agent_idis asked to serve both OCSF'suid(stable) andinstance_uid(session-scoped) concepts. §3.1 notes a future revision may split this into two fields if the overload proves to be a problem; this PR doesn't propose that split, flagging it for reviewers instead.cc @imran-siddique