Skip to content
Registry stack docs v0 · draft

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.

  • Rust toolchain (stable) installed and cargo on your PATH. The workspace has been tested with the edition in Cargo.toml.
  • curl available on your PATH.
  • 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.

Terminal window
git clone https://github.com/jeremi/registry-notary.git
cd registry-notary

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.

Terminal window
export REGISTRY_NOTARY_API_KEY_HASH=sha256:7fa1836768f03f0926a4ccc8de0c01ab493654dc9455b1703015098d0718ae57
export REGISTRY_NOTARY_BEARER_TOKEN_HASH=sha256:f2721a9dae064d1fdbc74cae1fb1baf26fac01b8aac160ae5acab97c35667d7f
export REGISTRY_NOTARY_AUDIT_HASH_SECRET=dev-registry-notary-audit-hash-secret
export EVIDENCE_SOURCE_REGISTRY_RELAY_TOKEN=dev-source-token

For 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:

Terminal window
export REGISTRY_NOTARY_ISSUER_JWK='{"kty":"OKP","crv":"Ed25519","d":"2oPoxdKuO7Kpd-3JLfNW_4xwpFxItbS-fxe03ZybYEw","x":"1aj_rLJsGFgw-5v925EMmeZj5JqP44xegafEKfZbdxc","alg":"EdDSA"}'
Terminal window
cargo run -p registry-notary-bin -- --config demo/config/registry-notary.yaml

The 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.

Terminal window
curl -s -H "x-api-key: dev-registry-notary-api-key" \
http://127.0.0.1:4255/openapi.json | head -c 200

A 200 response with a JSON body beginning {"openapi":"3.1.0",...} confirms the service is running and authenticating correctly.

Terminal window
curl -s -H "x-api-key: dev-registry-notary-api-key" \
http://127.0.0.1:4255/claims

The 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.

Terminal window
curl -s -H "x-api-key: dev-registry-notary-api-key" \
http://127.0.0.1:4255/.well-known/evidence/jwks.json

A 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”
Terminal window
curl -s -H "x-api-key: dev-registry-notary-api-key" \
http://127.0.0.1:4255/.well-known/evidence-service

This document describes the service identity, supported claim IDs, and output formats.

The service is working correctly when:

  1. GET /openapi.json returns 200 with a JSON body.
  2. GET /claims returns 200 with a JSON array containing at least one claim.
  3. GET /.well-known/evidence/jwks.json returns 200 with a keys array.
  4. Any request without a valid x-api-key or Authorization: Bearer header returns 401.

To generate the full OpenAPI document to a file (useful for Redocly or Swagger UI):

Terminal window
cargo run -p registry-notary-bin -- openapi > target/registry-notary.openapi.json

(README)

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.