Skip to content
autonym.dev
ContentsHide contents

Core

A3. Identifiers, handles and resolution

spec 1.0-draft-1

Status: normative. Document version 1.0-draft-1.

A3.1 Owner and recipient identifiers

Internal record, partition and entry identifiers use the prefix and ULID grammar in identifiers. They are owner-management and export identifiers. The legacy wire term profile_id means a partition of the person's record; it is not a commercial dossier.

Recipients MUST NOT receive a record DID, canonical entry ID, owner identifier, another client's handle or another client's grant identifier through ordinary reads. Version 1 portability uses the signed export and preserves canonical entry IDs. Person-held record keys and public DID host bindings are reserved for a separately specified extension, not a dependency of Core or Portable.

A3.2 Pairwise handles and entry aliases

Syntax: autonym:<local>@<authority>. Newly issued pairwise locals are exactly 32 lower-case RFC 4648 base32 characters, without padding. The authority is the configured lower-case ASCII DNS hostname, with no port, user information, path or trailing dot. An IP address is never an authority, and neither is a name whose last label is all digits or 0x followed by hexadecimal digits, since URL parsers read such a name as an IPv4 address. The handle pattern in the published schemas checks only the syntax of the authority's labels, so it also accepts such names. A valid shape example is autonym:abcdefghijklmnopqrstuvwxyz234567@autonym.example.

Each record partition has a dedicated random 256-bit handle key. Generate the local part as the first 32 characters of lower-case, unpadded RFC 4648 base32 of HMAC-SHA256 over UTF-8 RFC 8785 canonical JSON:

json
{
  "purpose": "autonym.handle.v1",
  "client_id": "https://recipient.example/client",
  "rotation": "00000000-0000-4000-8000-000000000001"
}

client_id is the exact registered identifier, not a normalised URL or display name. rotation is a newly generated lowercase UUIDv4 per recipient rotation. Check uniqueness before committing issuance. A collision requires a fresh rotation and retry. HMAC keys are never shared with recipients or exported to a new provider.

Recipient entry references use rent_ followed by all 52 base32 characters of HMAC-SHA256 under the same dedicated key, over JCS of {purpose:"autonym.entry.v1", client_id, rotation, entry_id}. The different purpose separates the two uses. Rotation atomically changes handles and aliases, invalidates old grants/tokens and starts required purge processing. Never expose canonical IDs through provenance, dependencies, errors, ETags or diagnostic counts.

The older 12-to-32-character parser grammar remains accepted for reading historical owner material. New wire objects use the exact 32-character contract. Public handles are optional: 3 to 30 ASCII characters, lower-case letters and digits with single internal hyphens. No leading, trailing or consecutive hyphens. Claiming one requires re-authentication, rate limits, a reserved-name list, one public name per partition, a 30-day change cooldown and a 12-month release quarantine. A public name provides a provider address for consent; it MUST NOT yield record contents, a DID or evidence that the person exists to unauthenticated enumeration. Token subjects remain pairwise.

Pairwise identifiers prevent identifier-based cross-recipient joins; they do not make context anonymous or prevent correlation using facts already disclosed.

A3.3 Discovery

GET /.well-known/autonym returns the discovery schema: protocol version, configured issuer and authorisation server, the trusted JWKS URI of the provider's A5.4 key set, enabled REST/MCP endpoints and an honest role-specific capability declaration. Disabled surfaces are null. No person's identifier or record information appears in discovery. The schema example in protocol examples illustrates capability claims, not a deployed service.

OAuth protected-resource metadata is separate and follows A6. Clients resolve the host from a user-supplied handle or configured provider, validate HTTPS and metadata origin, and never trust request forwarding headers as the provider's identity. Every fetch of an untrusted client/provider URL must use SSRF-safe retrieval with DNS/address checks, size/time limits and revalidation at each allowed redirect.

A3.4 Migration

Migration transfers an owner-approved export into a new provider. Canonical owner IDs can be preserved, but the new provider creates fresh pairwise keys, handles, aliases and authority. Imported grants are history only. The person reauthorises each recipient against the new audience.

The old provider MUST NOT redirect authenticated API or token requests to a different origin, forward credentials, or reveal the destination to contributors. Destination notifications are separately approved per recipient. An optional public-handle web redirect requires separate explicit approval and carries no credential or personal data. Purge instructions and acknowledgements continue at the old provider until settled; the new provider cannot acknowledge deletion of the old provider's disclosures.

Checks: PAIR-01, CORE-01, PORT-01, HANDLE-01, MIGRATE-01, FETCH-01. Fixed synthetic framing vectors give canonical bytes, HMAC digest, base32 and final identifiers. Independent cryptographic interoperability remains a runtime release gate.

References to other standards and projects describe intended technical alignment only and do not imply endorsement or partnership.