Unreleased documentation. These pages follow the main branch and can change before the next release. For supported guidance, use v0.15.2.
Manage Evidence Gateway verifier trust
For the consumer or verifier
A valid signature proves control of a private key. Your consumer still decides which provider, issuer, key set, algorithm, audience, requirement, and configuration revision it trusts.
Keep that decision outside the Evidence Gateway response. Discovery helps you find candidate metadata; it does not make the candidate trusted.
Establish trust before the first request
Section titled “Establish trust before the first request”Through your organization’s provider-onboarding process, verify and retain:
- the legal issuer and technical provider identifiers;
- the expected Evidence Gateway service and JWKS endpoints;
- the ES256 P-256 public keys and their RFC 7638 thumbprint
kidvalues; - the audience that identifies your relying party;
- the requirements, evidence types, purposes, concepts, and configuration revisions you accept;
- the maximum assertion lifetime and clock skew your decisions allow.
Fetch /.well-known/evidence/jwks.json only as a candidate. Compare it through an authenticated,
independent channel or approved configuration change, then store the accepted JWKS as a versioned
file. Verification must not follow key URLs supplied by a response.
Assemble a candidate trust set
Section titled “Assemble a candidate trust set”When the provider announces a new public key, build a new file without overwriting the active one:
evidencectl jwks \ --out trusted-issuer-keys.next.json \ provider-new-public.jwk.json \ provider-retiring-public.jwk.jsonPass public JWK files only. The command rejects private key members, conflicting keys with the same
kid, and an existing output path.
During the overlap window, the candidate set contains the new key and each retiring key that may still have a valid assertion in circulation. The provider must retain retiring public keys for at least its maximum assertion validity plus verifier clock skew. Your retention policy may be longer when historical re-verification requires it.
Prove the rotation before accepting it
Section titled “Prove the rotation before accepting it”Use representative stored responses and the policies retained for them:
evidence verify \ --jws response-signed-with-retiring-key.json \ --jwks trusted-issuer-keys.next.json \ --policy retained-policy.json \ --at "<original-decision-instant>"After the provider begins signing with the new key, verify a synthetic response through the same procedure. Confirm that an unknown key still fails and that the candidate changes only the key set, not issuer, provider, audience, purpose, requirement, concept, or configuration expectations.
Approve and atomically activate the candidate through your normal configuration process. Keep the previous trust file and approval record for rollback and audit.
Revoke a compromised key immediately
Section titled “Revoke a compromised key immediately”Treat the current revocation list as a separate governed trust input, not as metadata learned from the issuer or from the response. When a provider reports a compromised service key:
- verify the affected RFC 7638 thumbprint through the emergency onboarding channel;
- add it to the application’s current
revokedKeyIds(Node) orrevoked_key_ids(Rust and Python) configuration; - remove the key from the current pinned JWKS;
- reconstruct or restart the client so every instance uses both changes; and
- prove that a response signed by the revoked key is refused before resuming decisions.
The current denylist takes precedence even when the key remains in a cached JWKS or an older prepared request retained it in its verification policy. This lets an application stop accepting a compromised key without waiting for caches or prepared work to expire.
Keep current acceptance separate from historical verification. If policy permits historical replay, retain the exact trust set, denylist, decision instant, and approval record that governed the original decision. Never remove a key from today’s denylist merely to replay an older record.
Retire the old key deliberately
Section titled “Retire the old key deliberately”Remove a retiring key from current verification only after:
- the provider’s maximum assertion lifetime plus accepted clock skew has elapsed since its last possible use;
- no current transaction can legitimately return an assertion signed by it;
- historical records retain the exact trust set needed to re-verify earlier decisions;
- rollback procedures no longer require the old signing generation.
Never make verification fetch a missing key automatically. An unknown kid is a trust-change
signal and must fail closed until your organization approves the change.
Provider operators use Rotate Evidence Gateway signing keys for the other side of this rotation. Consumers remain independent and do not inherit trust merely because the provider published a key.