Skip to content
Open
138 changes: 138 additions & 0 deletions docs/hydra/guides/oauth2-clients.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,144 @@ 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 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
<Tabs>
<TabItem value="rest" label="REST API">

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

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

##### 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
<Tabs>
<TabItem value="rest" label="REST API">

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

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

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

// 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/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:
Expand Down
Loading