Skip to content

did:agent: Method Specification

Version: 0.1.0 Status: Draft

This document specifies the did:agent: DID method per W3C DID Core v1.0. The method provides self-sovereign, locally-resolvable identifiers for AI agents using Ed25519 public keys.

1. Method Name

The method name is agent. A DID using this method MUST begin with the prefix did:agent:.

2. Method-Specific Identifier

2.1 Syntax

did-agent = "did:agent:" agent-id
agent-id  = 32HEXDIG
HEXDIG    = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" /
            "8" / "9" / "a" / "b" / "c" / "d" / "e" / "f"

The agent-id is exactly 32 lowercase hexadecimal characters (128 bits).

2.2 Derivation

The agent-id is derived from an Ed25519 public key as follows:

  1. Let public_key_bytes be the 32-byte Ed25519 public key (RFC 8032).
  2. Compute hash = SHA-256(public_key_bytes).
  3. Take the first 16 bytes of hash: truncated = hash[0..16].
  4. Encode truncated as lowercase hexadecimal: agent_id = hex_lower(truncated).

The resulting DID is did:agent: concatenated with the 32-character hex string.

2.3 Example

Public key (hex):  d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
SHA-256 of key:    21fe31dfa154a261626bf854046fd227f1b0c36f3b0c51de0b0cd8e4b7e96f80
Truncated (16 B):  21fe31dfa154a261626bf854046fd227
DID:               did:agent:21fe31dfa154a261626bf854046fd227

2.4 Collision Resistance

The 128-bit truncation provides:

  • Second preimage resistance: ~2^128 operations to find a key matching a target DID.
  • Birthday-bound collision resistance: ~2^64 identities before a collision is expected.

For practical agent populations (well below 2^40), this provides adequate security margins.

3. DID Operations

3.1 Create

Generate a new Ed25519 keypair using a cryptographically secure random number generator. Derive the DID from the public key per Section 2.2. No external registration is required. The DID exists the moment the key is generated.

Implementations MUST support:

generate() -> (AgentKeyPair)
keypair.identity() -> AgentIdentity { did, public_key_bytes }

3.2 Read (Resolve)

Given a did:agent: identifier, resolution constructs a DID Document from the public key. Resolution is entirely local - there is no network resolver.

Prerequisite: The resolver MUST already possess the public key bytes for the DID. The public key is obtained through:

  • The issuer_public_key field embedded in a Delegation
  • The invoker_public_key field in an McpProof
  • A prior key exchange or configuration

Resolution algorithm:

  1. Verify the DID prefix is did:agent:.
  2. Verify the method-specific identifier is exactly 32 lowercase hex characters.
  3. Recompute expected_did = "did:agent:" + hex_lower(SHA-256(public_key_bytes)[0..16]).
  4. Verify expected_did == input_did. If not, resolution fails.
  5. Construct the DID Document per Section 4.

3.3 Update

DID Documents are derived deterministically from the public key and optional parameters (service endpoints, creation timestamp). To update a DID Document, update these parameters and re-derive.

The DID itself cannot change because it is bound to the public key. Key rotation requires creating a new DID.

3.4 Deactivate

A did:agent: identifier is deactivated by destroying the corresponding private key. There is no on-chain or network deactivation signal.

For delegation-based systems, revoke delegations via the is_revoked callback without deactivating the identity itself.

4. DID Document

4.1 Structure

Implementations MUST produce a DID Document conforming to this structure:

json
{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "did:agent:21fe31dfa154a261626bf854046fd227",
  "verificationMethod": [{
    "id": "did:agent:21fe31dfa154a261626bf854046fd227#key-1",
    "type": "Ed25519VerificationKey2020",
    "controller": "did:agent:21fe31dfa154a261626bf854046fd227",
    "publicKeyMultibase": "z6Mkf5rGMoatrSj1f4CyvuHBeXJELe9RPdzo2PKGNCKVtZxP"
  }],
  "authentication": [
    "did:agent:21fe31dfa154a261626bf854046fd227#key-1"
  ],
  "assertionMethod": [
    "did:agent:21fe31dfa154a261626bf854046fd227#key-1"
  ]
}

4.2 Verification Method

Each DID Document contains exactly one verification method:

FieldValue
id{did}#key-1
typeEd25519VerificationKey2020
controllerThe DID itself
publicKeyMultibaseMultibase-encoded public key (see Section 4.3)

If the key creation timestamp is known, the verification method SHOULD include a created field with the RFC 3339 timestamp.

4.3 Public Key Encoding

The public key is encoded using the Multibase and Multicodec standards:

  1. Prepend the Ed25519 public key multicodec prefix: 0xed 0x01.
  2. Concatenate with the 32-byte public key: [0xed, 0x01] + public_key_bytes.
  3. Encode the 34-byte result as Base58btc.
  4. Prepend the multibase prefix z (indicating Base58btc).

Decoding:

  1. Verify the string starts with z.
  2. Base58btc-decode the remainder.
  3. Verify the result is 34 bytes with prefix [0xed, 0x01].
  4. The remaining 32 bytes are the Ed25519 public key.

4.4 Verification Relationships

The DID Document declares the key for two verification relationships:

  • authentication - The key can prove the agent's identity (e.g., in challenge-response protocols).
  • assertionMethod - The key can create verifiable assertions (e.g., signed messages, provenance entries).

Both reference the same key via {did}#key-1.

4.5 Service Endpoints (Optional)

DID Documents MAY include service endpoints describing how to communicate with the agent:

json
{
  "service": [{
    "id": "did:agent:21fe31dfa154a261626bf854046fd227#messaging",
    "type": "AgentMessaging",
    "serviceEndpoint": "https://example.com/agent/msg"
  }, {
    "id": "did:agent:21fe31dfa154a261626bf854046fd227#resolve",
    "type": "KanonivResolve",
    "serviceEndpoint": "https://api.kanoniv.com/v1/resolve"
  }]
}

Service endpoint IDs that start with # are automatically prefixed with the DID. Full URIs are used as-is.

5. Security Considerations

  • No key rotation. The DID is permanently bound to the public key. Key compromise means identity compromise. Agents SHOULD enforce key freshness policies using the created_at timestamp.
  • No global state. There is no ledger or registry. DID resolution requires the public key to be available locally. This is a privacy advantage (no phone-home) but means the resolver must obtain the key through other channels.
  • Correlation. A did:agent: identifier is a persistent pseudonym. The same DID observed across interactions can be correlated. Agents requiring unlinkability SHOULD generate a new keypair per interaction context.

6. Privacy Considerations

  • DID resolution is entirely local. No network call reveals when a DID is used.
  • The DID is derived from a hash of the public key, not the key itself. However, the DID Document and signed messages expose the full public key.
  • Delegation chains reveal the authority structure (who delegated to whom). This is intentional for auditability but may expose organizational relationships.

7. Interoperability

7.1 Test Vector

Implementations MUST produce identical output for this test vector:

Secret key (hex): 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
Public key (hex): d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
DID:              did:agent:21fe31dfa154a261626bf854046fd227

7.2 Cross-Language Requirements

All implementations MUST:

  1. Derive the same DID from the same public key bytes.
  2. Produce DID Documents with identical structure (modulo service endpoints and created timestamp).
  3. Decode publicKeyMultibase values produced by any other implementation.

The identity and delegation layer for AI agents.