Add ai_agent object and extend ai_operation profile coverage#1641
Add ai_agent object and extend ai_operation profile coverage#1641Aniak5 wants to merge 15 commits into
ai_agent object and extend ai_operation profile coverage#1641Conversation
Schema Description ReviewAutomated suggestions for improving description clarity for LLM consumption. These are advisory — not required changes. Looking at this OCSF schema PR, I'll check against my previous review and assess the current state. Progress Check from Previous Review✅ Fixed: CHANGELOG formatting issue resolved
Current Review FindingsSuggestions
SummaryThe AI agent integration in this PR is well-designed with clear, self-contained descriptions that effectively distinguish between AI agents (autonomous task performers) and the existing agent object (security sensors). All visible attribute descriptions provide good semantic clarity for LLM consumption. However, there appears to be a compilation issue where |
…g placement Brings in the polished ai_agent vocabulary from PR ocsf#1641 (uid/ai_model description polish, version attribute, ai_agent placements on actor and process, ai_operation profile coverage extension, and the new charter attribute) so this delegation demo branch reflects the upstream-bound agent foundation. # Conflicts: # dictionary.json # events/application/web_resources_activity.json # events/system/file_activity.json # events/system/scheduled_job_activity.json # events/system/script_activity.json # objects/ai_agent.json # profiles/ai_operation.json
…agent activity) Builds on ocsf#1641. Advances ocsf#1640. Introduces an optional ai_forensics profile carrying an attestation object (a digital signature bound to ai_agent identity, with optional tamper-evident chaining via entry_hash/prev_entry_hash/chain_uid), plus the supporting dictionary attributes.
d855f9d to
3751504
Compare
…s profile Per maintainer feedback on ocsf#1661: fold the attestation object onto the ai_operation profile as an optional attribute rather than carrying it on a standalone single-attribute ai_forensics profile. The attestation object is unchanged and remains domain-agnostic, leaving a broader non-repudiation profile as a clean follow-on with AI as the first consumer. Advances ocsf#1640. Builds on ocsf#1641.
|
This is a strong foundation. What would really help reviewers and early implementers is a few concrete end-to-end examples - what an event looks like on the wire from both the producer and consumer sides. A couple of things I'm curious about: Producer side - how should an event source populate this in practice? For example, when a LangChain agent reads a file via a tool call, does Consumer side - what's the intended correlation pattern? How would an analyst pivot from "this file was deleted" to "which agent instance was responsible and what model was it running?" across the A pair of abbreviated JSON event snippets would go a long way toward building confidence that the attribute |
|
+1 to the ask for wire examples, @mikeradka. Rather than a hypothetical, here's a real (scrubbed) row from our gateway — we log every agent request as an immutable, hash-chained record, so I can speak to what a producer can and can't actually populate, which is where the placement questions get real. This is our own {
"activity_id": 2,
"category_uid": 6,
"class_uid": 6003,
"type_uid": 600302,
"severity_id": 1,
"time": 1777912519552,
"metadata": {
"version": "1.9.0-dev",
"profiles": ["ai_operation"],
"correlation_uid": "0a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
},
"action": "Allowed",
"action_id": 1,
"api": { "operation": "read_file", "service": { "name": "ada-tools" } },
"http_request": { "http_method": "POST", "url": { "path": "/ada/tools/read_file" } },
"actor": {
"user": { "uid": "11111111-2222-4333-8444-555566667777", "type_id": 1 }
},
"ai_agent": {
"uid": "a9c3e7d1-2b4f-4e6a-9c8d-3f5a7b1e2c4d",
"name": "ada"
},
"unmapped": {
"policy_version": 36,
"status_code": 200,
"latency_ms": 90,
"upstream_latency_ms": 45
}
}The honest producer answer to your Consumer pivot (your correlation question): Two placement questions back at you: (1) policy decisions map cleanly here — Thank you for the review - Jeff |
|
Thanks for the review @mikeradka — agreed, the placement question deserves a concrete answer before this lands. Here's how we're thinking about it. The placement landscapeWe currently have Why
|
| Placement | Pros | Cons |
|---|---|---|
ai_operation.ai_agent (profile-level) |
Producer's natural discovery path. Self-contained: producers don't need to combine multiple profiles to log an agent reference. Works on event classes that don't have actor (discovery, application, future model-inference events). |
None significant. This is the canonical home. |
actor.ai_agent |
Composes via evidences.actor.ai_agent in findings — a detection about agent-driven activity can carry the agent identity inside the evidence trail. Aligns with the actor model (agent as a non-human principal) for events where actor is the natural aggregator. |
On the top-level event itself, largely redundant with the profile-level reference. If we don't expect producers to use it for delegated-authority cases (actor.user + actor.ai_agent), it adds a placement choice without semantic value. |
process.ai_agent |
Composes via process.parent_process.ai_agent to express agent-to-agent delegation at the runtime layer — when an orchestrator agent spawns a worker agent, the worker carries ai_operation.ai_agent and the orchestrator surfaces only through parent_process.ai_agent; nothing else on the event preserves that spawning relationship between agents. Also composes via actor.process.ai_agent for "the running process is the agent's runtime" (endpoint forensics, container attribution). |
Redundant at the top level (the profile-level ai_agent already carries the acting agent's identity), and the composition cases are real but apply mainly in multi-agent / endpoint-forensics scenarios — single-agent events get nothing extra from it. |
Worth considering: adding to evidences
We could also add ai_agent to the evidences object directly, alongside actor and process. That would let findings carry agent identity at the top of the evidence trail without requiring it to be reached via evidences.actor.ai_agent. This may be the cleaner path for detection-finding consumers.
Producer-side convention (proposed)
Canonical placement:
ai_operation.ai_agentis the primary home for agent identity on any event applying theai_operationprofile. Populate this whenever an AI agent is involved.Nested placements (
actor.ai_agent,process.ai_agent,process.parent_process.ai_agent) are populated only when the binding carries information beyond the canonical reference — e.g., a child process whose parent is an agent runtime, or finding evidence that links agent activity to a detection.
Examples
LangChain agent reads a file via a tool call:
{
"class_uid": 1001,
"activity_id": 2,
"ai_agent": {
"uid": "agent-research-assistant",
"instance_uid": "i-7c2f9a",
"name": "Research Assistant",
"type_id": 4,
"type": "LangChain",
"version": "1.4.2",
"ai_model": {
"uid": "claude-sonnet-4-6",
"name": "Claude Sonnet 4.6",
"version": "20260514",
"vendor_name": "Anthropic"
},
"charter": {
"name": "research_assistant_charter.md",
"hashes": [
{ "algorithm_id": 3, "value": "8f3b2c1d4e7a..." }
]
}
},
"file": {
"name": "q4_earnings.pdf",
"path": "/data/reports/q4_earnings.pdf"
}
}Agent spawns a subprocess that performs the activity (parent_process binding):
{
"class_uid": 1007,
"activity_id": 1,
"ai_agent": {
"uid": "agent-deploy-worker",
"instance_uid": "i-9e22",
"name": "Deploy Worker",
"type_id": 1,
"type": "Native",
"ai_model": { "uid": "claude-haiku-4-5" }
},
"process": {
"pid": 51220,
"name": "python3.13",
"parent_process": {
"pid": 48211,
"name": "python3.13",
"ai_agent": {
"uid": "agent-devops-orchestrator",
"instance_uid": "i-44c1",
"name": "DevOps Orchestrator",
"type_id": 3,
"type": "A2A",
"ai_model": { "uid": "claude-opus-4-7" }
}
}
}
}The acting agent is agent-deploy-worker — that's the agent on ai_operation.ai_agent and the agent running in the current process. Its parent process is another agent (agent-devops-orchestrator, an A2A orchestrator) that delegated this work. process.parent_process.ai_agent is the only place this delegating-agent identity surfaces on the event — without it, you'd lose the spawning relationship between agents.
Questions for the group
- Is the canonical-placement-with-nested-bindings convention the right model, or should we simplify to profile-level only and accept the loss of parent_process / evidence composition?
- Should we add
ai_agentdirectly to the evidences object?
@davemcatcisco @jedwardsol if you get a chance, I'd really appreciate your feedback on adding ai_agent to actor and process. That's probably where endpoint telemetry has the biggest impact.
ai_agent object and extend ai_operation profile coverage
davemcatcisco
left a comment
There was a problem hiding this comment.
As well as the comments I've made about the AI profile being available in all System Activity and Network events, it also needs to be available in all events in the Identity & Access Management category by adding it to the iam base event for that category.
853d99a to
f201e0c
Compare
Address Dave + jedwardsol's review feedback on PR ocsf#1641. A single OS process can host multiple AI agents (e.g., an IDE running Claude Code, Codex, and Copilot simultaneously), and producers may not be able to attribute a given activity to a specific agent. Added hosted_ai_agent_list to the process object as an array of ai_agent, analogous to how the Windows extension models hosted services. The singular ai_agent attribute remains for cases where attribution is known. Also replaced two — HTML entities in dictionary.json with hyphens per mikeradka's nit.
2430051 to
74eca4b
Compare
Address Dave + jedwardsol's review feedback on PR ocsf#1641. A single OS process can host multiple AI agents (e.g., an IDE running Claude Code, Codex, and Copilot simultaneously), and producers may not be able to attribute a given activity to a specific agent. Added hosted_ai_agent_list to the process object as an array of ai_agent, analogous to how the Windows extension models hosted services. The singular ai_agent attribute remains for cases where attribution is known. Also replaced two — HTML entities in dictionary.json with hyphens per mikeradka's nit.
2c5696c to
849aa86
Compare
Address Dave + jedwardsol's review feedback on PR ocsf#1641. A single OS process can host multiple AI agents (e.g., an IDE running Claude Code, Codex, and Copilot simultaneously), and producers may not be able to attribute a given activity to a specific agent. Added hosted_ai_agent_list to the process object as an array of ai_agent, analogous to how the Windows extension models hosted services. The singular ai_agent attribute remains for cases where attribution is known. Also replaced two — HTML entities in dictionary.json with hyphens per mikeradka's nit.
|
@Aniak5 - As we discussed in the Network/AI call just now, I think there is a strong argument for the |
davemcatcisco
left a comment
There was a problem hiding this comment.
Looks good to me now. Thanks, @Aniak5.
|
@mikeradka will need to re-approve. |
Address Dave + jedwardsol's review feedback on PR ocsf#1641. A single OS process can host multiple AI agents (e.g., an IDE running Claude Code, Codex, and Copilot simultaneously), and producers may not be able to attribute a given activity to a specific agent. Added hosted_ai_agent_list to the process object as an array of ai_agent, analogous to how the Windows extension models hosted services. The singular ai_agent attribute remains for cases where attribution is known. Also replaced two — HTML entities in dictionary.json with hyphens per mikeradka's nit.
1499105 to
e516d55
Compare
Introduce a new ai_agent object representing an autonomous AI agent and thread it through the schema so that data-plane events across multiple categories can attribute activity to the agent that initiated it. Distinct from the existing agent object, which models security sensors (EDR, DLP, APM, etc.).
…guidance Address PR review feedback by clarifying the charter attribute description to prescribe populating hashes and signatures on the file for content integrity and provenance verification.
Lift ai_operation profile from individual classes to the system and network base events so all System Activity and Network Activity events inherit agent attribution. Refine ai_agent.uid, ai_model, type_id, and version descriptions; drop MCP and A2A from type_id since communication protocols are properties of operations, not the agent itself.
The charter attribute is added to ai_agent in the same PR that introduces the ai_agent object, so the per-attribute entry under Improved > Objects is redundant.
Address Dave + jedwardsol's review feedback on PR ocsf#1641. A single OS process can host multiple AI agents (e.g., an IDE running Claude Code, Codex, and Copilot simultaneously), and producers may not be able to attribute a given activity to a specific agent. Added hosted_ai_agent_list to the process object as an array of ai_agent, analogous to how the Windows extension models hosted services. The singular ai_agent attribute remains for cases where attribution is known. Also replaced two — HTML entities in dictionary.json with hyphens per mikeradka's nit.
The dictionary description is shared across all entities that may adopt the attribute. The process-specific guidance lives on the process object's own description.
An AI agent that initiates an activity is attributed via the ai_operation profile's ai_agent attribute, not the actor object. Remove ai_agent from actor (and its at_least_one constraint) and point the actor description to ai_operation.ai_agent instead.
- Extend ai_agent from _entity instead of object, matching the standard OCSF pattern for objects with name/uid identity. - Gate process.ai_agent and process.hosted_ai_agent_list behind the ai_operation profile so they only surface on AI-relevant events. - Replace remaining em dashes in ai_agent descriptions with hyphens.
- Add the ai_operation profile to the application base event so all Application Activity classes inherit agent attribution, and drop the now-redundant direct includes from web_resources_activity, api_activity, and datastore_activity. - Rewrite the ai_agent.instance_uid description to decouple it from OS process lifecycle: an instance is a logical session/run that may persist across restarts and span multiple cooperating components.
Per OCSF normative-schema guidance to keep company names out of descriptions.
- Add the ai_operation profile to the iam base event so all Identity &
Access Management classes inherit agent attribution, per Network/AI
call discussion.
- Reword the tail of the ai_agent.instance_uid description per review
("a particular instance of the agent rather than to the agent
generally").
e516d55 to
197d619
Compare
First step toward agentic AI observability per #1640. This PR introduces the
ai_agentobject and threads it through the schema so that data-plane events across multiple categories can attribute activity to the agent that initiated it. Delegation, lineage, and the AI control-plane event classes are intentionally deferred to follow-up PRs.Changes
New object
objects/ai_agent.json— autonomous AI agent identity with:uid(required) — stable logical agent identifier assigned by the agent's authoritative source (control plane, registry, or issuing IdP); persists across restarts and instancesinstance_uid— restart-sensitive identifier for a specific running instancename— human-readable agent nametype/type_id— agent framework with enum:Native,LangChain,AutoGen,CrewAI,Other(communication protocols like MCP/A2A are per-event rather than per-agent and are not modeledhere)
ai_model— the model backing the agent at the time of actionversion— agent version (its own code or configuration revision, distinct from the model version onai_model.version), for correlating behavioral changes with charter or configuration revisionscharter— file-typed reference to the document that defines the agent's durable role, responsibilities, constraints, and operating boundaries (e.g., system prompt or constitution); supportshashesfor content integrity andsignaturesfor provenanceagentobject (which models security sensors such as EDR, DLP, APM).Dictionary
dictionary.json— added top-levelai_agentattribute referencing the newai_agentobject type.dictionary.json— added top-levelcharterattribute (file type) for documents defining the role, scope, and operating bounds of an entity.Profile
profiles/ai_operation.json— added optionalai_agentattribute (context group) so any event class adopting the profile can carry agent attribution.Object updates
objects/actor.json— added optionalai_agentattribute and included it in theat_least_oneconstraint, so an actor can be identified as an autonomous AI agent rather than (or in addition to) a user, IAM role, process, etc.objects/process.json— added optionalai_agentattribute, allowing a process to be identified as the runtime of a specific AI agent.Event classes — added
ai_operationprofileevents/system/system.json(base class) — propagates the profile to all System Activity eventsevents/network/network.json(base class) — propagates the profile to all Network Activity eventsevents/application/web_resources_activity.json— does not extend the network base, added directlyevents/network/email_activity.json— does not extend the network base, added directlyThese join
process_activity,datastore_activity, andapi_activity, which already had the profile.Closes part of #1640.