Released docs. You are viewing the documentation published with v0.46.0. Development docs are available at Latest.
If you operate an application that verifies Evidence responses, its verifier must trust provider keys your organization approved, never keys the service or the response supplies while it is being verified. You pin the provider’s public keys, keep a revoked key out, and take the provider’s signing-key rotation without a gap.
Build the pinned key set
Section titled “Build the pinned key set”Obtain each public JWK from the provider through your onboarding channel, not from its JWKS endpoint alone, then assemble the set your client will trust:
rstack evidence jwks \ --output trusted-jwks.next.json \ provider-current.public.jwk.json \ provider-next.public.jwk.jsonwrote trusted-jwks.next.jsonThe command refuses a private key and an existing output file; pass --force to overwrite. Write
each set to a new file and activate it through your configuration change process, so the previous
set stays available for rollback.
Pin the set in the client profile
Section titled “Pin the set in the client profile”Pass the set to rstack evidence client profile create with --pinned-jwks, a path relative to the
profile file. The other values are the ones your deployment’s operator gave you; the private key is
the one your client registered with the issuer:
rstack evidence client profile create \ --base-url https://evidence.example.com \ --client-id age-check-app \ --private-key-file app-key/client-assertion-p384-private-jwk \ --pinned-jwks trusted-jwks.json \ --output age-check-client.jsonCreated client profilerstack evidence keygen client-assertion --output-dir app-key writes a key of that name (ES384, its
default); register its public half with your issuer. Without --pinned-jwks the profile fetches the
service’s key set itself, over HTTPS discovery or, with --local-loopback-discovery, over
loopback. A profile carries no revoked-key list in any trust mode, so with a profile you revoke a
key by removing it from the pinned set.
Keep a denylist with an explicit client
Section titled “Keep a denylist with an explicit client”When you need revoked key ids beside the pinned set, construct the client yourself:
client = EvidenceClient( "https://evidence.example.com", trusted_jwks=json.loads(Path("trusted-jwks.json").read_text()), revoked_key_ids=["<revoked kid>"], token=token_config,)In Node, the same configuration takes trustedJwks and revokedKeyIds. A revoked key id is
refused even while the key is still in the pinned set.
Take a rotation
Section titled “Take a rotation”- When the provider announces a new key, add it to the pinned set and activate the set before the provider signs with it.
- Once the provider’s maximum assertion lifetime plus clock skew has passed since the old key last
signed, remove the old key from the set. With an explicit client, also add its key id to
revoked_key_idsif it was compromised.
A response signed by a key outside the set fails with code key. Treat that as a trust change to
approve, never as a key to fetch. Rotation does not touch decisions you already kept: each
retained verification carries the keys trusted when its request was sent, so
a replay reads no current key set. The provider’s side is
Rotate Registry Evidence signing keys.
Registry Evidence security model, for the threats pinning answers.
Cookies on Registry Stack
We use optional cookies to understand how you use the main Registry Stack website and this documentation. If you contact us, we may link this activity to your enquiry. You can change your choice at any time. Read the privacy policy.
Your browser asks sites not to track you, so optional tracking stays off.
We could not use or save that choice. Optional tracking remains off.