Skip to main content
The mock issuer (packages/mock-issuer, @grantex/mock-issuer) stands in for an accredited issuer so the whole registry flow runs locally and in CI with no external party and no network. It is at version 0.1.0 and is not published; run it from the repository. It is https://mock-issuer.example. It has:
  • Identity. One ES256 (P-256) signing key, generated at start, and a static JWK Set. In Phase 1 the registry records an issuer’s keys as a static JWKS (see Becoming an Accredited Issuer); an OpenID Federation Entity Configuration is Phase 2.
  • Agent Passport issuance. A passport (vct urn:grantex:agent-passport:1, spec) bound to the agent’s key, with the provider, agent, verification and attestation_id disclosures and a status reference into the issuer’s own list. It is issued only after the agent proves possession of the key: the issuer hands out a challenge, the agent signs it (typ agent-key-proof+jwt, the same proof the registry uses in spec/agent-keys.md section 4), and anything else is refused with the registry’s codes: key_unproven (no proof, or a signature that does not verify with the key), key_binding_mismatch (a kid or sub for another key or agent) or audience_mismatch.
  • Passport status lists. Lists of 131,072 entries with indices drawn at random, published both as a Token Status List token (draft-ietf-oauth-status-list-21, two bits per entry) and as W3C Bitstring Status List credentials (revocation and suspension), each built from the issuer’s store and never one from the other. A passport can be revoked (final), suspended and reinstated. Its urn:grantex:tm:provider.entity attestation has its own entry and follows the passport: revoked or suspended with it, and reinstated with it unless it was revoked on its own.
  • Attestations. The compact JWS the registry takes (typ grantex-attestation+jwt, ES256, kid) for urn:grantex:tm:agent.identity or urn:grantex:tm:provider.entity, with external_credential_hash computed by the Agent Passport hash rule over the issued passport.
Signal delivery to the registry (an SSF transmitter) is Phase 2 and is not in the mock.

Status list ttl

In Phase 1 the status list ttl is 1 second for the mock issuer and CI, so a revocation reaches relying parties at once, and 600 seconds otherwise. serve uses 1 s unless given --standard-ttl (600 s) or --ttl SECONDS.

Issue, attest, suspend, reinstate and revoke

From packages/mock-issuer after make install (or npm ci here once packages/agent-passport is built with npm run build, since the mock uses the local @grantex/agent-passport build linked from the root package.json). The state directory holds the issuer’s private key and every passport it issued; it is scratch space for one run and must never be committed (.mock-issuer/ is ignored).
keys prints the entity id, status_list_base (https://mock-issuer.example/status/) and the public JWKS: the values to accredit the mock issuer with in a local registry. issue-passport generates an agent key under the state directory (or takes one with --agent-key FILE), runs both sides of the possession proof, and writes the passport, its attestation id and its status reference to --out. attest prints the attestation JWS; with --registry URL it also POSTs the compact JWS itself as the body, with Content-Type: application/grantex-attestation+jwt, to URL/v1/registry/attestations (change the path with --registry-path), the form the registry’s attestation route takes (application/jwt or application/grantex-attestation+jwt; JSON is refused with 415). No API key is sent: the route has none, and the issuer’s signature is the authentication. It waits at most 10 seconds and reads at most 64 KiB of the answer. A refusal exits with status 1 and prints its code, such as passport_revoked or attestation_not_registered.

Serve the JWKS and the status lists

The server binds 127.0.0.1 only and prints one JSON line with its origin and the origin_map pair. It serves: Status list URIs inside passports and attestations always stay https://mock-issuer.example/status/N. To let a local registry fetch them, start the auth service with the development-and-test origin override, which it refuses whenever it runs in production:

Use it from a test

The package’s API does the same in process; its README has an example that its tests run.
Last modified on September 28, 2026