Attestations¶
An attestation is a signed JSON document that binds a device to an identity.
You don't need to care about this unless...
You're building a verifier, debugging a failed verification, or designing a custom integration. For day-to-day commit signing, auths device link and auths verify-commit handle attestations for you. This page is for when you need to understand what's happening under the hood.
Structure¶
{
"version": 1,
"rid": "unique-request-id",
"issuer": "did:keri:EBf...",
"subject": "did:key:z6Mk...",
"device_public_key": "aabbccdd...",
"identity_signature": "1122334455...",
"device_signature": "6677889900...",
"capabilities": ["sign-commit"],
"expires_at": "2025-06-01T00:00:00Z",
"revoked": false,
"note": "Laptop key"
}
Key fields¶
| Field | Description |
|---|---|
issuer |
The identity DID (did:keri:E...) that authorized this device |
subject |
The device DID (did:key:z6Mk...) being authorized |
device_public_key |
Raw Ed25519 public key of the device (hex) |
identity_signature |
Signature by the identity key over the canonical payload |
device_signature |
Signature by the device key over the same canonical payload |
capabilities |
What the device is allowed to do |
expires_at |
Optional expiration timestamp |
revoked |
Whether this attestation has been revoked |
Dual signing¶
Both the identity and the device sign the attestation. This creates a two-way binding:
- The identity signature proves: "I authorize this device"
- The device signature proves: "I acknowledge this link"
The signed payload is a canonical JSON representation of the attestation data (excluding the signatures themselves), produced by json-canon for deterministic serialization.
What's signed vs. what's not¶
Signed (included in the canonical payload):
- version, rid, issuer, subject
- device_public_key
- capabilities, expires_at
- note, revoked
Not signed (computed, not part of payload):
- identity_signature
- device_signature
Storage¶
Attestations are stored as Git refs:
Each attestation is a JSON blob committed to the device's ref. The commit history of the ref records the attestation lifecycle (link, extend, revoke).
Verification¶
To verify an attestation, you need:
- The attestation JSON
- The issuer's public key (32 bytes, Ed25519)
The verifier:
- Checks the
revokedflag - Checks
expires_atagainst current time - Reconstructs the canonical payload
- Verifies
identity_signatureagainst the issuer's public key - Verifies
device_signatureagainst thedevice_public_keyin the attestation
If all checks pass, the attestation is valid.
Chain verification¶
For multi-level delegation (identity -> device -> sub-device), attestations form a chain. verify_chain() walks the chain from root to leaf, verifying each link and ensuring the subject of one attestation matches the issuer of the next.