Preview release. These docs are a work in progress. Pages are still being written, links may break, and structure may shift without notice. Treat everything here as a draft and report issues on GitHub.
Run Registry Notary locally
The steps below start Registry Notary with the demo config and use curl to probe the claims list, the JWKS endpoint, and the service capabilities document. Full claim evaluation requires a source registry at the configured base_url; configure a claim covers that step, and Registry Lab wires the full topology together.
Prerequisites
Section titled “Prerequisites”- Rust toolchain (stable) installed and
cargoon yourPATH. The workspace has been tested with the edition in Cargo.toml. curlavailable on yourPATH.- A shell that reads environment variables (any POSIX shell).
You do not need a running Registry Relay instance to start the service. Claim evaluation against the demo config will fail to fetch source data when no source registry is running, but all other routes respond normally.
1. Clone the repository
Section titled “1. Clone the repository”git clone https://github.com/jeremi/registry-notary.gitcd registry-notary2. Set required environment variables
Section titled “2. Set required environment variables”Registry Notary starts fail-closed: no protected route is served unless static credentials or OIDC auth are configured.
The demo config uses static credentials. It stores API-key and bearer-token fingerprints in environment variables named by hash_env, plus a separate audit hash secret.
export REGISTRY_NOTARY_API_KEY_HASH=sha256:7fa1836768f03f0926a4ccc8de0c01ab493654dc9455b1703015098d0718ae57export REGISTRY_NOTARY_BEARER_TOKEN_HASH=sha256:f2721a9dae064d1fdbc74cae1fb1baf26fac01b8aac160ae5acab97c35667d7fexport REGISTRY_NOTARY_AUDIT_HASH_SECRET=dev-registry-notary-audit-hash-secretexport EVIDENCE_SOURCE_REGISTRY_RELAY_TOKEN=dev-source-tokenFor credential issuance, you also need an Ed25519 OKP JWK.
The variable name is set by credential_profiles.<id>.issuer_key_env in the config.
The demo config uses REGISTRY_NOTARY_ISSUER_JWK.
A development-only key (never use in production) is hardcoded in the
sd_jwt.rs tests:
export REGISTRY_NOTARY_ISSUER_JWK='{"kty":"OKP","crv":"Ed25519","d":"2oPoxdKuO7Kpd-3JLfNW_4xwpFxItbS-fxe03ZybYEw","x":"1aj_rLJsGFgw-5v925EMmeZj5JqP44xegafEKfZbdxc","alg":"EdDSA"}'3. Start the service
Section titled “3. Start the service”cargo run -p registry-notary-bin -- --config demo/config/registry-notary.yamlThe demo config binds to 127.0.0.1:4255
(demo/config/registry-notary.yaml:7).
The default bind address when no config specifies one is 127.0.0.1:8081
(config.rs:143).
You will see tracing output on startup.
The service is ready when you see a line containing registry notary listening followed by the bind address.
4. Confirm the OpenAPI document
Section titled “4. Confirm the OpenAPI document”curl -s -H "x-api-key: dev-registry-notary-api-key" \ http://127.0.0.1:4255/openapi.json | head -c 200A 200 response with a JSON body beginning {"openapi":"3.1.0",...} confirms the service is
running and authenticating correctly.
5. List available claims
Section titled “5. List available claims”curl -s -H "x-api-key: dev-registry-notary-api-key" \ http://127.0.0.1:4255/claimsThe response is a JSON array of claim definitions visible to your credentials.
The demo config defines three claims: date-of-birth, farmed-land-size, and
farmer-under-4ha.
6. Fetch the issuer JWKS
Section titled “6. Fetch the issuer JWKS”curl -s -H "x-api-key: dev-registry-notary-api-key" \ http://127.0.0.1:4255/.well-known/evidence/jwks.jsonA 200 response confirms that the issuer JWK loaded from the environment variable is valid
and that the public key is exported correctly.
7. Inspect the service capabilities document
Section titled “7. Inspect the service capabilities document”curl -s -H "x-api-key: dev-registry-notary-api-key" \ http://127.0.0.1:4255/.well-known/evidence-serviceThis document describes the service identity, supported claim IDs, and output formats.
Verification
Section titled “Verification”The service is working correctly when:
GET /openapi.jsonreturns200with a JSON body.GET /claimsreturns200with a JSON array containing at least one claim.GET /.well-known/evidence/jwks.jsonreturns200with akeysarray.- Any request without a valid
x-api-keyorAuthorization: Bearerheader returns401.
To generate the full OpenAPI document to a file (useful for Redocly or Swagger UI):
cargo run -p registry-notary-bin -- openapi > target/registry-notary.openapi.json(README)
Troubleshooting
Section titled “Troubleshooting”Service exits immediately on startup.
The config validator runs before the HTTP listener binds.
Check the tracing output for a EvidenceConfigError message.
Common causes: evidence.enabled is not true; no API key or bearer token is configured;
a source binding references a connection name that does not exist in source_connections;
or audit.hash_secret_env is missing.
401 Unauthorized on every request.
Confirm the raw token you send matches the fingerprint stored in the environment variable named by hash_env in the YAML config.
The demo config expects REGISTRY_NOTARY_API_KEY_HASH and REGISTRY_NOTARY_BEARER_TOKEN_HASH.
GET /claims returns an empty array.
The demo config scopes claims to civil_registry:evidence_verification and
farmer_registry:evidence_verification.
Confirm that the credential configured in auth.api_keys or auth.bearer_tokens carries
those scopes.
Claim evaluation returns an error about source connection.
Claim evaluation contacts the source registry at the URL in source_connections.<id>.base_url.
If no source registry is running, you will receive a source fetch error.
The configure a claim page covers source connector setup.
REGISTRY_NOTARY_ISSUER_JWK parse error.
The JWK must be a valid OKP Ed25519 key with both d (private) and x (public) components
present and base64url-encoded without padding.