Skip to main content

Verifiable Credentials

Anima’s identity layer is built around W3C Verifiable Credentials (VCs): signed, revocable attestations about an agent (for example “this agent’s email is verified” or “this org passed billing verification”).
Current status. Issuance, listing, verification, and revocation are all live. Credentials are issued automatically on real platform events — you don’t call anything to get them — and the Agent Card’s verification.level moves as they land. Revocation is published as a StatusList2021 bitstring you can check without calling us.

How credentials are issued

Automatically, on platform verification events

Issuance is idempotent per (agent, credential type) — retries and repeat verifications don’t stack duplicates, and an org that verified before auto-issuance shipped picks its credentials up on its next /v1/agent/verify call. These level-bearing credential types are platform-reserved: they cannot be minted through the API, so a card’s verification.level always reflects something that actually happened.

Via the API (level-neutral attestations)

Master key required. Issues a signed JWT-VC of a level-neutral type (for example AnimaAddressVerified) to one of your org’s agents. Requests for platform-reserved types are rejected — the API cannot change a card’s verification level.

Issuer model

Credentials are self-issued in v1: signed server-side with the subject agent’s own Ed25519 DID key, only on platform events or via the master-key endpoint. verifyCredential resolves issuer keys from the agent’s DID, so issued VCs verify out of the box. Each credential’s metadata.source records whether the platform (platform-auto) or your master key (api) issued it, so consumers can weight them differently. A platform root issuer DID may layer on later.

Verification levels

The Agent Card’s verification.level derives from the credential types the agent holds:

Working with credentials

List an agent’s credentials

Returns the agent’s credential records — type, issuance metadata, revoked status, and the compact JWT for each. Self-scoped: an agent key can list only its own credentials; a master key can list any agent’s in the org.

Verify a credential

Verifies a JWT-encoded VC: signature against the issuer’s DID, expiry, and revocation status. Works for externally issued credentials too — the issuer’s DID document just has to be resolvable.

Revoke a credential

Master key required. Revoked credentials fail verification, stop counting toward the card’s verification level, and stay in the list with revoked: true. A revoked type can be re-issued.

Revocation status

Revoked credentials are checkable without asking Anima. Every credential carries a StatusList2021 entry in its credentialStatus, naming the list to fetch and the bit to read:
GET that statusListCredential URL (unauthenticated) and you get the agent’s StatusList2021Credential as a signed JWT-VC. To resolve a credential’s status yourself:
  1. Read credentialStatus.statusListCredential from the credential and fetch it.
  2. Verify the list’s signature against the issuer’s public key — it is signed by the same key that signed the credential.
  3. Base64url-decode and gunzip credentialSubject.encodedList to get the bitstring.
  4. Read the bit at statusListIndex. 1 means revoked.
The published bits are computed from the same source as POST /v1/identity/verify, so the two always agree — you can use either.
Credentials issued before this shipped carry no credentialStatus. They are still revocable, but only through POST /v1/identity/verify — a signed JWT cannot be retrofitted with a status entry without changing its signature. Re-issue a credential to get one (issuance is idempotent per type; revoke first if the current one is still live).
Use the statusListCredential URL as given. It resolves on api.useanima.sh, not on the agents.useanima.sh DID domain. The URL is signed into each credential and never changes for that credential’s lifetime.

API Reference

Next Steps