Implementing Zero-Trust Agent Identity with Ed25519 Keys and AgentDID Format

Implement zero-trust agent identity by generating cryptographically-bound DIDs in the format did:mesh:<unique-id> with Ed25519 key pairs that never leave the agent's memory, enabling non-repudiable signatures, human accountability, and continuous trust validation across multi-agent systems.

The Microsoft Agent Governance Toolkit (AGT) provides a comprehensive zero-trust identity layer for AI agents, implemented across Python, Go, TypeScript, and Rust. This implementation ensures that every autonomous entity operates under a verifiable, non-repudiable identity tied to human sponsorship and capable of secure delegation chains.

Understanding the AgentDID Format

The AgentDID format follows the W3C Decentralized Identifier specification, using the scheme did:mesh:<unique-id>. This structure provides globally unique, self-sovereign identifiers that are cryptographically verifiable without centralized authority.

DID Structure and Generation

Each DID contains a 128-bit random hex token generated using secrets.token_hex(16) in agent_id.py (lines 36-48). This approach avoids deterministic seeds and guarantees high entropy, preventing predictability attacks.

from agentmesh import AgentDID

# Generate a new DID

did = AgentDID.generate(name="ReportWriter", org="Analytics")
print(did)  # did:mesh:7f3a9b2c...

The AgentDID.generate method creates identifiers that are statistically unique and compliant with the toolkit's mesh architecture, as implemented in agent-governance-python/agent-mesh/src/agentmesh/identity/agent_id.py.

Implementing Ed25519 Key Management

The toolkit leverages Ed25519 elliptic curve cryptography for all identity operations, providing high-security signatures with compact key sizes and fast verification times.

Key Generation and Storage

When AgentIdentity.create is invoked (lines 71-81 in agent_id.py), the system generates a fresh Ed25519 key pair using ed25519.Ed25519PrivateKey.generate() (lines 71-73). The public key is Base64-encoded and persisted in the identity model, while the private key remains strictly in-memory only, stored in the _private_key attribute (lines 13-14).

from agentmesh import AgentIdentity

agent = AgentIdentity.create(
    name="DataProcessor",
    sponsor="[email protected]",
    capabilities=["read:data", "write:reports"],
)

print(agent.did)         # did:mesh:a1b2c3...

print(agent.public_key)  # Base64-encoded Ed25519 public key

This memory-only constraint for private keys ensures that compromised storage or logs never reveal signing material, maintaining the zero-trust property of cryptographic non-repudiation.

Signing and Verification

Agents can cryptographically sign arbitrary payloads using AgentIdentity.sign (lines 104-110), while peers verify signatures via verify_signature (lines 112-126) using the stored public key.

payload = b"important command"
sig = agent.sign(payload)

# Verification by any party possessing the public key

is_valid = agent.verify_signature(payload, sig)
print(is_valid)  # True

Both methods utilize the Ed25519 algorithm's deterministic signature scheme, ensuring consistent behavior across all supported language implementations.

Human Sponsorship and Accountability

Every agent identity requires a human sponsor, enforcing accountability and enabling policy-based governance limits.

The sponsor_email field is mandatory and validated in validate_sponsor_email (lines 32-38). The validation ensures proper email formatting before identity creation, preventing anonymous or unattributed agents.

if not "@" in sponsor:
    raise IdentityError("Invalid sponsor email")

This requirement enables organizational policies that limit the number of agents per sponsor, restrict delegation depth, and maintain audit trails for autonomous actions.

Delegation Chains and Capability Scoping

The toolkit supports hierarchical agent relationships through cryptographically-verified delegation, enabling parent agents to spawn restricted child agents without sharing their full capability set.

Delegation Constraints

Delegation enforces three critical security boundaries:

  • Maximum depth: Limited to MAX_DELEGATION_DEPTH = 10 (line 35)
  • No wildcard propagation: Explicitly blocked in delegate (lines 74-78)
  • Subset enforcement: Child capabilities must be present in the parent (lines 81-86)

Creating Child Agents

The AgentIdentity.delegate method (lines 34-66, 98-101) creates child identities with narrowed permissions and a recorded parent relationship.

child = parent.delegate(
    name="ReportWriter",
    capabilities=["write:reports"],  # Subset of parent capabilities

    max_initial_trust_score=600,
)

print(child.parent_did)       # Parent's DID

print(child.delegation_depth) # 1

This design prevents privilege escalation and mitigates Sybil attacks by ensuring trust scores and capabilities decrease or remain constant down the delegation chain.

Lifecycle Management and Revocation

The zero-trust model requires rapid response to compromised identities, implemented through immediate revocation with sub-five-second propagation.

Revocation and Suspension

Identity states include active, suspended, and revoked, tracked in the status field (line 101). The AgentIdentity.revoke method (lines 104-108) initiates permanent disablement, while suspend and reactivate provide temporary controls.

from agentmesh.identity import IdentityRegistry

registry = IdentityRegistry()
registry.register(agent)

# Immediate revocation with automated child propagation

registry.revoke(agent.did, reason="Compromised key")

Registry Integration

The IdentityRegistry class (lines 38-85) centralizes identity lookups and attestation enforcement. When _require_attestation is enabled, the register method verifies attestations before acceptance (lines 52-58). The registry also provides trust verification via is_trusted (lines 76-84).

Revocation propagates automatically to all delegated children through IdentityRegistry.revoke (lines 86-99), ensuring that compromising a parent identity cannot be circumvented by using child agents.

Interoperability and Export Formats

To support integration with external identity systems and W3C standards, agents export to standard formats.

JWK and DID Document Export

The to_jwk method exports keys as JSON Web Key format, while to_did_document (lines 514-535) generates W3C-compliant DID Documents containing verification methods and public key material.

jwk = agent.to_jwk()
did_doc = agent.to_did_document()

print(did_doc["@context"])
print(did_doc["verificationMethod"][0]["publicKeyBase64"])

These exports enable interoperability with existing decentralized identity infrastructure and blockchain-based DID resolvers.

Summary

  • AgentDID Format: Uses did:mesh:<unique-id> with 128-bit entropy generated via secrets.token_hex(16) in AgentDID.generate.
  • Ed25519 Security: Private keys remain in-memory only (_private_key), while public keys are Base64-encoded and shareable for signature verification.
  • Human Accountability: Mandatory sponsor_email validation ensures every agent traces back to a human operator.
  • Delegation Controls: Hard limit of 10 delegation levels with strict capability subsetting prevents privilege escalation.
  • Zero-Trust Lifecycle: Revocation propagates to all children within seconds via IdentityRegistry.revoke.

Frequently Asked Questions

What is the AgentDID format?

The AgentDID format follows the pattern did:mesh:<unique-id>, where the unique identifier is a 128-bit random hex string generated by AgentDID.generate in agent_id.py. This format provides globally unique, cryptographically verifiable identifiers that do not require centralized registration, enabling self-sovereign identity for autonomous agents.

How are private keys protected in the Agent Governance Toolkit?

Private keys are generated using ed25519.Ed25519PrivateKey.generate() and stored only in the _private_key attribute of the AgentIdentity instance (lines 13-14). They never persist to disk or external storage, existing only in volatile memory for the agent's lifecycle. This design prevents key extraction from compromised storage systems while maintaining signing capability through the sign method.

What is the maximum delegation depth for agent hierarchies?

The toolkit enforces a maximum delegation depth of 10 levels, defined by the constant MAX_DELEGATION_DEPTH (line 35). This limit prevents uncontrolled chain elongation that could complicate revocation propagation and trust calculation. Attempting to delegate beyond this depth raises an exception in the delegate method.

How does revocation propagate through delegation chains?

When IdentityRegistry.revoke is called (lines 86-99), it recursively invalidates the target identity and all descendants in its delegation tree. The registry updates the status field to revoked for the parent and automatically traverses child relationships, ensuring that compromised parent credentials cannot be exploited through existing child agents. This propagation completes in under five seconds according to the implementation specifications.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →