Delegate a sub-DID (parent to child)

Offline-testable today

A parent DID can authorise a restricted-scope sub-DID for a purpose, a resource set and a validity period, and bind an AI agent to it. You can rehearse the whole flow offline today; on-chain binding, revocation and quota need stage B and the window parameters.

Journey statusOffline-testable today

Steps

  1. 1What a sub-DID is: a restricted-scope grant, not a separate key

    Works today

    A sub-DID is a did:msg whose document has controller: [<parent DID>] and an AididDelegation service entry carrying the grant payload: purpose, resource scope, expiry, bound agent and status.

    In stage A the child document reuses the parent's Dilithium-5 key material: its verification method points at the parent public key. So this is a hand-off of restricted permissions, not a hand-off of keys. Never describe it as giving an agent its own production key.

    The own-key mode, where the parent signs over the agent's own Dilithium-5 public key, exists at the protocol level and is verifiable offline, but it is fail-closed by default and has no on-chain binding or revocation.

  2. 2Create it locally and run the offline demo

    Offline-testable today

    The offline demo in the RP SDK (examples/node/offline-demo.mjs, section 6) walks the whole flow with real Dilithium-5 signatures and no network: create a sub-DID, have the parent sign the delegation, sign in as the sub-DID (all 11 login checks pass), let the delegation gate allow it, have an out-of-scope resource refused, verify the audit receipt, and finally revoke and watch the identity still verify while the login is refused with delegation_revoked.

    Install the published SDK and run the same demo from the tarball if you do not have the repository.

  3. 3Verify a sub-DID on the RP side (step 12, fail-closed)

    Offline-testable today

    RP verification reuses the 11 login checks and adds step 12: read the delegation entries from the resolved child document (no entry means reject with delegation_not_found), then evaluate the payload for scope, expiry and expected parent.

    The SDK ships verifyDelegation and createDelegationVerifier. It never throws and never downgrades to allow. It needs one of two trust sources: the on-chain child document, or the parent's signature over the canonical delegation text. For own-key payloads it rejects unless the caller explicitly opts in with allowOwnKey: true, because there is no revocation channel offline.

    It does not count quota or run a deny-list. scope.maxUsesPerDay is declared metadata only, so counting, rate limiting and deny-lists are the RP's own responsibility.

  4. 4What is still blocked: on-chain binding, revocation and quota

    Not available today

    There is no on-chain authoritative binding of a sub-DID to an agent, no revocation primitive (the chain's deactivate is irreversible and there is no blacklist), and no enforced quota. Those need stage B, our identity contract, which is written but not deployed until the window parameters are released. Stage A writes the grant into the child DID document through the chain's own registry contract, and that write is blocked today too.

    Until then, treat every sub-DID grant as a local arrangement that can only be revoked by updating the document, and keep the honest wording: restricted-scope authorisation, not an independent production key.

    Why this is blocked today

    • chainWrite Chain write paths (and the stage-B identity contract) await the chain-side window parameters. Mainnet is No-Go and no contract is deployed.
    • independentAgentKey The protocol-level offline self-held key (the parent DID binds the agent's own Dilithium-5 public key with its own signature) is implemented and off by default — verifyDelegation is fail-closed unless the caller opts in with allowOwnKey. There is NO on-chain binding, NO revocation and NO quota, so production availability awaits stage B / the window parameters.

    Reason taken from status.json#capabilities — not written by hand for this page.