JWKS Key Management
Partner JWKS publication, key rotation, and public-key management.
Partner JWKS Key Management
This guide explains how a partner should publish and manage public signing keys used by YesCash to verify partner-signed quotes.
Use this host in API examples:
https://api.yes.cash
---
1. Purpose
Partner quote signing uses asymmetric cryptography:
- the partner keeps the private signing key;
- the partner publishes the public key in a JWKS endpoint;
- YesCash uses the public key to verify signed quotes;
- each signed quote identifies the signing key using
kid.
The partner must keep private keys secure and keep the JWKS endpoint available.
---
2. What the partner must provide
During onboarding, the partner must provide:
| Item | Required | Description |
|---|---|---|
| JWKS URL | Yes | HTTPS URL where the partner public keys are published |
| Signing algorithm | Yes | Must be RS256 |
| Active key ID | Yes | Current kid used for signing |
| Rotation contact | Yes | Technical contact for key rotation or incident handling |
| Sandbox JWKS URL | Yes, if sandbox enabled | Separate sandbox key set |
| Production JWKS URL | Yes | Production key set |
Example:
https://partner.example.com/.well-known/jwks.json
---
3. JWKS endpoint requirements
The JWKS endpoint must:
- be served over HTTPS;
- return
application/json; - be reachable by YesCash infrastructure;
- return a valid JSON Web Key Set;
- include all active public signing keys;
- include keys before they are used for signing;
- keep old keys available during the agreed rotation overlap;
- not require customer authentication;
- not expose private key material.
Recommended path:
/.well-known/jwks.json
---
4. JWKS response shape
A JWKS is a JSON object with a keys array.
Example:
{
"keys": [
{
"kty": "RSA",
"kid": "quote-signing-2026-01",
"use": "sig",
"alg": "RS256",
"n": "<base64url-modulus>",
"e": "AQAB"
}
]
}
---
5. Required JWK fields
| Field | Required | Description |
|---|---|---|
kty | Yes | Must be RSA |
kid | Yes | Key identifier used in the JWS header |
use | Recommended | Use sig |
alg | Recommended | Use RS256 |
n | Yes | RSA modulus, base64url encoded |
e | Yes | RSA public exponent, usually AQAB |
---
6. Fields not allowed in public JWKS
Do not publish private key fields.
Never expose:
d
p
q
dp
dq
qi
oth
If any private key field appears in the public JWKS, treat it as a key compromise.
---
7. Key requirements
| Item | Requirement |
|---|---|
| Key type | RSA |
| Minimum size | RSA-2048 |
| Recommended size | RSA-3072 |
| Algorithm | RS256 |
| Purpose | Signature verification |
| Private key location | Partner-controlled backend or HSM/KMS |
| Public key location | Partner JWKS endpoint |
---
8. Key ID rules
The kid value links the signed quote to the public key.
The partner must:
- include
kidin every signed quote JWS header; - make sure the same
kidexists in the JWKS; - never reuse a
kidfor different key material; - use stable, readable key IDs;
- keep old
kidvalues available during rotation overlap.
Good examples:
quote-signing-2026-01
quote-signing-2026-06
partner-prod-rsa-001
Avoid:
key
current
1
test
---
9. Environment separation
Use separate keys for sandbox and production.
Recommended:
Sandbox JWKS:
https://sandbox.partner.example.com/.well-known/jwks.json
Production JWKS:
https://partner.example.com/.well-known/jwks.json
Do not use production private keys in sandbox.
Do not use sandbox private keys in production.
---
10. Recommended key lifecycle
Generate key
→ Publish public key in JWKS
→ Register/confirm key with YesCash
→ Start signing with key
→ Monitor verification success
→ Rotate before expiry or on schedule
→ Keep old public key during overlap
→ Retire old key
---
11. Planned key rotation
Use this process for normal scheduled rotation.
Step 1 — Generate new key
Generate a new RSA key pair.
Requirements:
- RSA-2048 minimum;
- RSA-3072 recommended;
- private key stored securely;
- new unique
kid.
Step 2 — Publish new public key
Add the new public key to the JWKS without removing the old key.
JWKS during overlap:
{
"keys": [
{
"kty": "RSA",
"kid": "quote-signing-2026-01",
"use": "sig",
"alg": "RS256",
"n": "<old-modulus>",
"e": "AQAB"
},
{
"kty": "RSA",
"kid": "quote-signing-2026-06",
"use": "sig",
"alg": "RS256",
"n": "<new-modulus>",
"e": "AQAB"
}
]
}
Step 3 — Confirm availability
Before signing with the new key, confirm:
- JWKS endpoint returns HTTP
200; - JSON is valid;
- new
kidappears; - no private fields are exposed;
- YesCash has acknowledged or detected the new key according to onboarding process.
Step 4 — Start signing with new key
New quotes should use the new key:
{
"alg": "RS256",
"kid": "quote-signing-2026-06",
"typ": "JWT"
}
Step 5 — Keep old key during overlap
Keep the old public key available long enough for:
- already-issued quotes to expire;
- retries to complete;
- delayed quote acceptance attempts to fail deterministically.
Do not remove the old key immediately after switching.
Step 6 — Retire old key
After the overlap period, remove the old public key from JWKS.
---
12. Emergency key rotation
Use emergency rotation if:
- private key may be compromised;
- public JWKS accidentally included private material;
- signing system is breached;
- unauthorized quote signing is suspected;
- signing key was exposed in logs or source code.
Emergency process:
1. Stop signing with compromised key.
2. Remove affected key from active signing service.
3. Generate new key pair.
4. Publish new public key in JWKS.
5. Notify YesCash technical support immediately.
6. Provide affected kid and time window.
7. Reissue any active quotes using the new key.
8. Monitor quote verification failures.
If private material was published, treat the key as compromised even if there is no evidence of abuse.
---
13. Caching guidance
YesCash may cache partner JWKS responses.
Partner JWKS should use reasonable cache headers.
Recommended:
Cache-Control: public, max-age=300
Content-Type: application/json
For planned rotation:
- publish the new key before using it;
- wait for cache propagation;
- only then sign new quotes with the new
kid.
For emergency rotation:
- notify YesCash support;
- remove compromised key from active signing immediately;
- expect some verification failures until caches refresh or support intervenes.
---
14. JWKS endpoint availability
Partner JWKS must be reliable.
Recommended minimum behavior:
| Scenario | Expected behavior |
|---|---|
| Normal request | HTTP 200 with valid JWKS |
| Unknown path | HTTP 404 |
| Maintenance | Avoid downtime; use rolling deploy |
| Key rotation | Serve old and new keys during overlap |
| CDN enabled | Ensure no stale JWKS during emergency rotation |
Partner systems should monitor:
- JWKS endpoint uptime;
- HTTP status;
- JSON validity;
- presence of active
kid; - TLS certificate expiry;
- unexpected key changes.
---
15. TLS requirements
The JWKS URL must use HTTPS.
The partner must:
- use a valid certificate from a trusted CA;
- avoid expired or self-signed certificates;
- support modern TLS;
- monitor certificate expiry;
- avoid redirect chains where possible.
---
16. Private key storage
Private keys must be stored in a secure backend environment.
Recommended storage options:
- HSM;
- cloud KMS;
- dedicated secrets manager with signing controls;
- restricted backend signing service.
Do not store private keys:
- in mobile apps;
- in browser apps;
- in source code;
- in build logs;
- in plain-text configuration;
- in shared developer workstations;
- in support tickets.
---
17. Signing service controls
The partner signing service should enforce:
- access control;
- audit logging;
- environment separation;
- rate limits;
- payload validation before signing;
- key ID selection policy;
- monotonic quote sequence handling;
- monitoring for unusual signing volume.
A quote should be signed only after:
- pricing is calculated;
- values shown to customer are fixed;
- payload schema is valid;
- quote expiry is set;
- customer subscription reference is present.
---
18. JWKS validation checklist
Before sending the JWKS URL to YesCash, validate:
- URL is HTTPS;
- endpoint returns HTTP
200; - response is valid JSON;
- response has a
keysarray; - each key has
kty,kid,n,e; ktyisRSA;algisRS256;useissig, if present;- no private key fields are present;
- key size is RSA-2048 or stronger;
- active signing
kidexists in JWKS.
---
19. Example curl test
curl -i https://partner.example.com/.well-known/jwks.json
Expected response:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: public, max-age=300
Body:
{
"keys": [
{
"kty": "RSA",
"kid": "quote-signing-2026-01",
"use": "sig",
"alg": "RS256",
"n": "<base64url-modulus>",
"e": "AQAB"
}
]
}
---
20. Common JWKS problems
| Problem | Result | Fix |
|---|---|---|
kid in JWS not found in JWKS | Quote verification fails | Publish matching key or sign with active kid |
| JWKS returns invalid JSON | Key fetch fails | Fix JWKS generator |
| JWKS exposes private fields | Key compromise | Rotate immediately |
| JWKS only has new key | Old quotes fail during overlap | Keep old key until safe retirement |
| New quote signed before JWKS propagation | Verification may fail | Publish key first, wait, then sign |
| Sandbox quote signed with production key | Environment mismatch | Separate keys per environment |
| Expired TLS certificate | JWKS unavailable | Renew certificate |
| Weak RSA key | Key rejected | Generate RSA-2048 or stronger |
---
21. Local verification
Partners should verify every generated quote locally before using it.
Local verification should:
1. read the compact JWS;
2. extract the kid;
3. fetch local JWKS;
4. select matching public key;
5. verify RS256 signature;
6. decode payload;
7. check required claims;
8. check quote expiry;
9. check customer subscription reference;
10. check quote sequence.
If local verification fails, the YesCash API verification will fail.
---
22. Operational monitoring
Monitor:
- number of quotes signed;
- quote verification failures;
- signing service errors;
- JWKS endpoint uptime;
- JWKS response validity;
- active
kid; - unexpected key changes;
- failed key fetches;
- emergency rotation events.
Recommended alerts:
| Alert | Severity |
|---|---|
| JWKS endpoint down | High |
Active kid missing from JWKS | High |
| Private key fields detected in JWKS | Critical |
| Quote verification failures spike | High |
| TLS certificate near expiry | Medium |
| Signing volume anomaly | High |
---
23. Support information to provide
When escalating JWKS or signing issues, provide:
- environment;
- JWKS URL;
- active
kid; - quote ID, if relevant;
- timestamp;
- correlation ID, if available;
- HTTP status from JWKS endpoint;
- error code returned by API;
- sanitized JWS header and payload;
- confirmation that private key was not exposed.
Never send private key material.
---
24. Certification checklist
Before go-live, confirm:
- production JWKS URL is final;
- sandbox JWKS URL is separate;
- production private key is stored securely;
- active production
kidis registered and visible; - JWKS endpoint is monitored;
- TLS certificate is monitored;
- planned rotation procedure is documented;
- emergency rotation procedure is documented;
- quote signing service uses only approved keys;
- generated quotes verify locally;
- YesCash sandbox quote verification passes;
- no private key fields appear in public JWKS.