Blog Post

Linux and Open Source Blog
10 MIN READ

After the Agent Acts: Proving What Happened and Who Authorized It

mosiddi's avatar
mosiddi
Icon for Microsoft rankMicrosoft
May 14, 2026

In this third and final post of the Agent Governance Toolkit series, we move past the moment of action. Parts one and two covered runtime policy enforcement and shift-left CI gates. This post tackles the harder question: after an agent has already acted, can you prove who authorized it, through what chain, and whether the evidence was altered? That is the accountability gap, and it is where most agent deployments have no answer today.

In part one of this series, we covered AGT's runtime governance: the policy engine, zero-trust identity, execution sandboxing, and the OWASP Agentic AI risk mapping. In part two, we moved earlier in the lifecycle: shift-left governance, CI/CD gates, attestation workflows, and supply chain integrity.

Both posts focused on governance that happens around the moment of action, before it, during it, or right after it. That coverage is essential. But after those posts went live, a different pattern emerged in conversations with teams deploying agents in production. The question was more pointed:

"An agent executed a financial transfer last Tuesday. A compliance officer is asking us to show who authorized it, through what chain, and exactly what scope it was granted. We have logs. But can we prove they weren't altered?"

No policy engine prevents a past action. No CI gate reconstructs a delegation chain after the fact. No shift-left tool tells an auditor whether the cryptographic identity that authorized a trade was legitimately derived from a human principal, or was injected mid-chain.

This is the accountability gap. It is the governance question that neither runtime enforcement nor pre-runtime checks were designed to answer. Regulatory frameworks are tightening: the EU AI Act includes high-risk obligations with enforcement timelines in 2026, and the Colorado AI Act introduces requirements for automated decision-making. Courts are beginning to encounter AI agents in the evidentiary record. The accountability infrastructure has not caught up.

This post covers what post-hoc accountability means for autonomous agents, what the Agent Governance Toolkit has to help address it, and three value propositions that are real but not yet visible in how governance tooling is typically described.

Note: The policy files, workflow configurations, and code samples in this post are illustrative examples designed to show the concepts. For working implementations, see the QUICKSTART.md in the repository.

The Accountability Gap in Multi-Agent Systems

The accountability problem is architectural. When a single agent takes a single action, accountability is straightforward: you know which model ran, what prompt it received, and what it called. When agents delegate to sub-agents, which delegate further to tool-execution agents, the chain of authorization becomes progressively disconnected from the original human instruction that started it.

Consider this delegation topology, common in any production orchestration scenario:

Human Principal
  └── Orchestrator Agent (did:mesh:orchestrator-001)
        └── Data Analyst Agent (did:mesh:analyst-001)
              └── File Write Tool (write /reports/q3-summary.csv)

By the time file_write fires, three delegation hops have occurred. The file write tool has no reliable way to know whether the human principal actually authorized file writes, what scope they granted to the orchestrator, or whether the analyst agent's instructions arrived through a legitimate delegation or were injected by a prompt injection attack.

This gap has three concrete consequences:

Consequence

Operational Impact

Post-hoc audits cannot reconstruct authorization

Incident investigations are limited to "the agent did this," not "here is who authorized this, through what chain, at what time, with what scope"

Agents cannot distinguish legitimate delegation from injection

A prompt injection attack that inserts itself into a delegation chain is indistinguishable from a real orchestrator instruction without cryptographic verification

Accountability cannot be attributed to a human authorization event

When a regulator asks "who is responsible for this action," the answer is a shrug and a log file

AGT already has the technical foundations designed to help close all three. The gap is not capability, it is visibility.

What AGT Has: The Cryptographic Accountability Stack

AGT's accountability infrastructure spans three components that work together: cryptographic agent identity, delegation chains, and tamper-evident audit logs.

1. Ed25519 Agent Identity with Lifecycle Management

Every agent in an AGT-governed system carries a cryptographic identity: a verifiable Ed25519 keypair with a W3C DID Document that can be exported, shared, and verified by any participant in the system.

from agentmesh import AgentIdentity, IdentityRegistry

 # Create a verifiable agent identity
 identity = AgentIdentity.create(
     name="data-analyst",
     sponsor="operator@contoso.com",
     capabilities=["data.read", "report.write"],
     organization="data-team",
     description="Q3 close data analyst agent"
 )

 # Export as W3C DID Document for cross-system verification
 did_document = identity.to_did_document()

 # Register in the shared identity registry
 registry = IdentityRegistry()
 registry.register(identity)

Identity lifecycle states, active, suspended, revoked, are tracked and cascaded. When an orchestrator identity is revoked, every downstream agent delegated from it is also invalidated. This cascade revocation behavior lets you kill a compromised delegation chain from its root rather than hunting sub-agents individually.

2. Delegation Chains with Scope Inheritance

When an orchestrator delegates to a sub-agent, AGT records the delegation cryptographically: who delegated, to whom, what capabilities were transferred, and what restrictions were applied. Sub-agents are designed to be unable to exceed the scope of their delegating principal.

from agentmesh import ScopeChain, DelegationLink

 # Create a scope chain rooted in a human sponsor
 chain, root_link = ScopeChain.create_root(
     sponsor_email="operator@contoso.com",
     root_agent_did=str(orchestrator_identity.did),
     capabilities=["data.read", "report.write", "data.delete"],
     sponsor_verified=True,
 )

 # Orchestrator delegates narrowed scope to analyst agent
 link = DelegationLink(
     link_id="link-analyst-001",
     depth=1,
     parent_did=str(orchestrator_identity.did),
     child_did=str(analyst_identity.did),
     parent_capabilities=["data.read", "report.write", "data.delete"],
     delegated_capabilities=["data.read", "report.write"],  # narrowed: no delete
     parent_signature=orchestrator_identity.sign(
         f"{orchestrator_identity.did}:{analyst_identity.did}:data.read,report.write".encode()
     ),
     link_hash="",  # computed on add
     previous_link_hash=root_link.link_hash,
 )
 link.link_hash = link.compute_hash()
 chain.add_link(link)

 # Verify the entire chain: scope narrowing + hash integrity + signatures
 valid, reason = chain.verify()
 if not valid:
     raise ValueError(f"Chain verification failed: {reason}")

The scope chain carries the human authorization context: the root sponsor email, when the chain was created, and what capabilities were granted at the top. Every downstream agent can trace any capability back through the chain using chain.trace_capability("data.read"). A file write tool executing three hops from the human principal can verify that the original sponsor authorized file writes in this scope. This is the mechanism designed to help close the prompt injection gap: an injected instruction cannot produce a valid signed delegation link from a legitimate orchestrator identity.

3. Tamper-Evident Audit Logs

Every policy decision, every delegation event, every tool call, every trust score evaluation: AGT writes a signed, append-only audit record. The signature covers the content hash of the log entry plus the hash of the preceding entry, forming a chain where tampering is designed to be detectable.

 from agentmesh import PolicyEngine, AuditLog

 # Create the audit log (with optional external sink for production)
 audit_log = AuditLog()

 # Log a governance decision
 entry = audit_log.log(
     event_type="policy_decision",
     agent_did=str(analyst_identity.did),
     action="report.write",
     resource="/reports/q3-summary.csv",
     data={"task_id": "q3-close-2026"},
     outcome="success",
     policy_decision="allow",
 )

 # Verify the audit chain has not been tampered with
 valid, reason = audit_log.verify_chain()
 # valid == True: all hashes and chain links are intact

 # Query audit trail for a specific agent
 trail = audit_log.get_entries_for_agent(str(analyst_identity.did))

The audit trail for a single task session includes the complete delegation chain, from human authorization event at the top to tool execution at the bottom, with cryptographic signatures at every step.

Validating a Compliance Evidence Package

The three components above are most powerful when used together. At runtime, AGT's audit chain, identity registry, and delegation system each produce structured records. Assembling these into a single evidence package for compliance submission or incident investigation is a deployment-level concern: your CI pipeline or orchestration layer collects the outputs into a JSON artifact.

Once assembled, AGT's agt verify --evidence flag validates the package: checking that signatures are intact, delegation chains are complete, and audit entries have not been tampered with.

 # Validate a runtime evidence package
  agt verify --evidence ./agt-evidence.json

  # Strict mode: fail if evidence is missing, incomplete, or signatures don't verify
  agt verify --evidence ./agt-evidence.json --strict

Future direction: A built-in agt evidence collect command to automate evidence assembly is on the backlog.

The evidence package helps answer the audit questions directly:

Auditor Question

Where It Lives in the Evidence Package

Which agent executed this action?

identity.agent_id with Ed25519 public key

Who authorized it?

delegation_chain[0].human_principal with timestamp

What scope was granted?

delegation_chain[*].granted_capabilities at each hop

Was the delegation legitimate?

delegation_chain[*].signature, verifiable against issuer's public key

Was the audit log altered?

audit_trail.chain_valid: true/false with entry-level hash verification

What policy governed the action?

policy_decision.rule_name with the policy YAML snapshot at decision time

This is the difference between "we have logs" and "here is a verifiable chain of custody backed by cryptographic signatures."

The Governance Dial: Enabling Autonomy, Not Just Blocking Risk

There is a framing problem in how agent governance is typically described. Governance is described almost entirely as a constraint: what agents cannot do, what gets blocked, what violations get caught. This framing is accurate but incomplete.

Governance is the mechanism that helps you safely expand what your agents can do.

Without governance evidence, every expansion of agent autonomy is a leap of faith. With it, expansions are decisions with a measured risk profile:

Scenario

Without Governance Evidence

With AGT Accountability Stack

Expand agent to write to production databases

Requires human approval on every write indefinitely

Pilot with human-in-loop for 500 writes; audit trail shows 0 violations; graduate to autonomous

Deploy agent in a regulated data environment

Blocked by legal until "we can prove it"

Evidence package helps satisfy audit requirement; deployment proceeds

Respond to a security incident involving an agent

Manually reconstruct what happened from scattered logs

Pull the task session's evidence package; full chain of custody in minutes

The governance layer is the dial between supervised and autonomous operation. Audit evidence is what helps justify turning the dial further in the autonomous direction.

Blast Radius: The Governance Assurance You're Not Advertising

The sandboxing and privilege ring system in AGT is typically described in security terms: isolation, privilege reduction, process-level enforcement. But there is a more concrete operational value: blast radius definition before an incident occurs.

The question every operations team needs to answer before deploying an autonomous agent at scale is:

*"If this agent goes wrong, not if, when, what is the worst-case outcome?"*

Without governance-enforced privilege boundaries, the answer is uncomfortably open-ended. With AGT's capability model and execution rings, the blast radius is a policy configuration: a bounded, declared set of resources the agent can touch, scoped to what the task requires.

# policies/financial-agent.yaml
apiVersion: governance.toolkit/v1
version: "1.0"
name: financial-agent-policy
default_action: deny

rules:
  - name: allow-report-write
    condition: "tool_name == 'report.write' and path.startswith('/data/reports/')"
    action: allow
    priority: 10
  - name: allow-data-read
    condition: "tool_name == 'data.read' and path.startswith('/data/processed/')"
    action: allow
    priority: 10

With this policy in place, the worst-case outcome for this agent is declared in the policy file, not discovered during a post-incident review. The audit log records not just what the agent did, but also every action that was blocked, giving you a full picture of how close any session came to the declared blast boundary.

Regulatory Alignment

The OWASP-COMPLIANCE.md in the AGT repository maps the toolkit's controls to each of the 10 OWASP Agentic AI risks. The compliance picture for specific regulatory frameworks:

Regulatory Requirement

Relevant Framework

AGT Control

Technical documentation for high-risk AI

EU AI Act, Art. 9-11

Evidence package, policy audit trail, OWASP attestation

Logging for automated decisions

EU AI Act, Art. 12

Tamper-evident audit log with entry-level signatures

Human oversight mechanisms

EU AI Act, Art. 14

Circuit breakers, privilege rings, delegation scope limits

Algorithmic impact assessment

Colorado AI Act

Policy snapshot at decision time, signed governance evidence

Audit trail for automated decisions

HIPAA, SOC 2 Type II

Immutable audit log with W3C DID-based agent identity

Non-repudiation of agent actions

Financial services (MiFID II, SEC)

Ed25519-signed audit entries, delegation chain with human auth context

Note: The Agent Governance Toolkit does not guarantee compliance with any specific regulatory framework. The mappings above show how the toolkit's controls align with common requirements. Consult legal counsel for your specific obligations.

Putting It Together

The three posts in this series cover three distinct layers of the governance lifecycle:

Layer

Timing

Primary Value

Post

Shift-left governance

Before production

Catch policy violations at commit, PR, and CI time

Part 2

Runtime governance

At the moment of action

Deterministic policy enforcement, zero-trust identity, sandboxing

Part 1

Post-hoc accountability

After the action

Cryptographic chain of custody, blast radius evidence, regulatory proof

This post

None of these layers substitutes for the others. Pre-runtime governance cannot prevent a runtime violation. Runtime enforcement cannot retroactively prove authorization. Post-hoc accountability cannot undo an action that runtime governance should have blocked. They compose.

Getting Started

If you already have the AGT policy engine in place, the path to full accountability coverage is incremental:

  1. Add agent identity - Create identities for each agent and register them. Export DID documents for cross-service verification.
  2. Record delegation tokens - At each orchestrator-to-agent delegation boundary, create and sign a delegation link. Pass tokens as context to the policy engine.
  3. Configure a tamper-evident audit backend - Configure the audit chain with a signing key and chain verification. For production, use an immutable backend: Azure Blob with WORM retention, S3 Object Lock, or equivalent.
  4. Generate your first evidence package:
agt verify --evidence ./agt-evidence.json --strict
  1. Add evidence generation to your CI/CD release gate:
# .github/workflows/release.yml
- name: Governance Evidence Gate
  uses: microsoft/agent-governance-toolkit/action@<sha> #v3.5.0
  with:
    command: governance-verify
    evidence-path: ./agt-evidence.json
    strict: true
    fail-on-missing-chain: true

Conclusion

Runtime governance and shift-left governance answer the question: did we apply the right controls? Post-hoc accountability answers the question: can we prove it?

The Agent Governance Toolkit has the technical infrastructure designed to help answer it: Ed25519 agent identity with cascade revocation, cryptographically signed delegation chains with human authorization context, and tamper-evident audit logs that form a verifiable chain of custody from human principal to terminal tool call.

The governance dial analogy is worth keeping. Every autonomous agent deployment exists on a spectrum between fully supervised and fully autonomous. The limiting factor on where you can set that dial is not model capability or framework maturity. It is how much governance evidence you have, and how verifiable that evidence is.

Resources

Have questions about deploying AGT in your environment? Open an issue at aka.ms/agent-governance-toolkit or join the conversation in the comments below.

Updated May 14, 2026
Version 1.0
No CommentsBe the first to comment