Rotating client keys and certificates
Rotate the keys and certificates your applications and M2M apps authenticate with — private_key_jwt signing keys, request-object keys, mutual TLS trust anchors, subject DNs and self-signed certificates — with a 24-hour overlap or an immediate stop, and without breaking sign-in.
An application that authenticates with a key or a certificate registers the public half with SenseCrypt. This guide covers replacing it without a sign-in gap: the new credential is accepted at once, and the old one keeps working until your clients have switched.
This is about the credentials your clients present. For the tenant's own signing keys (the ones that sign your ID tokens), see Rotating signing keys.
What can be rotated
| Credential | Used by | Where |
|---|---|---|
| Signing keys (public JWKs) | private_key_jwt client authentication, signed request objects (JAR), signed CIBA requests | …/keys |
| Trust anchors (CA certificates) | tls_client_auth: client certificates must chain to one | …/trust-anchors |
| Allowed subject DN | tls_client_auth: the client certificate's subject must equal it | …/subject-dns |
| Client certificate | self_signed_tls_client_auth: the certificate itself | …/certificates |
The paths sit under /v1/admin/oidc-apps/{client_id} for an OIDC application and /v1/admin/m2m-apps/{id} for an M2M app in a FAPI 2.0 tenant. In the console, use the application's Credentials tab, or ⋯ → Credentials on an M2M app.
Keys published at a JWKS URL (jwks_uri) are rotated by your client at that URL. SenseCrypt re-reads it within 5 minutes, or at once with Refresh keys now.
Each credential's lifecycle
| State | Accepted? | Meaning |
|---|---|---|
current | ✅ | In use. |
grace | ✅ until retired_at | Rotated out; still accepted so your clients can switch. |
retired | ❌ | Stopped. Can be reactivated for 30 days (reactivatable_until). |
revoked | ❌ | Stopped for good. It can never be reactivated or registered again. |
An application that authenticates with a credential always keeps at least one current: the last current one can't be stopped or revoked (409 last_current_key). Rotate a new one in first.
Rotate
POST …/rotate registers the new credential and retires every current one, after the grace period you choose:
"grace_period": "24h"(recommended). The old credential keeps working for 24 hours while you deploy the new one."grace_period": "immediate". The old one stops at once. Use it when it is compromised, or when your client already uses the new one. The console asks you to type the application's name first.
curl -X POST {admin_api}/v1/admin/oidc-apps/{client_id}/keys/rotate \
-H "Authorization: Bearer {management_token}" \
-H "Content-Type: application/json" \
-d '{"jwks": {"keys": [{"kty": "EC", "crv": "P-256", "alg": "ES256", "kid": "key-2", "x": "…", "y": "…"}]}, "grace_period": "24h"}'Send one public key (or one PEM certificate for the anchor and certificate paths; a "dn" for the subject path). Private key material is refused. The response lists every credential with its state.
Other operations on the same path: POST … adds a signing key or trust anchor without retiring any, and on each item there are POST …/{id}/retire (Stop now), …/{id}/reactivate (Keep active during the window, or Reactivate within 30 days) and …/{id}/revoke. Revoking can also end the app's live tokens ("revoke_tokens": true). In the console, Revoke asks for a reason (recorded in the audit log) and the application's name, because it can't be undone. Every action is recorded in the audit log.
A safe rotation, step by step
- Rotate with
24h, registering the new key or certificate. - Deploy the new private key or certificate to your client.
- Confirm the client works with it: its token requests succeed, and the old one shows
grace. - Let the window close, or Stop now on the old one once nothing uses it.
If something goes wrong inside the window, Keep active on the old credential cancels its countdown.
An application has only one current subject DN and one current self-signed certificate, so Keep active on an old one swaps them back: the old one is current again at once, and the one it replaces keeps working for 24 hours, the same window a rotation gives. The console asks you to confirm first.
An application accepts at most 16 keys (10 trust anchors) at a time. A rotation is never blocked by that limit: an immediate one stops the keys it replaces, and a 24h one may go one over the limit until the window closes. A second rotation inside that window needs room, so Stop now an old key first.
A compromised credential: rotate with immediate, then Revoke the old one, with revoke_tokens if tokens obtained with it must stop working too. Revoked credentials can't come back, whether by POST, rotate, a whole-set PATCH of the application, or a JWKS URL that still publishes them.
The whole-set PATCH still works
PATCH /v1/admin/oidc-apps/{client_id} with jwks, tls_client_auth_ca_pem, tls_client_auth_subject_dn or tls_client_certificate_pem keeps its original meaning: exactly this set, now. Anything not in it stops at once, and grace windows end. A retired credential it includes becomes current again; a revoked one is refused (*.key_revoked).
Related
- Machine-to-machine: M2M apps that sign in with a key or a certificate.
- Sender-constrained tokens: DPoP and mutual TLS.
- Error codes: the codes these routes return.
Rotating signing keys
Operator how-to for rotating a tenant's OIDC and SAML signing keys — one-shot OIDC rotate vs make-before-break SAML staging, the overlap (grace) windows, staged certs by kid, KMS vs software custody, and what your relying parties and service providers must do during the overlap.
Audit log
Read, page, live-stream, and export the console-governance audit trail in the admin console or the Management API — and understand its tamper-evidence.