Archived docs.You are viewing v0.13.0. For current guidance, useLatest. Report archive issues onGitHub.
This guide shows the minimum static-peer setup for delegated evaluation. It covers static peer configuration, inbound request verification, and the documented limits of the current implementation: no outbound Notary connector, no dynamic trust registration, and explicit in-memory state suitable for local, single-process development only.
What this enables
Section titled “What this enables”One trusted Notary can call another trusted Notary:
Agency B -> signed request JWT -> Agency A /federation/v1/evaluationsAgency B <- signed response JWT <- Agency AThe serving Notary verifies the request, enforces local peer policy, evaluates an admitted source-free claim only after policy passes, emits audit, and returns a signed result.
sequenceDiagram participant B as Agency B (requesting Notary) participant A as Agency A (serving Notary) participant Audit as Audit sink B->>A: POST /federation/v1/evaluations (signed request JWT) A->>A: Verify signature, audience, time window, profile, purpose, replay, denylist, body limit A->>A: Evaluate admitted source-free claim A->>Audit: Chained audit record A-->>B: Signed response JWT, or signed error, or Problem Details denial
The delegated evaluation exchange. Every check runs before claim evaluation, and an audit write failure prevents a successful signed response.
Required environment
Section titled “Required environment”Set these before starting the serving Notary:
export REGISTRY_NOTARY_AUDIT_HASH_SECRET='change-me-audit-hash-secret'export REGISTRY_NOTARY_FEDERATION_RESPONSE_JWK='{"kty":"OKP","crv":"Ed25519","d":"...","x":"...","alg":"EdDSA"}'export REGISTRY_NOTARY_PAIRWISE_SUBJECT_HASH_SECRET='change-me-pairwise-secret'Do not reuse the pairwise subject hash secret for audit hashing, cookies,
credential signing, or federation response signing. Federation response
signing references a named key from evidence.signing_keys, so the same local
JWK and PKCS#11 providers are used for evidence and federation signatures.
Minimal config shape
Section titled “Minimal config shape”evidence: signing_keys: federation-response: provider: local_jwk_env alg: EdDSA kid: agency-a-fed-1 status: active private_jwk_env: REGISTRY_NOTARY_FEDERATION_RESPONSE_JWK
federation: enabled: true node_id: did:web:agency-a.example.gov issuer: https://agency-a.example.gov jwks_uri: https://agency-a.example.gov/federation/jwks.json federation_api: https://agency-a.example.gov/federation/v1 supported_protocol_versions: - registry-notary-federation/v0.1 inbound_body_limit_bytes: 16384 max_request_lifetime_seconds: 300 clock_leeway_seconds: 60 signing: signing_key: federation-response pairwise_subject_hash: secret_env: REGISTRY_NOTARY_PAIRWISE_SUBJECT_HASH_SECRET response_shaping: minimum_denial_latency_ms: 250 emergency_denylist: node_ids: [] kids: [] peers: - node_id: did:web:agency-b.example.gov issuer: https://agency-b.example.gov jwks_uri: https://agency-b.example.gov/.well-known/jwks.json # Local Compose demos may use allow_insecure_private_network: true with # an HTTP service URL. Production peer JWKS URLs must use HTTPS. allowed_protocol_versions: - registry-notary-federation/v0.1 allowed_purposes: - https://purpose.example.gov/social-protection/service-delivery allowed_profiles: - disability_status_predicate evaluation_scopes: - disability_registry:evidence_verification evaluation_profiles: - id: disability_status_predicate ruleset: disability-status-v1 claim_id: disability_status subject_id_type: national_id max_claim_result_age_seconds: 3600The local peers block is authoritative. Manifest metadata helps partners
configure each other, but it does not grant access.
evaluation_scopes are the scopes assigned to the authenticated federation
principal when authorizing the selected local claim. They do not grant registry
or Relay source access. max_claim_result_age_seconds bounds the age of the
local claim result’s issued_at timestamp.
The current federation endpoint cannot select a claim with
evidence_mode.type: registry_backed. Startup rejects that composition because
federation audit does not yet carry the Notary evaluation id and Relay
consultation ids needed for end-to-end reconciliation. The existing federation
MVP is therefore limited to admitted source-free/self-attested claims.
Relay-backed federation is deferred until the audit boundary is implemented as
one complete feature. Notary has no direct registry-source fallback.
allow_insecure_private_network is a development and lab escape hatch for
private Compose networks. It allows HTTP peer JWKS fetches through the shared
bounded-fetch policy while still blocking cloud metadata targets. Do not enable
it for production federation.
Request requirements
Section titled “Request requirements”Send POST /federation/v1/evaluations with:
Content-Type: application/jwt- compact JWS serialization
- protected header
typ = registry-notary-request+jwt alg = EdDSAkidpresent in the configured peer JWKS- payload claims
iss,sub,aud,iat,nbf,exp,jti,protocol,action,profile,purpose, andrequest
The serving Notary rejects the request before claim evaluation when signature, audience, time window, profile, purpose, replay, emergency denylist, or body limit checks fail.
Response requirements
Section titled “Response requirements”Successful responses are compact signed JWTs with:
- protected header
typ = registry-notary-response+jwt issandsubfor the serving Notaryaudfor the requesting peer node idrequest_jticopied from the requestresult.subject_ref.hashas a pairwisehmac-sha256:handle
Stale claim results return HTTP 200 with a signed top-level error object.
Transport denials use RFC 9457 Problem Details JSON and do not prove whether
the subject exists.
Correctness state
Section titled “Correctness state”Replay protection uses the global Notary correctness-state backend. Production and multi-instance deployments use the Notary-owned PostgreSQL schema. Local, single-process development can select in-memory state explicitly:
deployment: profile: local multi_instance: falsestate: storage: in_memoryDo not run active-active federation with in-memory state. Install the
PostgreSQL schema and run registry-notary state doctor before enabling
privileged federation traffic. See
postgresql-state-operations.md for role,
installation, backup, restore, and upgrade procedures.
Verification checklist
Section titled “Verification checklist”Also confirm:
- federation routes are absent when
federation.enabledis false; - the peer JWKS contains the request signing
kid; - raw subject identifiers do not appear in audit JSONL;
- audit write failure prevents a successful signed response;
- replaying the same request
jtireturns a denial.