DEV Community

AgentGraph
AgentGraph

Posted on

How We Built Verifiable Agent Identity with DIDs — and Why the Moltbook Breach Should Scare You

TL;DR: AI agent platforms without identity verification are a security disaster waiting to happen — and the Moltbook breach proved it. AgentGraph uses W3C Decentralized Identifiers (DIDs) to give every agent a cryptographic identity that's auditable, on-chain, and not owned by any single platform. Here's how we built it and what we got wrong along the way.


The Moltbook breach hit 35,000 emails and 1.5 million API tokens. 770,000 agents, zero identity verification. Meta acquired the platform, the breach happened, and suddenly every developer who had integrated Moltbook agents into their pipelines had to assume those agents were compromised. No audit trail. No way to know which agents had been tampered with. No cryptographic proof of anything.

That's the actual problem we're solving at AgentGraph.

OpenClaw has 512 CVEs and 12% of their skills marketplace has been flagged as malware. These aren't edge cases — they're what happens when you build agent infrastructure without identity as a first-class concern.


Why Agent Identity Is Different From User Identity

OAuth solves identity for humans. JWT handles session auth. X.509 certificates work for servers. None of these map cleanly to agents.

An agent isn't a user. It acts autonomously, often across multiple sessions, sometimes spawning sub-agents, sometimes being cloned or forked by other operators. The identity model needs to handle:

  • Persistence across sessions — the agent's identity shouldn't be tied to a single API session or runtime
  • Delegation — agent A can authorize agent B to act on its behalf, and that delegation needs to be verifiable
  • Evolution — an agent that gets new capabilities, a new model, or a new system prompt is still "the same agent" in some meaningful sense, but that change should be auditable
  • Portability — identity shouldn't be locked to one platform

W3C DIDs solve most of this. A DID is a globally unique identifier that resolves to a DID document containing public keys, service endpoints, and verification methods. The identifier itself is controlled by whoever holds the private key — not by a registry, not by a platform.

did:agentgraph:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK
Enter fullscreen mode Exit fullscreen mode

That's what an agent identity looks like on AgentGraph. The did:agentgraph method stores the DID document on-chain, which means resolution doesn't go through our servers. If we disappear tomorrow, your agent's identity still resolves.


The Architecture

Here's the high-level flow:

Agent Operator
     
     
AgentGraph SDK
     
     ├── Generates keypair (Ed25519)
     ├── Creates DID document
     ├── Anchors to chain
     └── Returns DID + verification material

     
     
DID Document (on-chain)
{
  "@context": ["https://www.w3.org/ns/did/v1"],
  "id": "did:agentgraph:z6Mkha...",
  "verificationMethod": [{
    "id": "did:agentgraph:z6Mkha...#key-1",
    "type": "Ed25519VerificationKey2020",
    "controller": "did:agentgraph:z6Mkha...",
    "publicKeyMultibase": "z6Mkha..."
  }],
  "service": [{
    "id": "did:agentgraph:z6Mkha...#agentgraph",
    "type": "AgentGraphProfile",
    "serviceEndpoint": "https://agentgraph.co/agents/z6Mkha..."
  }]
}
Enter fullscreen mode Exit fullscreen mode

When agent A wants to verify it's talking to agent B, it resolves B's DID, gets the public key from the DID document, and checks that B's messages are signed with the corresponding private key. No central authority involved. No "trust us, we verified them."


Registering an Agent: The SDK Flow

Here's what registration looks like using the AgentGraph SDK:

from agentgraph import AgentGraph, AgentConfig

# Initialize the client
ag = AgentGraph(api_key="your-api-key")

# Register a new agent with a verifiable identity
agent = ag.agents.register(
    AgentConfig(
        name="data-pipeline-agent-v2",
        description="Processes and validates financial data streams",
        capabilities=["data-processing", "validation", "reporting"],
        operator_did="did:agentgraph:z6MkOperator...",  # your DID as operator
        model="gpt-4o",
        version="2.1.0"
    )
)

print(agent.did)
# did:agentgraph:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK

print(agent.trust_score)
# 72  (starts lower, increases with verified activity)

# Sign a message as this agent
signed_message = agent.sign({
    "action": "process_batch",
    "batch_id": "batch-20260318-001",
    "timestamp": "2026-03-18T09:00:00Z"
})

# Another agent verifying that signature
verification_result = ag.verify(
    did="did:agentgraph:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK",
    message=signed_message.message,
    signature=signed_message.signature
)

print(verification_result.valid)  # True
print(verification_result.trust_score)  # 72
print(verification_result.audit_trail_url)  # Link to on-chain history
Enter fullscreen mode Exit fullscreen mode

The operator_did field is where the human accountability chain starts. Every agent is registered by an operator, and that operator has their own DID. If an agent goes rogue, you can trace back to the operator who deployed it.


The Trust Score: What It Actually Measures

Trust scores are the part we've thought hardest about and gotten wrong in interesting ways.

The score (0-100) is a composite of:

  • Identity verification depth — just a DID, or DID + operator verification + source repo?
  • Behavioral consistency — does the agent do what its DID document claims it does?
  • Audit trail length — how much verifiable history exists?
  • Operator reputation — what's the trust score of the humans/orgs behind this agent?
  • Capability attestations — third-party verification of claimed capabilities

What we got wrong in v1: we weighted "age" too heavily. An agent that had been around for six months got a big trust boost just from longevity. That's wrong. A malicious agent that's been operating quietly for six months is more dangerous, not more trustworthy. We now weight behavioral consistency against claimed capabilities much more heavily.

The other thing we got wrong: we tried to make the score opaque, like a credit score. Developers hated it. Now every component is visible in the API response:

{
  "did": "did:agentgraph:z6Mkha...",
  "trust_score": 72,
  "components": {
    "identity_depth": 85,
    "behavioral_consistency": 78,
    "audit_trail": 65,
    "operator_reputation": 70,
    "capability_attestations": 60
  },
  "last_updated": "2026-03-18T08:45:00Z",
  "audit_trail_entries": 147
}
Enter fullscreen mode Exit fullscreen mode

The Audit Trail Problem

Every change to an agent's capabilities, model, or system prompt gets recorded as an on-chain event. This is the "evolution trail" — the idea that you can see exactly how an agent has changed over time.

This matters because the Moltbook-style attack vector isn't just "steal credentials." It's "quietly modify an agent's behavior and wait." If you can't see that an agent's system prompt changed three weeks ago, you can't detect that attack.

The trade-off here is cost. On-chain writes aren't free. We batch non-critical updates and only write immediately for security-relevant changes (new keys, capability additions, operator changes). Minor version bumps get batched into daily writes. It's a compromise — a sophisticated attacker could theoretically modify an agent and wait for the batch window. We're honest about that.

The alternative was keeping the audit trail off-chain in our database. Faster, cheaper, but then you're trusting us. For a trust infrastructure platform, that's a bad look.


MCP Bridge and Tool Discovery

Agents don't just have identities — they use tools. The Model Context Protocol is becoming the standard way agents discover and call tools, and we've built a bridge that integrates DID-based identity into that flow.

When an agent discovers a tool through AgentGraph's MCP bridge, it gets the tool's DID, trust score, and audit trail alongside the normal MCP response. Before calling an untrusted tool, the agent can check:

  • Is this tool's DID document valid and resolvable?
  • What's the trust score?
  • Has this tool's behavior changed recently in unexpected ways?

We also open-sourced mcp-security-scan — a CLI and GitHub Action that scans MCP servers for credential theft vectors, data exfiltration patterns, unsafe execution, filesystem access, and code obfuscation. It outputs a trust score that integrates directly with AgentGraph trust badges.

# Scan an MCP server before integrating it
npx mcp-security-scan scan --server https://mcp.example.com/tools

# Output:
# Trust Score: 67/100
# ⚠️  Filesystem access detected (read: /tmp, write: none)
# ✅  No credential theft patterns found
# ✅  No data exfiltration vectors detected
# ⚠️  One obfuscated code block in tool handler
# 
# Full report: https://agentgraph.co/scan/abc123
Enter fullscreen mode Exit fullscreen mode

The GitHub Action version runs in CI so you catch problems before deployment. It's MIT licensed because the goal is for this to become standard practice, not to lock anyone in.


Why On-Chain and Not Just a Database?

This is the question we get most often.

The honest answer: on-chain is slower, more expensive, and more complex to operate. We chose it anyway because the alternative — a database we control — creates a single point of failure and a single point of trust. If our database gets breached (see: Moltbook), all the identity records are compromised. If we get acquired and the acquirer has different incentives, the identity records can be modified.

On-chain means the DID documents are verifiable without going through our infrastructure. An agent can resolve another agent's DID using any DID resolver that supports the did:agentgraph method. We're not in the critical path for verification.

The cost is real though. We absorb chain write costs for registered agents and pass them through at scale. It adds latency to registration (seconds, not milliseconds). For high-frequency updates, it's genuinely limiting.

Some things we keep off-chain: the social graph visualization, detailed behavioral logs, the marketplace listings. Those live in a database. The cryptographic roots — keys, capability hashes, operator relationships — go on-chain.


What the Healthcare and Finance Verticals Are Teaching Us

A few teams building AI agents for healthcare have started using AgentGraph, and they've pushed us hard on one thing we hadn't fully thought through: agent delegation chains.

A healthcare agent might be: deployed by a hospital (operator), configured by a department (sub-operator), and used by a specific doctor (end user). The liability chain matters. When the agent makes a recommendation, who is cryptographically accountable?

We're building delegation proofs into the DID document structure — verifiable credentials that capture the full chain from operator to end user. It's not shipped yet. But the requirement is real and the W3C Verifiable Credentials spec gives us the building blocks.

The finance teams have a different problem: they need to prove to auditors that the agent that ran a transaction in January is the same agent (or provably different) from the one running transactions now. The audit trail solves this, but only if the auditors can read it. We're working on a human-readable audit report export that doesn't require understanding DIDs.


Getting Started

If you're building agents and you're not thinking about identity yet, the Moltbook breach is the argument. 1.5 million API tokens exposed because there was no cryptographic link between agents and their operators.

AgentGraph is live and free to register. You get a DID for your agent, a trust score, and access to the API and marketplace. The SDK supports Python and TypeScript, with more coming.

The mcp-security-scan tool is a good starting point even if you're not ready to commit to the full platform — run it against any MCP servers you're integrating and see what comes back.

Full docs, API reference, and early access registration are at agentgraph.co.


Disclosure: This post was generated with AI assistance and reviewed by the AgentGraph team. We think transparency about that is table stakes for a company whose whole thing is trust.

Top comments (0)