Identity, Delegation & Proofs
Why Checkpoint uses DIDs instead of API keys, and why identity alone grants nothing
The Govern pillar is built on three primitives — DIDs, delegations, and proofs — that together answer the question a bot blocker can't: not "is this a bot?" but "what is this agent allowed to do, on whose behalf, and who is accountable?" This page explains why each primitive exists and how they differ from the authentication you already know.
Why DIDs instead of API keys
An API key is a shared secret. The server stores a copy, every hop in the request path can see it, leaking it is total compromise, and it means nothing outside the service that issued it. Scaling API keys to a world of autonomous agents means distributing, rotating, and revoking secrets across systems you don't control.
A DID (Decentralized Identifier) inverts the model:
- The agent generates its own keypair locally (Ed25519). The identifier is derived from the public key (
did:key) or anchored to a domain the agent's operator controls (did:web). - Verification means proving possession of the private key — by signing something — rather than presenting a secret. The private key never travels.
- The identity is portable: any verifier that can resolve the DID can check a signature. There is no issuing service the identity is locked to.
- Verification works offline: resolving a DID document and checking an Ed25519 signature requires no callback to a central authority.
The KYA-OS specification requires agents to generate their own keys. Registries and verifiers only ever receive public keys — an implementation that generates or holds an agent's private key on its behalf is non-conformant. There is no central store of agent secrets to breach.
Choosing a DID method
| Method | Anchored to | Best for | Key rotation |
|---|---|---|---|
did:key | The public key itself | Development, ephemeral agents | Not possible — a new key is a new DID |
did:web | A domain (/.well-known/did.json) | Production, organizational identity | Update the DID document with a new key |
Identity is not permission
Here is the deliberate design decision that makes Govern different from OAuth-style client registration: being a recognized agent grants nothing. An agent can have a valid DID, a verified profile, and a good reputation — and still be denied everything, because identity and authorization are separate layers.
Authority comes from a delegation: a signed grant from a user or organization to a specific agent, expressed as a W3C Verifiable Credential. A delegation names:
- Who — the agent's DID
- What — explicit scopes in
{resource}:{action}form (e.g.files:read,payment:create). Scopes match exactly; there is no implicit hierarchy wherefiles:readimplies anything else. - How long — an expiry, plus optional constraints such as allowed origins, IP restrictions, time windows, and usage limits.
Compare this to OAuth as most teams deploy it: registering a client is the hard part, and a registered client then holds broad, long-lived tokens. KYA-OS flips the weight — recognition is easy, but every meaningful action requires a delegation that names the specific resource. The result is least-privilege by default for agents.
Delegation chains
Delegations can chain: a user delegates to an agent, which sub-delegates to a helper agent. Two rules keep chains safe:
- Attenuation only. A sub-delegation's scopes must be a subset of its parent's. Authority can narrow down a chain; it can never widen.
- Revocation cascades. Revoking any link invalidates everything downstream of it. Rights and accountability trace back to the chain's root — the party ultimately responsible for the agent's actions.
See Delegations for the lifecycle and API.
Proofs: exercising a delegation
A delegation is the durable grant; a proof is how an agent exercises it on a single request. A proof is a short-lived signed assertion (JWS, Ed25519) that carries the agent's DID, a reference to the delegation and scope being used, a unique nonce, and a tight validity window — typically five minutes.
The distinction matters because it is what makes stolen credentials nearly useless: possessing a delegation credential isn't enough to act on it. Each request must be freshly signed with the agent's private key, and each proof can only be used once.
A useful mnemonic for the three primitives:
Delegation = the permission. Credential = the signed document embodying it. Proof = showing up with the document and your key.
See Proofs for the payload format and verification error codes.
Consent: where delegations come from
Delegations aren't minted by fiat — they come from a consent step: a hosted page where a human reviews exactly which scopes an agent is requesting and approves or denies them. The approval produces the durable delegation record that enforcement checks from then on, and that the user (or their organization) can revoke at any time.
This is the piece that turns agent governance into something you can show an auditor: every agent action traces to a delegation, and every delegation traces to an explicit human grant. See Consent.
How this shows up in policies
Identity facts flow directly into Cedar policies as first-class conditions:
@id("block-unverified-agents")
@verdict("BLOCK")
forbid ( principal, action, resource )
when { principal.category == "ai_agent" }
unless { principal.delegation == "verified" };Unknown agents are blocked; agents that present a valid delegation pass. Add context.granted_scopes.contains("...") to gate specific routes on specific consented scopes. This single pattern — forbid the category, exempt verified delegations — is how most teams join the Enforce and Govern pillars.