diff --git a/docs/hydra/guides/oauth2-clients.mdx b/docs/hydra/guides/oauth2-clients.mdx index 5d5588bbed..15f906043a 100644 --- a/docs/hydra/guides/oauth2-clients.mdx +++ b/docs/hydra/guides/oauth2-clients.mdx @@ -180,6 +180,144 @@ See [API documentation](../../reference/api#tag/oAuth2/operation/patchOAuth2Clie ```` +## Rotate OAuth2 client secret + +OAuth2 client secret rotation allows you to change a client's secret without downtime. When you rotate a secret, the old secret +remains valid until you remove it, allowing you to update all your client services without service interruption. + +##### How secret rotation works + +1. Generate a new secret for the client service. Both the old and the new secrets can be used to authenticate from this point on. +2. Update your client services to use the new secret. +3. Test that the client services can authenticate with the new secret. +4. Manually remove the old secret. Only the new secret authenticates from this point on. + +:::info + +Secret rotation is available only for clients that use the `client_secret_basic` or `client_secret_post` token endpoint +authentication method. Ory keeps up to five rotated secrets per client. When you rotate again, the oldest rotated secret is +dropped and can no longer authenticate. Setting a new secret through the update or patch client APIs clears all rotated secrets. + +::: + +##### Rotate OAuth2 client secret + +To rotate an OAuth2 client secret, use the following methods: + +````mdx-code-block + + + +```bash +curl -X POST https://{project.slug}.projects.oryapis.com/admin/clients/{client-id}/secrets/rotate \ + -H "Authorization: Bearer ory_pat_..." +``` + +The response includes the new `client_secret`. Ory shows this value only once. Store it immediately in the secret store that your +client services read from, such as a secrets manager or an encrypted environment configuration. + +See [API documentation](../../reference/api#tag/oAuth2/operation/rotateOAuth2ClientSecret). + + + + +```typescript +import { Configuration, OAuth2Api } from "@ory/client" + +const ory = new OAuth2Api( + new Configuration({ + basePath: `https://${projectSlug}.projects.oryapis.com`, + accessToken: "ory_pat_..." + }) +) + +const { data: client } = await ory.rotateOAuth2ClientSecret({ + id: clientId +}) + +// Save the new client_secret immediately +console.log("New secret:", client.client_secret) +``` + + + +```` + +##### Remove old secret + +Once all services are updated to use the new secret, remove the old secret to revoke access using the old secret: + +````mdx-code-block + + + +```bash +curl -X DELETE https://{project.slug}.projects.oryapis.com/admin/clients/{client-id}/secrets/rotate \ + -H "Authorization: Bearer ory_pat_..." +``` + +After removing the old secret, only the current (new) secret is valid. The old secret can no longer authenticate. + +See [API documentation](../../reference/api#tag/oAuth2/operation/deleteRotatedOAuth2ClientSecrets). + + + + +```typescript +await ory.deleteRotatedOAuth2ClientSecrets({ + id: clientId +}) + +// Old secret is now revoked. +``` + + + +```` + +##### Secret rotation workflow example + +Here's a complete workflow for rotating a client secret: + +```bash +# 1. Get current client +CLIENT_ID="your-client-id" + +# 2. Rotate the secret +NEW_SECRET=$(curl -X POST "https://{project.slug}.projects.oryapis.com/admin/clients/$CLIENT_ID/secrets/rotate" \ + -H "Authorization: Bearer ory_pat_..." | jq -r '.client_secret') + +echo "New secret: $NEW_SECRET" + +# 3. Update your client services with the new secret +# (Both the old and the new secrets work during this period) + +# 4. Verify the new secret works +curl -X POST "https://{project.slug}.projects.oryapis.com/oauth2/token" \ + -u "$CLIENT_ID:$NEW_SECRET" \ + -d "grant_type=client_credentials" + +# 5. Once all client services are updated, remove the old secret +curl -X DELETE "https://{project.slug}.projects.oryapis.com/admin/clients/$CLIENT_ID/secrets/rotate" \ + -H "Authorization: Bearer ory_pat_..." + +# Old secret is now revoked +``` + +:::tip Zero-downtime credential rotation + +Secret rotation enables zero-downtime credential updates. Both the old and new secrets remain valid until you manually remove the +old secret, allowing you to update all your client services without service interruption. + +::: + +:::warning Security best practice + +Secrets remain valid indefinitely until you explicitly remove them. Always remove old secrets once your secret rotation process is +complete to ensure that compromised credentials cannot be used. + +::: + ## Delete OAuth2 client To delete an existing OAuth2 client, use the following methods: