Authdog has two kinds of key material, and you rotate them for different reasons.

The **public key** (`pk_...`) only identifies the environment. It is safe in a frontend or a mobile app. Rotating it is not a security response. The **signing keys** inside the environment are what make a session signature valid. The **client secret** on an OIDC client is what lets a machine mint tokens. Those two are the ones you rotate when something leaks, or on a schedule before it does.

## Rotate a signing key

Verification and signing are separate. The JWKS endpoint publishes every public key that is not revoked. Only keys marked **In use** sign new tokens. That is why you can introduce a key before you cut over.

In **Authentication > Sessions**:

1. Click **New JSON Web Key**. It is created **Inactive**: published for verification, not yet signing. The default algorithm is RS256.
2. Wait until verifiers have refreshed their cached JWKS. SDKs that call `userinfo` pick up the new key on that path. Anything that verifies from a long-lived JWKS cache needs the cache window to pass.
3. Click **Use Key** on the new key so it signs new tokens.
4. Leave the previous key inactive until every token it signed has expired. That is at least one token lifetime. See [Session security](/docs/secure/session-security).
5. Click **Revoke** on the old key.

Revoke is permanent. A revoked key never signs again. Tokens it already signed can still be verified from JWKS until they expire, which is why step 4 exists. Revoking first rejects sessions that are still honest.

Keep at least one key **In use**. The full table, algorithms, and claims preview are in [Sessions](/docs/console/sessions).

Each environment has its own keys. Rotate `production` on its own. A new key in `dev` does not replace the production signer.

## Replace a client secret

The client secret is shown once, when you create the OpenID client, the M2M application, or the agent identity. Store it in a secret manager or in [Vault](/docs/vault) before you close the dialog. You cannot read it back from the console later.

If it leaks:

1. Create a new client (or a new M2M application) for that workload and copy the new secret into the process that calls the token endpoint.
2. Deploy that process so it mints with the new secret.
3. Remove the old client so it cannot mint again.
4. Treat bearers the old secret already minted as valid until `expires_in`. There is no refresh token to cancel. Short lifetimes make this window small. [Machine authentication](/docs/secure/machine-authentication) is the model.

Don't put the new secret in the same ticket, chat, or CI log that exposed the old one.

## After either rotation

Confirm a fresh sign-in and a fresh client-credentials exchange in the environment you changed. Then look at [audit logs](/docs/audit-logs) for the key or client change, and for token use you don't recognize. A rotation that nobody asked for is an incident, not maintenance.

## Related

| Read | To learn how to |
| --- | --- |
| [Sessions](/docs/console/sessions) | Key states, algorithms, and token lifetime |
| [Machine authentication](/docs/secure/machine-authentication) | Which workload gets a client secret |
| [Vault](/docs/vault) | Store the secret after you copy it |
| [Sessions and tokens](/docs/concepts/sessions-tokens) | What the public key is for |
