Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions docs/hydra/guides/oauth2-clients.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,137 @@ See [API documentation](../../reference/api#tag/oAuth2/operation/patchOAuth2Clie
</Tabs>
````

## 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 explicitly clean it up, allowing you to update all services using the client credentials without service
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
remains valid until you explicitly clean it up, allowing you to update all services using the client credentials without service
remains valid until you remove it, allowing you to update all your services without service

interruption.

##### How secret rotation works

1. Rotate the secret: Generate a new secret for the client
Copy link
Contributor

@unatasha8 unatasha8 Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
1. Rotate the secret: Generate a new secret for the client
1. Generate a new secret for the client service

2. Both secrets work: Old and new secrets both authenticate until cleanup
Copy link
Contributor

@unatasha8 unatasha8 Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be #3 not #2. The new secret won't work until you update the client application, right?
Move position and change to: "Both old and new secrets authenticate until you remove the old secret."

3. Update services: Update your applications to use the new secret
Copy link
Contributor

@unatasha8 unatasha8 Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
3. Update services: Update your applications to use the new secret
3. Update your client services to use the new secret

4. Cleanup: Manually remove old rotated secrets once all services are updated
Copy link
Contributor

@unatasha8 unatasha8 Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
4. Cleanup: Manually remove old rotated secrets once all services are updated
4. After you test the client services can authenticate with the new secret, manually remove the old secret.


##### Rotate client secret
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
##### Rotate client secret
##### Rotate OAuth2 client secret


To rotate an OAuth2 client secret, use the following methods:

````mdx-code-block
<Tabs>
<TabItem value="rest" label="REST API">

```bash
curl -X POST https://{project.slug}.projects.oryapis.com/admin/clients/{client-id}/secret/rotate \
-H "Authorization: Bearer ory_pat_..."
```

The response includes the new `client_secret`. Save this value immediately - it will not be shown again.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where should this be saved? Is there a secure location it should be saved to?


See [API documentation](../../reference/api#tag/oAuth2/operation/rotateOAuth2ClientSecret).

</TabItem>
<TabItem value="sdk" label="Ory SDK">

```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)
```

</TabItem>
</Tabs>
````

##### Clear rotated secrets
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
##### Clear rotated secrets
##### Remove old secret


Once all services have been updated to use the new secret, you can remove the old rotated secrets to revoke access using the old
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Once all services have been updated to use the new secret, you can remove the old rotated secrets to revoke access using the old
Once all services are updated to use the new secret, remove the old secret to revoke access using the old

credentials:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
credentials:
secret:


````mdx-code-block
<Tabs>
<TabItem value="rest" label="REST API">

```bash
curl -X DELETE https://{project.slug}.projects.oryapis.com/admin/clients/{client-id}/secret/rotate \
-H "Authorization: Bearer ory_pat_..."
```

After cleanup, only the current secret will be valid. Old secrets will no longer authenticate.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
After cleanup, only the current secret will be valid. Old secrets will no longer authenticate.
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).

</TabItem>
<TabItem value="sdk" label="Ory SDK">

```typescript
await ory.deleteRotatedOAuth2ClientSecrets({
id: clientId
})

// Old secrets are now revoked
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Old secrets are now revoked
// Old secret is now revoked.

```

</TabItem>
</Tabs>
````

##### 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/secret/rotate" \
-H "Authorization: Bearer ory_pat_..." | jq -r '.client_secret')

echo "New secret: $NEW_SECRET"

# 3. Update your applications with the new secret
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# 3. Update your applications with the new secret
# 3. Update your client servcies with the new secret

# (Both old and 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 services are updated, clean up old secrets
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# 5. Once all services are updated, clean up old secrets
# 5. Once all client services are updated, remove the old secret

curl -X DELETE "https://{project.slug}.projects.oryapis.com/admin/clients/$CLIENT_ID/secret/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 clean up
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Secret rotation enables zero-downtime credential updates. Both the old and new secrets remain valid until you manually clean up
Secret rotation enables zero-downtime credential updates. Both the old and new secrets remain valid until you manually remove

the rotated secrets, allowing you to update all your services without service interruption.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
the rotated secrets, allowing you to update all your services without service interruption.
the old secret, allowing you to update all your client services without service interruption.


:::

:::warning Security best practice

Rotated secrets remain valid indefinitely until you explicitly clean them up. Always remove old rotated secrets once your
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Rotated secrets remain valid indefinitely until you explicitly clean them up. Always remove old rotated secrets once your
Secrets remain valid indefinitely until you explicitly remove them. Always remove old secrets once your

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"secrets remain valid indefinitely" Are you sure? Don't they have a validity date?

Deepak just added this feature: "The SAML connection includes a valid_to attribute, which is an array of expiry dates for the signing certificates associated". This might not directly link to your code as it's for SAML... but wanted to point it out to you.

migration is complete to ensure that compromised credentials cannot be used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
migration is complete to ensure that compromised credentials cannot be used.
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:
Expand Down
Loading