From 2b84dfc5260331c831387325b76bd624583150e9 Mon Sep 17 00:00:00 2001 From: unatasha8 Date: Thu, 16 Jul 2026 10:56:29 -0700 Subject: [PATCH] docs: adds client secret rotation info --- docs/hydra/guides/oauth2-clients.mdx | 171 ++++++++++++++++++++++++++- 1 file changed, 166 insertions(+), 5 deletions(-) diff --git a/docs/hydra/guides/oauth2-clients.mdx b/docs/hydra/guides/oauth2-clients.mdx index 5d5588bbed..ad48710adf 100644 --- a/docs/hydra/guides/oauth2-clients.mdx +++ b/docs/hydra/guides/oauth2-clients.mdx @@ -4,15 +4,29 @@ title: Manage OAuth 2.0 and OpenID Connect clients sidebar_label: Manage OAuth2 clients --- -OAuth2 clients are applications that securely authenticate with the authorization server to obtain access to an HTTP service. -Confidential clients can use registered client secrets to authenticate, while public clients are unable to use registered client -secrets. OAuth2 clients can be configured in a secure manner using the Ory OAuth2 and OpenID Connect product. This documentation -article explains how to manage OAuth2 clients using the Ory Console, Ory SDK, Ory CLI, and Ory REST APIs. +OAuth2 clients are applications that securely authenticate with an authorization server to obtain access to an HTTP service. Every +OAuth2 client is either confidential or public, depending on whether it can keep a secret. Applications that run on infrastructure +you control, for example, backends and services, are confidential clients. They authenticate with a client secret. Applications +distributed to users, for example, single-page apps, mobile, and native apps, are public clients. Anyone can read the code and +extract an embedded secret, so they authenticate with PKCE and have no secret at all. + +For each of your confidential clients, you register a client record with the client's secret for authentication. Public clients do +not have a client secret in the registered client record. In Ory, you set whether the client is confidential or public with +`token_endpoint_auth_method` value, where `none` means public. + +This documentation article explains how to manage OAuth2 clients using the Ory Console, Ory SDK, Ory CLI, and Ory REST APIs. ## Create OAuth2 client To create a new OAuth2 client, use the following methods: +:::info + +Clients that use the `client_secret_basic` or `client_secret_post` `token-endpoint-auth-method` are able to perform secret +rotation. + +::: + ````mdx-code-block import Tabs from '@theme/Tabs' import TabItem from '@theme/TabItem' @@ -23,7 +37,7 @@ import TabItem from '@theme/TabItem' The Ory Console is a web-based user interface that allows you to manage OAuth2 clients. To create a new client: 1. Go to -2. Click **Create OAuth2 Client** and complete the form or update an existing client. +2. Click **Create OAuth2 Client** and complete the form. 3. When creating a confidential client, copy the client secret when printed. It is only shown once. @@ -110,6 +124,12 @@ across deployments and requires no client updates. To update an existing OAuth2 client, use the following methods: +:::warning + +If you use secret rotation, setting a new secret through the update client API clears all rotated secrets. + +::: + ````mdx-code-block @@ -153,6 +173,12 @@ See [API documentation](../../reference/api#tag/oAuth2/operation/setOAuth2Client To partially update an existing OAuth2 client, use the following methods: +:::warning + +If you use secret rotation, setting a new secret through the patch client API clears all rotated secrets. + +::: + ````mdx-code-block @@ -180,6 +206,141 @@ 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. This allows you to update the secret wherever your applications store it, then restart or +redeploy anything that reads it, without service interruption. + +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. + +:::warning + +If you use secret rotation, setting a new secret through the update or patch client APIs clears all rotated secrets. + +::: + +### How secret rotation works + +1. Rotation generates a new secret for the client. Both the old and the new secrets can be used to authenticate from this point + on. +2. Update the secret wherever it's stored, then restart or redeploy whatever applications read it. +3. Verify that the application can authenticate with the new secret. +4. Delete the old secret. Only the new secret authenticates from this point on. + +### 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 returns this value once and stores only its hash, so it can't be +retrieved later. Save it now, wherever you keep the current secret. + +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) +``` + + + +```` + +:::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. + +::: + +### Remove old secret + +Once your application is authenticating with the new secret everywhere, delete the old secret to revoke access: + +````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's 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 your client's 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 +``` + ## Delete OAuth2 client To delete an existing OAuth2 client, use the following methods: