Skip to main content
An accredited issuer is an organisation whose Agent Passports and attestations the Grantex registry accepts. Accreditation is decided outside the registry, by the registry operator, against the evidence the operator requires. What the registry holds is the outcome: one record per issuer that says who the issuer is, what it is accredited to attest, the keys it signs with and where its status lists live. Relying parties and the registry’s own checks read that record; nobody reads the evidence through it. This page covers Phase 1 of the registry. In Phase 1 an issuer’s keys are a static JWK Set recorded at accreditation. Resolving keys and trust marks through OpenID Federation is Phase 2 and is not available yet. The protocol text is in spec/registry-federation.md.

The issuer record

The registry adds id, status, suspended_effective_from, accredited_at, revoked_keys, created_at and updated_at.

Trust marks

A trust mark type says what an accredited issuer may attest. Phase 1 has five, and the registry refuses any other value: An issuer is accredited for a mark only while its record lists it. Removing a mark from the record ends the accreditation for that mark at once.

Keys

jwks is a JWK Set (RFC 7517 section 5) of public signing keys:
  • EC keys on P-256, for ES256 (RFC 7518 sections 3.4 and 6.2), are supported.
  • OKP keys on Ed25519, for EdDSA (RFC 8037), are supported as well.
  • Every key has a kid, and no two keys share one.
  • No private members: a key carrying d (or any RSA private member, or k) is refused, so a leaked private key is never published.
  • use, if present, is sig; key_ops, if present, is ["verify"]; alg, if present, matches the curve. The registry fills in alg.
  • At most 16 keys and 16 KiB.
Revoking a key is done by kid. The registry stops serving a revoked key immediately, and the kid cannot be registered again for that issuer: rotate to a new kid instead.

Status

When a check refuses an issuer it answers issuer_not_accredited (unknown or withdrawn), issuer_suspended (a suspension in effect) or trust_mark_missing (the issuer is not accredited for the mark in question).

How the operator records an issuer

The registry operator’s routes take a key from REGISTRY_OPERATOR_API_KEYS (see self-hosting, section 5). An issuer does not call them; the operator does, once accreditation is decided. Each change is recorded on the registry’s audit chain with the reason given for it. Accredit issuer.example:
accredit.json
The answer is 201 with the whole record, including its id (aiss_...). Later changes go to PATCH /v1/registry/issuers/{id} with a reason. Suspend it from a given time (a time in the past takes effect at once; leave effective_from out to suspend now):
suspend.json
Revoke one key:
revoke-kid.json
A PATCH can also set status to active or withdrawn, replace trust_marks with a new list, or replace jwks with a new set.

What relying parties see

GET /v1/registry/issuers needs no key, so it is served only when the operator sets REGISTRY_PUBLIC_ENDPOINTS_ENABLED=true (exactly true; the default is off). Off, the route is not registered and a request is answered as for any unknown route: 401 without an API key, 404 with one. The operator routes and the accreditation lookups work either way. It lists the issuers with only entity_id, trust_marks, status (as it stands at the time of the request), status_list_base and jwks without revoked keys, ordered by entity_id. It is paged with page (from 1, default 1) and pageSize (1 to 500, default 100), and reports total, the number of issuers in all; a page past the end is empty and still carries total, and any other value answers 400. Read pages until you have total issuers, or until a page comes back empty:
It is rate limited per client address and carries an ETag for each page: send it back in If-None-Match and an unchanged page answers 304. It is sent with Cache-Control: no-cache, so a cache checks back on every read and never serves a revoked key.
Last modified on September 28, 2026