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 | |
|
Runtime governance |
At the moment of action |
Deterministic policy enforcement, zero-trust identity, sandboxing | |
|
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:
- Add agent identity - Create identities for each agent and register them. Export DID documents for cross-service verification.
- Record delegation tokens - At each orchestrator-to-agent delegation boundary, create and sign a delegation link. Pass tokens as context to the policy engine.
- 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.
- Generate your first evidence package:
agt verify --evidence ./agt-evidence.json --strict
- 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
- GitHub: microsoft/agent-governance-toolkit: AI Agent Governance Toolkit — Policy enforcement, zero-trust identity, execution sandboxing, and reliability engineering for autonomous AI agents. Covers 10/10 OWASP Agentic Top 10.
- Quickstart: Quick Start - Agent Governance Toolkit
- OWASP Compliance Mapping: OWASP Compliance - Agent Governance Toolkit
- PyPI: pip install agent-governance-toolkit[full]
- npm: npm install BANNEDUSERNAME/agent-governance-sdk
- NuGet: dotnet add package Microsoft.AgentGovernance
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.