FR EN

DID documents

A verifier resolves two DID documents to check a receipt: the company document for companySig, and the citizen document for the WebAuthn assertion. They use different DID methods and expose keys differently.

The company DID document

Resolved from did:web:agreely.ca:c:{slug} at https://agreely.ca/c/{slug}/did.json. It resolves only when the company has a verified domain and an active signing key.

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/data-integrity/v2"
  ],
  "id": "did:web:agreely.ca:c:acme",
  "alsoKnownAs": ["did:web:acme.com"],
  "verificationMethod": [
    {
      "id": "did:web:agreely.ca:c:acme#kms-1",
      "type": "Multikey",
      "controller": "did:web:agreely.ca:c:acme",
      "publicKeyMultibase": "z6Mk...base58btc..."
    }
  ],
  "assertionMethod": ["did:web:agreely.ca:c:acme#kms-1"],
  "authentication": ["did:web:agreely.ca:c:acme#kms-1"]
}
Field Meaning
id The Agreely-hosted company DID.
alsoKnownAs The company's verified real domain DID, the binding that proves the Agreely-hosted id belongs to the real organization.
verificationMethod[].type Multikey.
verificationMethod[].publicKeyMultibase The Ed25519 public key as z-prefixed base58btc of `(ed25519-pub multicodec 0xed01
assertionMethod / authentication Reference the signing key fragment.

The citizen DID document

Resolved from did:agreely:citizen:.... It is public, unauthenticated, and tenant-less by design (any verifier may resolve it). It is assembled from the full key history, so every key the DID ever held appears with its authority window.

{
  "@context": [
    "https://www.w3.org/ns/did/v1",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
  "id": "did:agreely:citizen:9F8K2M4P7Q1R3T5V8W0X2Y4Z6B",
  "verificationMethod": [
    {
      "id": "did:agreely:citizen:9F8K2M4P7Q1R3T5V8W0X2Y4Z6B#passkey-1",
      "controller": "did:agreely:citizen:9F8K2M4P7Q1R3T5V8W0X2Y4Z6B",
      "validFrom": "2026-01-10T14:00:00Z",
      "validUntil": null,
      "type": "WebAuthnAuthenticationKey2024",
      "publicKeyCose": "0xa5010203262001..."
    },
    {
      "id": "did:agreely:citizen:9F8K2M4P7Q1R3T5V8W0X2Y4Z6B#recovery-1",
      "controller": "did:agreely:citizen:9F8K2M4P7Q1R3T5V8W0X2Y4Z6B",
      "validFrom": "2026-01-10T14:00:00Z",
      "validUntil": null,
      "type": "Ed25519VerificationKey2020",
      "publicKeyMultibase": "z6Mk...base58btc..."
    }
  ],
  "authentication": [
    "did:agreely:citizen:9F8K2M4P7Q1R3T5V8W0X2Y4Z6B#passkey-1"
  ],
  "capabilityInvocation": [
    "did:agreely:citizen:9F8K2M4P7Q1R3T5V8W0X2Y4Z6B#recovery-1"
  ]
}
Field Meaning
validFrom / validUntil The key's authority window. validUntil is present even when null so a verifier distinguishes "still valid" from "expired at T". A receipt signed at time T resolves to whichever key was authoritative at T.
WebAuthnAuthenticationKey2024 A passkey. Its publicKeyCose is the COSE-encoded public key as 0x-hex; verify the receipt's WebAuthn assertion against it.
Ed25519VerificationKey2020 A recovery key, exposed as publicKeyMultibase.
authentication Passkey fragments (authorized to sign consent).
capabilityInvocation Recovery-key fragments, authorized solely for DID rotation, never for signing consent.

The window is what keeps old receipts valid

When you verify proof[1] of a receipt, take its verificationMethod fragment, find that method in the citizen document, and confirm its [validFrom, validUntil] window contains the receipt's grantedAt. Then verify the assertion against that method's COSE key. A rotated-out key still verifies its historical receipts.

Next