Signing and key discovery
The PoP signing envelope, the ES256 signature, key discovery via JWKS, and rotation vs revocation.
Every PoP is signed. The signature binds the proof contents to a key version, and the public half of that key is published so any party can verify the signature independently. This page fixes the wire-level signing contract and the key discovery surface a verifier MUST use.
Signing envelope
A PoP is a JSON object with the following top-level fields:
| Field | Type | Description |
|---|---|---|
kid | string | Identifier of the key version that produced the signature. |
alg | string | Signing algorithm. MUST equal ES256. |
iat | integer | Unix timestamp (seconds) at generation time. |
schema_version | string | The PoP schema version defining the layout of data. |
data | object | The canonical proof payload. See Artifact contents. |
signature | string | base64url-encoded DER signature over the canonical serialization of data. |
The signature covers the canonical serialization of data only. The kid, alg, iat, schema_version, and signature fields are envelope metadata and are NOT part of the signed payload. A verifier MUST verify over the canonical serialization of data and MUST NOT include any envelope field in the signed input.
Signature algorithm
algMUST equalES256— ECDSA on curve P-256 (secp256r1) with SHA-256.- The signed input is the canonical serialization of
dataunder RFC 8785 (JSON Canonicalization Scheme). The verifier MUST canonicalizedatathe same way before verifying. signatureis the DER-encoded ECDSA signature, encoded as base64url.
Key identifier (kid)
The kid identifies the key version that produced the signature.
- Format:
pop-signing-v{N}, where{N}is a monotonically incrementing integer starting at1(for example,pop-signing-v1,pop-signing-v2). kidvalues are assigned sequentially with no gaps, and are immutable once assigned.- Every PoP carries exactly one
kid. A verifier MUST read it from the envelope and resolve the matching public key before verifying.
Key discovery (JWKS)
Public keys are discovered through a public, unauthenticated JWKS endpoint that returns a JWK Set (RFC 7517). It carries no secret material.
- The response contains one JWK entry per published key version, each including at minimum
kty,use,alg,kid,crv,x,y. - A verifier MUST locate the JWK whose
kidmatches the artifact, and MUST reject the artifact as unverifiable if no suchkidis present. - The JWKS endpoint URL for your environment is provided in your onboarding package.
Verifier obligations
A verifier MUST:
- Extract
kidandalgfrom the envelope. - Fetch the JWKS endpoint and locate the JWK with the matching
kid. - Reject the artifact if the
kidis not present in the JWKS response. - Verify
signatureover the RFC 8785 canonical serialization ofdata, using the located public key and thealgfrom the envelope.
A verifier MUST NOT trust an artifact whose signature does not verify, and MUST NOT verify the signature over anything other than the canonical data.
Rotation vs revocation
Two distinct key lifecycle events change what the JWKS endpoint serves, and they differ in their effect on historical artifacts.
| Rotation (orderly) | Revocation (emergency) | |
|---|---|---|
| Trigger | Planned key change. | Suspected or confirmed key compromise. |
| Effect on signing | A new key version becomes active; new PoPs are signed under the new kid. | The compromised key version is disabled; a new active key version replaces it. |
| Effect on JWKS | The previous key version is retained in the JWKS response. | The compromised kid is withdrawn from the JWKS response immediately. |
| Effect on historical PoPs | Artifacts signed under the previous kid remain verifiable indefinitely. | Artifacts signed under the revoked kid become cryptographically unverifiable. |
Revocation makes previously issued artifacts unverifiable, and this is the correct security behavior: a key that may be compromised must not continue to vouch for anything. Internal payment truth — the finality outcome and the on-chain facts — is unaffected; only the cryptographic proof artifact is impacted. The on-chain settlement remains independently checkable against the chain.
Historical verifiability
As long as a kid is present in the JWKS response, every artifact signed under it verifies. A kid absent from the JWKS response — whether revoked after compromise, or a retired version — MUST be treated as unverifiable. Verifiers that cache the JWKS response SHOULD re-fetch on a verification failure, since a cached response may not yet reflect a recent revocation.