How to Build AI Agent Audit Logs That Explain Every Action
An internal agent changes a payment record, sends a customer message, or disables an account. Later, the operator can see that a tool ran, but cannot tell who requested it, which workflow version chose it, what policy allowed it, or whether a person approved it. A line that says tool completed is not enough. AI agent audit logs need to connect the business request to the final outcome without copying raw prompts, credentials, or private documents into another sensitive database. The design below covers the event model, capture points, controls, and tests needed to reconstruct an AI-assisted action.
An audit record is not a diagnostic trace
A trace helps an engineer debug execution. It usually answers questions about duration, model calls, token usage, exceptions, and the path through a workflow. An audit record serves a different reader and a different retention policy. It must explain an accountable business action: who initiated it, what authority applied, what object was affected, which decision was made, and what happened.
Link the records instead of merging them. Put a trace identifier in the audit event, then keep detailed spans in the observability system, where access and retention can be tuned for diagnosis. The smaller accountability record belongs in the audit store. The OpenTelemetry generative AI agent span specification supplies a common vocabulary for agent operations and trace context. That vocabulary handles the diagnostic side of the link. It does not establish approval or business authorization by itself.
This separation also limits exposure. Debug telemetry may contain model input, output, or error details. An audit trail should favor stable identifiers and decision summaries. If an investigator needs deeper evidence, the trace ID points to the restricted diagnostic record while it still exists.
Begin with the questions an investigation must answer
Logging every field exposed by the agent framework produces noise quickly. Use a reconstruction exercise instead. Pick one consequential action, perhaps approving a refund or changing a supplier bank account, and work out what an investigator would need after someone disputes the result.
The investigation should be able to answer these questions:
- Which human, service, or scheduled job initiated the workflow?
- Which agent and workflow version processed the request?
- What business action was proposed, and which object was its target?
- Which authorization policy and approval step allowed or denied it?
- Which tool executed the action under which workload identity?
- Did the target system accept, reject, or partly apply the change?
- Which trace and request records contain deeper diagnostic evidence?
Each answer needs a field or a reliable link to another record. The exercise also exposes missing controls. If the system cannot identify the requesting user separately from the service identity that called the tool, adding more prompt text will not fix the gap.
The OWASP Logging Cheat Sheet recommends recording the actor, action, target, result status, time, and an interaction identifier for security events. It also warns against recording data that applications should exclude, including access tokens, passwords, and sensitive personal information. Those principles apply directly to an AI workflow, with a few extra fields for model and policy decisions.
Use one schema across every action boundary
Emit structured events. Free-text messages are difficult to search, validate, and compare after the wording changes. A compact event can describe an intent, an approval, a tool invocation, or a result while retaining the same envelope.
{
"event_id": "evt_01",
"occurred_at": "2026-07-30T05:42:11Z",
"event_type": "tool_action_completed",
"interaction_id": "int_4821",
"trace_id": "trc_7b2",
"requester": {
"subject_id": "usr_184",
"tenant_id": "org_27",
"auth_method": "work_sso"
},
"workflow": {
"agent_id": "invoice_review",
"version": "wf_31",
"policy_version": "pol_12"
},
"decision": {
"action": "invoice.mark_for_payment",
"target_type": "invoice",
"target_id": "inv_9031",
"authorization": "allowed",
"approval_id": "apr_611"
},
"execution": {
"tool": "accounts_payable_api",
"workload_identity": "svc_invoice_agent",
"attempt": 1,
"result": "succeeded",
"target_revision": "rev_88"
},
"data_classification": "confidential",
"redaction_profile": "audit_v3"
}
This contract is an example. Change the field names to fit the system, but keep the identities separate. subject_id names the person or system that asked for the work. workload_identity names the credential that called the downstream tool. agent_id and version identify the code and configuration that made the decision. One generic user field collapses different actors and makes later analysis unreliable.
Use stable action names such as invoice.mark_for_payment, not prose generated by the model. Record target identifiers rather than entire business objects. For a write, keep the target's resulting revision, transaction ID, or downstream receipt when the system provides one. That value helps an investigator prove that the action reached the system of record.
Capture events before and after the tool call
One completion event cannot describe a crash that happens between authorization and the downstream write. Capture the lifecycle at explicit boundaries:
- Record
action_proposedafter the workflow has normalized the model's suggestion into a deterministic action and target. - Record
authorization_decidedwhen the policy engine allows or denies that action. - Record
approval_recordedwhen a person approves, rejects, or edits a consequential request. - Record
tool_action_startedimmediately before the external call, including an attempt number and idempotency key reference. - Record
tool_action_completedortool_action_failedafter the target system responds.
Keep the audit writer outside the model's control. A model may suggest an action, but deterministic application code chooses the event type and fields. Prompt content must not be able to change the logging policy.
For operations that can partly succeed, add an explicit state rather than forcing every result into success or failure. A workflow might create a record but fail to attach a document. Record the completed side effect, the failed step, and the recovery state as separate facts. Do not overwrite the first event when a retry succeeds. Append another attempt so the sequence remains visible.
Redact at collection time
An audit database is often retained longer and accessed by more operational roles than a model trace. Copying prompts and outputs into it creates a second store for customer text, employee data, secrets, and retrieved documents. Avoid that default.
The OWASP logging guidance lists data that should normally be removed, masked, sanitized, hashed, or encrypted before it reaches a log. Apply that decision before serialization. A downstream cleanup job is too late if a credential has already entered the log pipeline, backups, and alerting system.
Prefer these representations:
- Store internal subject and object IDs instead of names, email addresses, or full records.
- Store a policy decision code instead of the policy input document.
- Store the prompt template version and input classification instead of raw prompt text.
- Store a content hash only when it has a defined verification use and cannot become a practical identifier for sensitive data.
- Store the downstream transaction or revision identifier instead of the full response body.
Redaction should be deterministic and versioned. Put the redaction profile name in each event so investigators know which rules applied at collection time. Test the profile with synthetic tokens, personal data, and prompt-injection text. The audit writer must treat all model-produced strings as untrusted input and encode them before storage or display.
Protect the record from the workflow it observes
An agent that can edit or delete its own audit events can hide a bad action, whether the cause is a compromised tool, a software defect, or an overly broad service account. Send events to a separate append-oriented sink through a narrowly scoped writer identity. The workflow should be able to create an event, but not update prior events or change retention settings.
Limit read access too. Audit records reveal user IDs, workflow structure, tool names, policy outcomes, and business-object references. Security staff may need broad search, while a product support role may need access only to one tenant or interaction. Log all administrative searches and exports.
OWASP's guidance covers verification, protection, monitoring, and disposal throughout the logging lifecycle. The NIST AI RMF Playbook organizes AI risk work around Govern, Map, Measure, and Manage actions. Put those ideas into an operating rule: name the audit-system owner, specify who reviews each event class, and define where findings go. A store that nobody reviews cannot provide much accountability.
Set retention by purpose and data class. The audit event may need to outlive its detailed trace, but it does not need to live forever. Document the retention period, legal basis where applicable, deletion process, and any hold mechanism. Keep the policy outside agent configuration so a prompt or workflow release cannot change it.
Walk through one invoice approval
Consider an invoice workflow that extracts payment details, checks a purchase order, asks an employee to approve the payment, and calls an accounts-payable API.
The first audit event identifies the employee who submitted the invoice, the tenant, and the workflow version. The agent proposes invoice.mark_for_payment against inv_9031. Application code checks whether the invoice value and supplier status require human approval. The policy event records the decision code and policy version without copying the invoice into the log.
The approver sees the normalized action, target, amount from the source system, and supplier identity. Their decision produces an approval ID tied to their own authenticated subject. The tool call then uses a dedicated workload identity. A completion event records the target system's transaction and resulting revision.
If the tool times out, the workflow records a failed attempt without claiming that no write occurred. It queries the target system by idempotency key or transaction reference before retrying. The next event records either the discovered prior success or a second attempt. An investigator can now follow the interaction ID from submission through policy, approval, execution, and recovery.
This trail also makes a denied action useful. If the agent proposes a target outside the requester's tenant, record the proposed stable identifiers, the denial code, and the workflow version. Do not call the tool. Repeated denials for the same agent version may indicate a mapping defect or an attack. The OWASP agentic AI threats and mitigations resource provides a threat-modeling frame for systems where generative AI can act through autonomous components and business tools.
Test reconstruction, not just event delivery
Delivery is only the first check. The useful test is whether someone can reconstruct a known scenario from the stored records.
Create a synthetic workflow run that includes an approval, one failed tool attempt, and a successful recovery. Give an investigator only the initial request ID. They should be able to identify the requester, tenant, workflow and policy versions, proposed action, approver, workload identity, target, both attempts, final result, and linked trace. If any answer depends on searching raw message text, the schema needs another stable field.
Run four additional checks:
- Submit synthetic credentials and personal data through every model-controlled field, then prove that none appears in the audit sink.
- Attempt to update and delete an existing event with the workflow's writer identity. Both operations should fail.
- Break the telemetry service and confirm the business action follows the documented policy. For a high-risk action, that may mean stopping rather than operating without an audit record.
- Compare the audit completion event with the system-of-record revision or transaction receipt. Detect any action that reached the target without a matching event.
Alert on missing sequences, not only explicit errors. An action_proposed event with no authorization decision may mean a crash. A started tool action with no completion needs reconciliation. An approval tied to a different tenant or target should be rejected before execution and flagged for review.
Common mistakes that weaken the trail
Logging the full chain of thought is not an accountability design. It adds sensitive text without producing stable, testable decisions. Record the normalized action, policy outcome, evidence references, and result instead.
Using one service identity for every field is another common failure. The requester, approver, agent version, and executing workload are different actors. Preserve each one.
Do not treat an immutable store as a substitute for data minimization. A perfectly protected secret is still a secret copied into the wrong system. Redact before the event leaves the application boundary.
Finally, avoid an audit schema that exists only in documentation. Define it as a versioned contract, validate required fields at the writer, reject unknown event types, and include audit-event tests in workflow release checks.
Put the first action under audit
Choose one consequential tool action in the current workflow. Map the seven investigation questions to structured fields, then add lifecycle events around authorization and execution. Run the failed-attempt reconstruction exercise with an engineer who did not build the workflow. If they cannot prove who authorized the action and what the target system did, fix the schema before adding another tool.
References
- OWASP Logging Cheat Sheet supports the event attributes, interaction identifiers, data-exclusion rules, verification steps, and log-protection guidance.
- OWASP Agentic AI threats and mitigations supports threat modeling for generative AI connected to autonomous components and business tools.
- NIST AI RMF Playbook supports the Govern, Map, Measure, and Manage framing for AI risk ownership and operational controls.
- OpenTelemetry generative AI agent spans supports the trace context and semantic vocabulary used to link agent operations with diagnostic telemetry.