Skip to content

Give an agent an identity

An agent’s identity starts with a domain and a keypair, and is finalized by a published and verified identity record. The domain is one you own: you operate its DNS, TLS, and JWKS, and you sign and publish the record. This is the self-managed model, and it is the accountability model the protocol is built around—your domain vouches for your agent.

Most developers prove out the flow first on DNSid Local, where a disposable local network stands in for your DNS and hosting, then publish on their own domain. Environments maps that progression. From code, Publish self-managed records covers the pure-protocol path. On DNSid Local, the local registry runs the same verification workflow against the local zone.

Identity is published as a signed TXT record below the agent’s domain, carrying an algorithm-prefixed record signature:

_dnsid.agent.example. IN TXT "v=dnsid-draft-01; gi=example.com; ek=https://example.com/.well-known/dnsid/jwks.json; ku=https://agent.example/.well-known/dnsid/jwks.json; lr=c2sp-tlog:public:https://log.dnsid.ai#EREREREREREREREREREREQ; su=https://agent.example/.well-known/dnsid/status.json; sg=EdDSA:<signature>"
Annotated DNSid TXT record showing the version, governance identifier, JWKS URL, log reference, status URL, and algorithm-prefixed record signature.Annotated DNSid TXT record showing the version, governance identifier, JWKS URL, log reference, status URL, and algorithm-prefixed record signature.

Each field in the signed TXT record, and what it carries. The sample lr= stream ID is an opaque placeholder; generate a fresh random ID for each identity instance.

The record in public DNS is authoritative—the registry API tracks workflow state, but what counterparties trust is what resolves. The DNSid Local quickstart walks through inspecting and verifying a record field by field.

A registered identity becomes trustworthy when its record is verified. dnsid verify runs TLS, JWKS-format, and proof-of-possession checks before the identity reaches VERIFIED / READY. From there, freshness is maintained by the domain owner, who republishes the record and keeps the status endpoint current. Status & freshness covers that upkeep.

DNSid identity record lifecycle: provisioning moves to verified and ready; records are republished by the domain owner.DNSid identity record lifecycle: provisioning moves to verified and ready; records are republished by the domain owner.

The record lifecycle. Self-managed records are maintained by the domain owner.

Lifecycle state changes—issuance, key rotation, revocation, retirement—are recorded as signed events in the agent’s lifecycle log, which verifiers check as part of domain verification. The Transparency log guide covers that half of the story.

Registrations driven through a registry—DNSid Local’s included—move through a fixed set of states, visible in dnsid status:

Registration lifecycle state machine: PENDING through PROVISIONING, VERIFICATION, and VERIFIED to READY, with a retryable ERROR branch and terminal REVOKED state.Registration lifecycle state machine: PENDING through PROVISIONING, VERIFICATION, and VERIFIED to READY, with a retryable ERROR branch and terminal REVOKED state.

The registration workflow. ERROR is recoverable; REVOKED is not.

  • PENDING → PROVISIONING → VERIFICATION → VERIFIED → READY is the happy path. A registration waits at VERIFICATION until your DNS, TLS, JWKS, and proof-of-possession checks pass.
  • ERROR is recoverable. If any check fails, the registration lands in ERROR with a specific error code and message. Read it with dnsid status, fix the underlying issue, then re-run dnsid verify to retry the full workflow. The usual suspects for self-managed domains are the _dnsid TXT record not yet resolving, an invalid TLS certificate, an unreachable JWKS URL, or an unanswered challenge. See dnsid challenge in the command reference.
  • REVOKED is terminal, as are REJECTED and CANCELLED for registrations that never completed. A revoked identity cannot return to READY—register a new identity on the domain instead.