SenseCrypt Docs
Guides

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

CredentialUsed byWhere
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 DNtls_client_auth: the client certificate's subject must equal it…/subject-dns
Client certificateself_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

StateAccepted?Meaning
current✅In use.
grace✅ until retired_atRotated 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

  1. Rotate with 24h, registering the new key or certificate.
  2. Deploy the new private key or certificate to your client.
  3. Confirm the client works with it: its token requests succeed, and the old one shows grace.
  4. 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).

On this page