Skip to content
Registry StackDocsDevelopment (unreleased)

Manage Evidence Gateway verifier trust

For the consumer or verifier

View as Markdown

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.

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 kid values;
  • 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.

When the provider announces a new public key, build a new file without overwriting the active one:

Terminal window
evidencectl jwks \
--out trusted-issuer-keys.next.json \
provider-new-public.jwk.json \
provider-retiring-public.jwk.json

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

Use representative stored responses and the policies retained for them:

Terminal window
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.

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:

  1. verify the affected RFC 7638 thumbprint through the emergency onboarding channel;
  2. add it to the application’s current revokedKeyIds (Node) or revoked_key_ids (Rust and Python) configuration;
  3. remove the key from the current pinned JWKS;
  4. reconstruct or restart the client so every instance uses both changes; and
  5. 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.

Remove a retiring key from current verification only after:

  1. the provider’s maximum assertion lifetime plus accepted clock skew has elapsed since its last possible use;
  2. no current transaction can legitimately return an assertion signed by it;
  3. historical records retain the exact trust set needed to re-verify earlier decisions;
  4. 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.