Skip to content

Enterprise deploymentFully managed today; customer-hosted available as a pilot.Contact salesView pricing

Technical paper11 min read

What to record for every agent action: a security telemetry schema

A field-by-field schema for agent security events covering identity, action, decision, context provenance, outcome and correlation, mapped to OpenTelemetry GenAI conventions, with privacy rules and retention tiers that keep the log useful and safe.

IntertraceSecurity engineering

Plain-language guidance for teams adopting AI — the risk, the cost, the compliance, and what to ask before you buy.

July 29, 2026 · 11 min read

TelemetryDetection EngineeringOpenTelemetryAuditAI Agents
Anatomy of a single agent security event split into who, what, decision, context and outcome
One agent action, recorded as one event with five parts that detection, investigation and audit can all read.Fig. 0 · Cover
Contents
  1. 01Who: identity is five fields, not one
  2. 02What: record the action, not just the tool name
  3. 03Decision: the band most logs leave out
  4. 04Context provenance, outcome and correlation
  5. 05Mapping to the OpenTelemetry GenAI conventions
  6. 06Privacy: minimize, hash, never store secrets
  7. 07Detections the schema enables, and mistakes that break them
  8. 08What to do this quarter

Picture the first hour of an investigation. A customer's records were deleted through an agent's database tool. The log has a timestamp, a tool name, an HTTP 200 and a model ID. It does not say which employee started the session, which credential the agent used, whether the statement was a DELETE or a SELECT, which policy allowed it, or whether a retrieved document told the agent to do it. Every one of those facts existed at decision time, and none was written down.

Agent telemetry fails this way because it is inherited from performance monitoring, which asks how long and how much. Security asks who, on whose authority, and why it was allowed. The schema below answers the second set of questions and is deliberately boring: flat fields, stable names, enumerated values, no free text where an enum will do.

The unit of record is a decision point: every model call, tool call, MCP request or agent-to-agent message a policy evaluated. One HTTP request can carry several tool calls, and a session summary cannot be joined to a specific action, so neither is the right grain. Three consumers read the same event. Detection needs indexed fields it can aggregate. Investigation needs linkage to rebuild a session hop by hop. Audit needs proof, months later, that a consequential action was authorized by a named rule or person.

Five bands of one security eventFig. 1
EVENT · agent.decisionONE PER DECISIONWhouser_idagent_idkey_idsession_idWhattoolnormalized_actionconsequence_tierargs (redacted)Decisionoutcomedeciding_rulelayerapproverContextinput_provenanceuntrusted_spansdetectionsOutcomeupstream_statuslatency_mstrace_idcorrelate every hop of one request with the same trace_id · never write secret values into any field

Who caused the action, what it did, how it was decided, what context shaped it and what happened next. A missing band is a question an investigator cannot answer from the log.

Who: identity is five fields, not one

Collapsing layered identity into a single "user" field is the most common reason agent investigations stall. Record each layer separately, as identifiers rather than display names.

  • User: the human principal the agent acts for, or an explicit marker that it is running autonomously.
  • Agent: a stable agent ID plus a version or configuration hash, so you know which build acted.
  • Runtime key: the credential's key ID or fingerprint, never its value. This is what you revoke, so it is what you must search by.
  • Tenant: the organization, derived from the authenticated credential on the server. A tenant ID copied from the request body is a claim, not a fact.
  • Session: the conversation or run that groups related actions. Without it you have a pile of calls instead of a story.

When agent A asks agent B to act, B's event should carry the ordered delegation chain and the originating user, so a series of handoffs cannot launder authority.

What: record the action, not just the tool name

A tool name says which function ran, not what it did. `run_sql` covers both a read and a table drop; `bash` covers both `ls` and `curl | sh`. Record three layers. Tool identity is the tool name, its server or connection, and for MCP a hash of the tool definition in effect. The normalized action is what the call does once its arguments are read, such as `sql.delete`, `git.push.force` or `message.send.external`; detections should key on it. The consequence tier is an ordinal for how bad the action is if wrong (read, reversible change, external effect, privileged, irreversible), which lets one rule cover "irreversible actions in production" instead of a list of tool names.

Arguments carry most of the risk and most of the sensitive data, so do not log them raw. Record their shape (names, types, lengths), the data classes detected in them, the destination for outbound calls, and a keyed hash of each value. An HMAC with a per-tenant secret answers "was the same recipient used in both calls" without storing the recipient, and resists the dictionary attack a plain SHA-256 of an email address invites.

Decision: the band most logs leave out

A record of an allowed action is not evidence of authorization unless it names what allowed it. This band is the difference between an activity log and an audit trail.

  • Outcome: allow, flag (allowed and marked for review), ask (held for a person) or block. In monitor mode, record both the enforced outcome and what enforce mode would have done.
  • Deciding rule and layer: the rule ID and version that produced the outcome, and where it lives (organization, agent, exception, built-in safeguard). Auditors ask whether something was allowed by default policy or by an exception someone granted.
  • Policy snapshot: a hash of the full policy set evaluated, so the decision can be replayed against the exact rules in force.
  • Signals: detector outputs that fed the decision, each with its source, so a false positive traces back to its detector.
  • Approval: for asks, the approver's identity, decision, time and the scope of any remembered approval. An approval without an approver ID cannot be audited.
  • Failure reason: if the enforcer could not decide and failed closed, say so instead of recording an ordinary block.

Context provenance, outcome and correlation

Indirect prompt injection is a provenance problem: the instruction behind the action came from content the user did not write. You do not need that content in the log. You need, for each input span in the model's window, its source type (user turn, system prompt, retrieved document, tool result, web page, another agent), a source identifier such as a document ID or host, a trust label, and a hash. Then "the agent emailed a file after reading an external page" is a query, not a forensic project.

The outcome band records upstream status or tool error type, latency, response size and data classes found in the response. Correlation ties events together: a W3C trace and span ID, the session ID, a parent event ID for the model call that proposed the tool call, a hop index, and the provider's response ID where one exists. That chain lets an investigator walk from a deleted record back to the user turn and the document that led to it.

Consider an illustrative finance-operations agent, ledger-bot, at a fictional logistics company. A clerk asks it to clean up duplicate vendor records; it proposes a SQL statement, and policy holds it for approval.

Sample security event for one held tool call (illustrative values)
FieldExample valueWhy it is there
actor.user_ididp|u_48213 (clerk)The human principal; the person to interview.
actor.agent_id / versionledger-bot / cfg 9f3a1cWhich agent and configuration acted.
actor.key_idkey_7Q2M (fingerprint only)The credential to revoke; the value is never logged.
tenant_idorg_logistics_eu (from the key)Scoping that a request body cannot spoof.
session_id / hopsess_c41e / 7Rebuild the conversation in order.
tool / serverrun_sql / finance-dbWhat was invoked, through which connection.
action.normalized / tiersql.delete (CTE) / irreversibleWhat the call does and how bad a mistake would be.
args.shape / classes / hmacquery: string, 412 chars / none / h:5be0Evidence without the raw statement.
decision.outcome / modeask / enforceWhat policy did, and whether it was enforced.
decision.rule / layerorg.sql-delete-asks v3 / organizationThe authority for the outcome.
approval.by / at / scopeidp|u_10077 / 14:02:31Z / this call onlyWho accepted the risk, and how broadly.
context.untrusted_spans1 tool_result (vendor-export.csv)Whether untrusted content preceded the action.
outcome.status / latency_ms200 / 812What happened after approval.
trace_id / parent_event4bf92f35... / evt_model_6Correlation across hops and systems.

Mapping to the OpenTelemetry GenAI conventions

Use OpenTelemetry where it defines a field and your own namespace only where it does not. The GenAI semantic conventions now live in their own repository and are marked Development, so pin the version you implement. They define an `execute_tool` span with `gen_ai.tool.name` required, `gen_ai.tool.call.id` when the provider supplies one, and `gen_ai.tool.call.arguments` and `gen_ai.tool.call.result` as opt-in because they may contain sensitive information [1]. Agent spans add `gen_ai.agent.id`, `gen_ai.agent.version` and `gen_ai.conversation.id` [2]; the MCP conventions add `mcp.method.name` and `mcp.session.id` [3].

Two details matter. The conventions say instrumentations should not capture instructions, inputs and outputs by default [1]; keep that default, because span attributes fan out to every observability backend. And the inference conventions say not to populate a conversation ID when none is available, and not to fall back to a new UUID, a trace ID or a hash of request content [5]. Security still needs a session, so assign one at the gateway in your own field and leave the GenAI attribute truthful.

Where the GenAI conventions cover the schema, and where security adds fields
Schema conceptOpenTelemetry attributeWhat security adds
Agent identitygen_ai.agent.id, gen_ai.agent.version [2]Delegation chain.
Tool identitygen_ai.tool.name, gen_ai.tool.call.id [1]Server identity and tool-definition hash.
Sessiongen_ai.conversation.id, mcp.session.id [3][5]A gateway-assigned session when the client sends none.
Argumentsgen_ai.tool.call.arguments, opt-in [1]Shape, data classes and keyed hashes instead of values.
User, key, tenantNot defined in the agent span conventions [2]Principal, key fingerprint, server-derived tenant.
Normalized action, tierNot definedAction read from arguments; consequence ordinal.
Decision, rule, layer, approverNot defined [2]The whole decision band.
Context provenanceNot definedPer-span source type, trust label and hash.

The agent spans define no user identity, authorization outcome, policy or approval [2]. So a security event is a superset: an OpenTelemetry span with standard attributes plus a security namespace you own, written to the security pipeline and reduced before export to general observability tools.

Privacy: minimize, hash, never store secrets

A security log holding every prompt is a second copy of your most sensitive data with weaker access control than the original. OWASP's logging guidance lists what should usually not be recorded directly, including session identifiers (hash them if you must track sessions), access tokens, passwords, encryption keys, payment card data and sensitive personal data, which should be removed, masked, sanitized, hashed or encrypted [4]. Agents make them more likely: users paste credentials into chats.

  1. Minimize at the source. Detection rarely needs content; it needs classes, counts and hashes.
  2. Redact before write. Run secret and PII detection on argument values, error messages and retrieved titles before they reach the pipeline, not in a nightly job.
  3. Hash with a key. Use a per-tenant HMAC for values you correlate, and rotate it like any other secret.
  4. Never store secret values at any tier. A fingerprint is enough to match a leaked key to its events and revoke it.
  5. Isolate content capture. If a defined purpose requires raw prompts, keep them in a separate store with its own access list, retention and deletion path.
Retention tiers for agent security eventsFig. 2
Hot · 30 daysfor detectionfull metadata, redacted argumentsWarm · 1 yearfor investigationmetadata, hashed argumentsCold · per policyfor auditdecisions and approvals onlyDETAIL NARROWS AS DATA AGES ←SECRETS NEVER STORED AT ANY TIERretention periods are examples; set them from your detection, investigation and regulatory needs

Detail decays with age: full metadata for detection, redacted arguments for investigation, and only decisions and approvals for audit. Secrets are never stored at any tier.

Tier retention by consumer; the durations are examples to adapt, not a standard. Hot storage (about 30 days) holds full metadata for detection and triage. Warm storage (about a year) keeps hashes and classes with no residual content, which covers investigations that start late. Cold storage, kept as long as audit policy requires, holds only decisions, approvals and identity. Telemetry retention and audit retention are different clocks.

Detections the schema enables, and mistakes that break them

Each detection below is a query over guaranteed fields. If a detection you want requires parsing free text, the schema is missing a field.

  • Injection to action: an external-effect or irreversible action in a session shortly after an untrusted web or tool-result span entered context.
  • Credential reuse: one key fingerprint seen with more than one agent ID, or from a new network origin.
  • Rubber-stamping: an approver accepting asks faster than a person could read them, or accepting nearly every ask for one rule, which suggests the rule should change.
  • Exception creep: a rising share of an agent's allows decided at the exception layer, or exceptions renewed back to back.
  • Exfiltration shape: one argument hash sent to a new external destination from several sessions, or sensitive classes in a response followed by an outbound message.

The mistakes that break them are predictable. Logging full prompts "for debugging" gives the log every pasted secret and every customer record, then ships it to tools with broad access. Recording the outcome without the deciding rule and layer shows that something was allowed but never why. A missing session ID, or one only some components set, disconnects the injected document from the action it caused. Trusting a tenant field from the body records what the attacker claimed. Sampling security events drops exactly the one you need, and editing events in place on approval erases the original decision; append a new event that references the first.

How Intertrace records decisions

Intertrace's gateway emits a structured event for every decision on LLM, MCP, inference, service and agent-to-agent traffic: who acted, what the call did after action normalization read its arguments, the outcome, the rule and layer that decided it, and the evidence. Tenancy comes from the `itr_rt_*` runtime key, not the request body. Events export to your SIEM, the OpenTelemetry fan-out is metadata only, and discovery never stores key values, only masked forms and fingerprints. HIRO, the AI security analyst, reads these events and proposes changes a person approves.

What to do this quarter

  1. Pick one consequential agent and mark each field of the five bands as present, derivable or missing in its current events.
  2. Add the decision band first: outcome, deciding rule and version, layer, policy hash and approver. It is the cheapest to add and the most expensive to lack.
  3. Assign a session ID at your gateway or orchestrator for every run, and propagate trace context to tools and sub-agents.
  4. Replace raw argument logging with shape, data classes and per-tenant HMACs, and run secret detection ahead of the pipeline.
  5. Map fields to a pinned version of the GenAI conventions, keep security-only fields in your own namespace, and set hot, warm and cold retention separately.
  6. Add a test that fails if a canary secret appears in any tier, then run a tabletop where an investigator rebuilds one session from the log alone.

Sources

Reporting, research and specifications this piece draws on. Links go to third-party sources; analysis and recommendations are Intertrace’s own.

  1. 01Semantic conventions for generative AI spans (execute_tool, content capture) · OpenTelemetry
  2. 02Semantic conventions for GenAI agent and framework spans · OpenTelemetry
  3. 03Semantic conventions for Model Context Protocol (MCP) · OpenTelemetry
  4. 04Logging Cheat Sheet · OWASP
  5. 05Semantic conventions for GenAI client inference spans · OpenTelemetry

Dated July 29, 2026 · added to intertrace.ai October 19, 2026

+ Runtime enforcement

See these controls on your own agent traffic.

Intertrace sits inline between your agents and the models, tools and MCP servers they call, and decides every call before it runs.

Keep reading

All insights →