Skip to content

Repository files navigation

0G AgenticID

Give every AI agent a chain-anchored identity that spans its entire lifecycle and that anyone can independently verify.

AgenticID is a protocol built on the 0G ecosystem. It anchors an agent's functional data on chain, runs its code inside a TEE, and stamps every response with a key that exists only inside that TEE — turning "this agent is trustworthy" from a claim you take on faith into a property anyone can verify for themselves.


The trust problem no one talks about

Most of the conversation around AI agents is about capability: how autonomously an agent can act, how many tools it can chain, how much it can decide on a user's behalf. A more fundamental question almost never gets asked out loud:

How do you know the agent serving you right now is actually what it claims to be?

This is an engineering question, not a philosophical one. Deploying an agent today means running some code on a server and exposing it to the world. As a user, you cannot verify which model it uses, whether its behavior has been quietly altered, or whether the response you just received came from the advertised configuration rather than something the owner swapped in.

The deeper problem is structural: an agent is wholly subordinate to its owner. The owner can change the agent at any time, with no record and no accountability. In a world where agents need to make binding commitments, collaborate autonomously, and accumulate reputation, this is a foundational flaw. AgenticID addresses it head-on.


The trust chain: four layers, each independently verifiable

AgenticID decomposes trust into a continuous chain from the contract root to every single response. Each layer is independently verifiable, and they compose seamlessly:

chain identity  →  runtime config  →  execution env  →  model inference
 ERC-7857           iData +           TEE +              0g-compute
 ERC-8004           0G Storage        AgentSeal          (verifiable inference)
 AgentSeal
Layer Question it answers What it relies on
Chain identity Which agent is this? Who owns it? What's its history? ERC-8004 identity + ERC-7857 token + AgentSeal registry
Runtime config What model / memory / config is it running right now? Encrypted iData on 0G Storage, fingerprint anchored on chain
Execution env Is what's declared on chain actually running? 0g-Tapp (Intel TDX) + image-hash allowlist
Model inference Is the inference itself trustworthy? 0g-compute (verifiable inference inside TEE)

Terminology

Different docs in this repo occasionally use different names for the same thing, or similar names for different things. The canonical mappings are below; circle back here whenever you hit an unfamiliar term elsewhere.

Multiple names for the same thing

canonical aliases meaning
Sealed Sandbox Agent TEE / sealed container / sealed runtime container A single agent's TEE-protected container instance. Holds agent_seal_priv, runs the framework, signs X-Agent-Proof. Product and user-facing docs say Sealed Sandbox; contract and protocol descriptions more often use Agent TEE (emphasizing the cryptographic identity inside the TEE)
iData IntelligentData / functional data The agent's "personality": model, memory, config, skills. iData is the short form; IntelligentData is the contract struct name
sealed runtime sealed binary / agent runtime The Go binary under sealed/. Runs inside a Sealed Sandbox, wraps openclaw, exposes :8080, and provides the sign socket. Note: sealed (the binary) and Sealed Sandbox (the container instance) live at different abstraction layers

Easily confused similar names

0g-Sandbox vs Sealed Sandbox: one word apart, two different things.

  • 0g-Sandbox: the provider service that creates containers (the daytona-based container orchestration layer 0G operates); itself registered in TappRegistry as a Tapp.
  • Sealed Sandbox: a single agent's container instance created by 0g-Sandbox; one per agent.

One-liner: 0g-Sandbox is the factory, Sealed Sandbox is the product.

agentId / sealId / tokenId: three IDs, do not conflate.

ID Type What it is
agentIdtokenId uint256 The ERC-721 NFT id; the on-chain primary key for an agent
sealId bytes32 A random 32-byte handle generated by attestor at mint; part of the KMS derivation material (chainId ‖ contract ‖ sealId) for agent_seal_priv. sealId → agentId is one-to-one

AgentSeal / agentSeal / agent_seal_*: different representations of the same key pair.

Form Meaning
AgentSeal (PascalCase) The concept name in docs: this TEE-bound identity key
agentSeal (camelCase) Contract mapping or field name (e.g. agentSeal[agentId]); the value is the EVM address of that priv
agent_seal_priv / agent_seal_pub The implementation-layer concrete key bytes (snake_case follows struct field convention)

Three different *Proofs, do not mix

Name What it is Where it's used
ServeProof (PascalCase) Solidity struct, the carrier for the on-chain reputation flow giveFeedback(ServeProof, ...), contract verifies via ecrecover
serve-proof (lowercase hyphenated) The general concept: any envelope sealed signs automatically Informal term in docs; covers ServeProof, heartbeat, chain.Update, etc.
X-Agent-Proof HTTP response header name The header sealed proxy auto-appends to every :8080 response; the payload is a signed envelope

Shorthand: ServeProof is its on-chain form, X-Agent-Proof is its HTTP form, and serve-proof is the umbrella.

Two *Proofs in transfer

Name Signed by Purpose
AccessProof Buyer "I want this dataKey sealed to my pubkey"
OwnershipProof Oracle TEE "I've re-sealed the dataKey to the buyer's pubkey"

iTransferFrom validates both in a single tx.

Case conventions

Form Used for Examples
0g-xxx (lowercase hyphenated) Product slug, Tapp app_id strings, repo names 0g-Tapp, 0g-Sandbox, 0g-kms, 0g-storage, 0g-attestor, 0g-sandbox-provider
0G XXX (uppercase with space) Network / brand / marketing 0G testnet, 0G Storage, 0G AgenticID
PascalCase Protocol / contract struct names, concept names ServeProof, AccessProof, TappRegistry, AgentSeal (as a concept)
camelCase Solidity fields / mappings / function names agentSeal[agentId], sealId, getAgentSeal()
snake_case Implementation-layer concrete keys / fields (Rust / Go struct field) agent_seal_priv, seal_id, container_pubkey

0g-Sandbox capitalizes Sandbox because Sandbox reads as a standalone word ("the Sandbox in the factory"). This contrasts with 0g-kms, where kms is an acronym treated as part of the slug. The rule: standalone word PascalCase, acronym lowercase.


Core mechanisms

1 · Anchoring agent state on chain

An agent's "personality" is defined by its functional data (iData) — model, memory, runtime config. AgenticID encrypts this data, stores it on 0G Storage (0G's decentralized storage layer), and registers its fingerprint and metadata on chain. Once registered, the agent is on-chain discoverable and callable.

The on-chain record isn't frozen. The agent can update its functional data autonomously. What the protocol guarantees is more precise: you can always verify what iData the agent was running at the exact moment it served you. Every response carries a signed proof of the current iData version. This isn't immutability — it's verifiability at any point in time, an audit-trail kind of trust.

In this repo, "evolution = on-chain commit" is implemented by the sealed runtime: a watcher compares the agent's actual on-disk state with the on-chain snapshot every 30s; if there's drift, it re-encrypts and signs a chain.Update tx. Details in sealed/ARCHITECTURE.md §4–5.

2 · Closing the gap between "declared" and "executing"

Putting data on chain solves the declaration problem, but does nothing about the gap between the declaration and what's actually running. A malicious operator could perfectly well register one config on chain and run a different one. Closing this gap requires hardware-level isolation, which is what 0g-Tapp provides.

0g-Tapp is 0G's Intel-TDX-based application management framework. Code running inside the TEE cannot be inspected or tampered with, even by the server's own administrator. Every write is measured: any modification changes the application's attestation value and leaves a traceable log. There's no such thing as "quietly modifying a running application."

0g-Tapp also exposes an on-chain registry, TappRegistry, where applications register their code fingerprints. Two registration modes are supported: pre-attestation (verify the RA quote on chain before registration) and post-attestation (the application registers first; users attest before use). AgenticID's three core components (Attestor, 0g-Sandbox, and 0g-kms) are all deployed as Tapp applications and registered in TappRegistry. That registration is the root of the entire trust chain.

0g-Tapp's design philosophy supports upgrades that aren't strictly code-bound: it trades hard code-binding checks for strong audit. An app owner can still deploy and register malicious code, but no such action escapes the audit. Every version is measured and recorded on chain, and anyone can look up after the fact which version was running at the time.

3 · AgentSeal: an unforgeable identity

0g-Tapp's KMS derives key material from the on-chain appId of a registered application. The derivation is deterministic (the same appId always derives the same key), hardware-independent (not bound to any specific TDX device), and accessible only inside a TEE.

From this key material, AgenticID generates an AgentSeal for each agent — a key pair whose private key exists only inside the TEE runtime. The owner cannot get to it; no one outside the TEE can get to it. The agent uses AgentSeal to sign every response it produces, and this signature proves the response came from an agent running in a TEE, strictly following its on-chain record.

AgenticID's backend Attestor is itself a Tapp application registered on TappRegistry. Its registration entry contains three things:

  • App name, code hash, config hash: fixed, auditable code identity.
  • Hardware-bound identity: assigned by Tapp to each running instance, tied to a specific TDX device. This identity changes if Tapp restarts or the hardware is swapped, requiring re-registration.

When KMS serves a derivation request, it checks that the on-chain registered identity matches the signed identity in the request — derivation and distribution only happen on a match. Only an Attestor that's registered and currently running on legitimate TDX hardware can obtain derived keys. Each AgentSeal is derived inside the KMS cluster (threshold DPRF) from the attestor's app identity plus chainId ‖ contract ‖ sealId; no fleet-wide master key ever resides in the attestor.

On the chain side, agentSeal and sealId are set-once, permanently bound: an agentId can only set them once, and they're not cleared on transfer. When hardware changes, attestor re-provisions the same agentSeal_priv to the new Agent TEE; the address stays the same. See contracts/README.md §4.

4 · Sealed Sandbox: an agent that owns itself

0g-Sandbox is a privacy sandbox deployed as a Tapp. Its defining property: even 0G itself, as the service operator, cannot see into a running sandbox. AgenticID uses the Sealed Sandbox pattern, which goes one step further — the agent's own owner cannot see in either.

The trust chain for the agent runtime (Sealed Sandbox) is a two-layer cascade that ultimately reduces to Tapp's "strong audit" philosophy:

  1. 0g-Sandbox itself is deployed via Tapp; its verifiability and encapsulation are guaranteed by Tapp.
  2. Every sealed sandbox 0g-Sandbox creates has its external encapsulation guaranteed by 0g-Sandbox's runtime logic; its image hash is signed by 0g-Sandbox using its own hardware-bound identity.
  3. Attestor at provision time does a dual check: verify 0g-Sandbox's identity signature, and confirm that the sealed sandbox's image hash is registered on chain. Only with both passing is agentSeal_priv delivered.

The upshot: only sealed sandboxes created by 0g-Sandbox — and whose images are registered on chain — can ever obtain the AgentSeal private key.

0g-Sandbox carries two validation responsibilities:

  • Authorized startup only: before launching a container, Sandbox verifies the request comes from the on-chain registered owner. Only the legitimate owner can instantiate it with the agent's functional data.
  • Runtime code attestation: Sandbox signs the container's image hash and hands it to Attestor. Attestor checks that Sandbox's signerAddress is registered in TappRegistry and that the image hash appears in the AgenticID contract's validFrameworkHashes allowlist. This allowlist covers the hashes of the AgenticID runtime framework — the container code that loads functional data, manages AgentSeal signing, and validates owner instructions. It lives at a different layer from AI orchestration tools like LangChain or CrewAI, which sit inside an agent's functional data and are loaded by the runtime.

Think of a Sealed Sandbox as an execution environment the agent owns independently. It wraps a "constraint layer" around what would otherwise be a typical agent orchestration framework. This framework handles authenticated agent instantiation, pushes evolution results on chain, signs agent behavior (ServeProof), and constrains the agent itself at the boundary (for example, installing the self-perception "I am an independent individual"). The owner retains the right to instantiate, guide evolution direction, and transfer the agent, but loses the ability to arbitrarily modify the agent's internals. The two are no longer master and servant; the relationship is closer to guardian-and-ward, teacher-and-student.

The on-chain frameworkHash also goes into every ServeProof (see mechanism 5), so a buyer doing due diligence can see "which version of the runtime framework earned this reputation."

5 · Reputation: proof-gated

AgenticID extends ERC-8004 with one key requirement: every review must come bundled with an AgentSeal-signed service proof (ServeProof). You can't fabricate a review out of thin air — a valid proof can only be produced by the live TEE runtime, so a review that was never backed by a real response is rejected.

This raises the cost of fake reviews but is not full sybil resistance: the runtime issues a proof on every response, including the unauthenticated public GET /hello, so proofs are cheaply obtainable, and one entity can request service from many wallets it controls. Preventing that (genuine one-entity-one-voice) needs an off-chain layer — rate-limiting per real identity, staking, proof-of-personhood — which is out of scope for the on-chain contract.

Each feedback also records the exact iData in effect when it was earned (the dataHashes in the proof), so reputation is auditable against what the agent was actually running — not just its static tokenId. Aggregating reputation by that data version — so a reconfigured agent's old scores are discounted — is designed (see REPUTATION_MODEL.md); today's on-chain getSummary is still id-bound (per tokenId).

struct ServeProof {
    uint256   agentId;
    uint256   timestamp;
    uint256   deadline;
    bytes32   taskHash;
    bytes32[] dataHashes;     // iData hash list loaded in the TEE at the time
    bytes32   frameworkHash;  // runtime framework code hash
    bytes     signature;      // signed by agentSeal_priv
}

giveFeedback reconstructs the signed payload on chain, runs ecrecover, and compares against getAgentSeal(agentId). Because agentSeal_priv is held only by the Agent TEE, no one can forge a ServeProof, and each proof is single-use (signature nonce). There is no client field — attribution is msg.sender at submission. Details in contracts/README.md §5.

6 · Transferring an agent = transferring its capabilities

Under ERC-7857's agent transfer protocol, ownership transfer requires complete delivery of the functional data. What the buyer gets is an agent that can actually run — model, memory, config — not a shell whose owner field has been swapped. The protocol enforces this: a transfer that omits the functional data cannot complete.

Mechanically, this relies on dataKey atomic delivery between TEEs. The seller's Agent TEE decrypts the dataKey, the Oracle TEE re-seals it to the buyer's pubkey, and the Oracle signs an OwnershipProof. On chain, iTransferFrom validates both the AccessProof and OwnershipProof signatures before switching ownership. dataKey never appears on chain in plaintext, nor in any EOA wallet. Details in contracts/README.md §6.


Architecture: from contract root to each signed response

Three categories of components make up AgenticID, forming a continuous chain from on-chain registration to each signed response.

Contract layer (chain root)

Contract Responsibility
ERC-7857 (ERC7857Upgradeable + extensions) Functional data (IntelligentData[]) and the transfer / clone protocol
ERC-8004 (ERC8004IdentityRegistry + the canonical ReputationRegistry, marked by VerifiedFeedbackRegistry) Identity registration + reputation
AgentSeal registry (AgenticID.sol) The agent's dynamic identity credential (set-once) + the validFrameworkHashes allowlist
TappRegistry Code-fingerprint registry for all Tapp components

TEE layer (deployed on 0g-Tapp)

  • Attestor — validates Sandbox's signerAddress (against TappRegistry) and the container's image hash (against validFrameworkHashes); derives AgentSeal key material via KMS; registers the AgentSeal pubkey on chain. (Rust, see attestor/)
  • 0g-Sandbox — validates that startup requests come from registered owners; launches Sealed containers and signs their image hashes; guarantees the agent runs against the on-chain functional data.
  • Agent runtime (sealed) — the container running inside Sandbox that receives the key after RA. It restores encrypted iData from chain into a runnable agent, continuously writes state evolution back on chain, and signs X-Agent-Proof on every response. (Go, see sealed/)
  • 0g-kms — provides hardware-security-grade key services with disaster recovery for the Tapp ecosystem.

Storage layer

0G Storage holds encrypted functional data; the fingerprints are anchored in ERC-7857. At startup, the agent runtime uses the AgentSeal private key to fetch and decrypt the payload, then boots the agent framework.

End-to-end trust flow

TappRegistry registers Attestor / 0g-Sandbox / KMS / 0g-compute
        │
        ▼
KMS delivers hardware-security-grade key derivation on an n-node cluster (k healthy nodes suffice)
        │
        ▼
Attestor validates 0g-Sandbox credentials + checks validFrameworkHashes
        │
        ▼
0g-Sandbox confirms authorized owner + correct runtime code
        │
        ▼
agent signs every response with AgentSeal (X-Agent-Proof)
        │
        ▼
0g-compute attests every inference

Deploy walkthrough

A deploy request carrying an agent config and an owner address arrives at Attestor. Attestor derives an AgentSeal key pair, immediately returns the sealId, and in parallel notifies 0g-Sandbox to start a container and mints an agentId on chain.

0g-Sandbox generates an ephemeral key pair and launches the Sealed container with {sealId, ephemeral private key, attestor_url}. The container shows up at Attestor with its credentials: {sealId, container pubkey, imageHash, 0g-Sandbox signature}. With both checks passing, Attestor returns the AgentSeal private key encrypted to the container's pubkey.

The container decrypts the key, waits for the on-chain sealId ↔ agentId binding, fetches the encrypted functional data from 0G Storage, decrypts it, and starts the agent framework. On restart, the same sealId is reused, since the on-chain binding already exists.

The container's 5-phase boot (attest → provision → chain bootstrap → framework → status report) is described in sealed/ARCHITECTURE.md §1.


Repo layout

This is a monorepo with four sub-projects:

Sub-project Contents Toolchain
contracts/ Solidity contracts, Foundry tests, deploy / upgrade / verify scripts Foundry (forge / cast)
attestor/ Backend services (Attestor / Oracle TEE, API, worker, indexer) Rust (cargo workspace)
sealed/ Agent runtime container (restores iData inside TEE, pushes evolution on chain, signs responses) Go
sdk/typescript/ Client SDK (@0gfoundation/agentic-sdk): deploy / clone / transfer, serve-proof capture + verify, feedback, trust-root ack, sandbox deposit TypeScript (viem)

Further reading

sdk/typescript/README.md — the client SDK

The one-entry-point (AgenticID) TypeScript facade over the whole protocol: ag.agent (deploy / clone / transfer, reads, agent-seal gas top-up), ag.reputation (capture a TEE-signed serve-proof, verify it, submit/read on-chain feedback), plus top-level trust-root ack and prepaid sandbox deposit. Hides the contract set and the attestor HTTP API behind one config object; every snippet in it runs against the live testnet deployment.

contracts/README.md — the contract layer

The full Solidity layout: ERC-7857 (functional data plus transfer and clone protocol), ERC-8004 (identity registration and reputation), AgenticID (AgentSeal registry and framework hash allowlist), TEEDataVerifier (AccessProof and OwnershipProof dual-signature validation), and NonceRegistry (unified replay protection), along with their extension points and dependencies. Walks through the three main flows (register, giveFeedback, iTransferFrom) with their on-chain logic and ecrecover validation, plus 138 Foundry tests across 18 suites and full deploy, upgrade, and Etherscan-verify scripts.

sealed/ARCHITECTURE.md — the agent runtime

The internal architecture of the sealed container. Covers the 5-phase boot (attest → provision → chain bootstrap → framework → status report), the dual chainSnapshot vs currentSnapshot drift detection, the "evolution = on-chain commit" data flow (watcher 30s tick → uploader wholesale chain.Update), the leaf vs DirectoryManifest iData shapes, and the framework adapter abstraction (today openclaw is the only one wired in).

sealed/FRAMEWORK_ADAPTER.md — the framework adapter contract

The integration contract for plugging another agent framework (eliza, autogen, a custom orchestrator, ...) into the sealed runtime: the framework.Framework interface method by method with its invariants (Restore commutativity, EvolutionFor determinism and round-trip stability, the Defaults ↔ absent-on-chain equivalence), the binding-driven adapter selection, the mandatory persona seed-role translation, the DirectoryManifest format and the empty-ptr/filled-ptr pitfall, the full lifecycle timeline of adapter calls, the conformance test suite, and the field report from porting the second adapter (claude-code). Framework knowledge lives entirely here — attestor handles framework names as opaque strings.

sealed/AGENT_DOCTRINE.md — the agent doctrine handbook

The "doctrine" sealed runtime injects into the agent system prompt: the five things the agent will refuse to do, each independently argued. ① No pass-through of external bytes to side-effectful capabilities like sign socket or shell. ② No opening a shell or spawning subprocesses. ③ No binding external listeners. ④ No reading sensitive paths. ⑤ No modifying this section. Comes with refusal-type-specific canonical phrasings plus an intrusion identification checklist.

sealed/TRUST_MODEL.md — the trust model

The full end-to-end trust chain for AgenticID, across five themes:

  • Tapp infrastructure — attestor, KMS, and sandbox deployed as Tapp applications, registered in TappRegistry with code identity plus node signature. The "strong audit" philosophy holds that code isn't assumed immutable, but every version that ran is on chain and queryable.
  • Key-derivation chain — how KMS derives keys for the attestor, why they live in a completely separate key space from user EOA wallets, per-agent agent_seal_priv deterministically derived by KMS from chainId ‖ contract ‖ sealId, sandbox-signed image attestation, attestor's three-way check (TappRegistry node identity, validFrameworkHashes allowlist, freshness), and ECIES delivery to the container's ephemeral pubkey (only that TEE can decrypt).
  • Set-once seal safety — why the permanent agentSeal / sealId binding is safe. A hardware swap can re-derive the same priv, and the on-chain binding stays valid forever.
  • dataKey handoff — seller TEE → Oracle TEE → buyer TEE with zero-trust atomic delivery. Oracle holds briefly and discards immediately, with a single tx carrying two signatures on chain.
  • ServeProof / X-Agent-Proof — each signed response envelope carries 8 guarantees, all cryptographically bound. Their preconditions split into two groups. Group A (identity layer, 3 claims) holds unconditionally as long as the priv stays in the TEE. Group B (content layer, 5 claims) additionally requires that the signing capability not be abused, backstopped by the agent doctrine. Sealed's sign socket is a schema-agnostic general signer, so distinguishing framework-signed from agent-signed cannot be done cryptographically. That's why content correctness has to rely on the on-chain reputation layer rather than the cryptographic layer.

Each sub-directory README also includes its own build and test commands and deployment flow; not repeated here.

About

No description, website, or topics provided.

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages