Rotate Client Secret
To securely rotate the authentication secret value for a ClientApplication
, a special operation is provided that
ensures a secret with sufficient entropy is chosen, and that clients using the old secret do not immediately lose access.
[baseUrl]/ClientApplication/[id]/$rotate-secret
Privileged Operation
This operation is only available to Project Admins and Super Admins.
Parameters
Name | Type | Description | Required |
---|---|---|---|
secret | string | Rotate the primary secret, generating a new one and placing the old one into retiringSecret | No (see below) |
retiringSecret | string | Rotate the retiring secret, removing it from use | No |
Mutually Exclusive Parameters
One and only one of the secret
and retiringSecret
parameters must be provided, and must match the corresponding
value in the ClientApplication
.
Output
The operation returns the ClientApplication
resource with the updated secret value.
- If the
secret
is provided and matches the currentClientApplication.secret
, that value is copied intoClientApplication.retiringSecret
(overwriting any other value there), and a new secret is securely generated and placed intoClientApplication.secret
; both secrets can be used to grant application access - If the
retiringSecret
parameter is provided and matches the currentClientApplication.retiringSecret
value, theretiringSecret
is removed from the resource and can no longer be used to grant application access
Examples
Fully rotate client secret:
// First, rotate the initial secret
const rotatedClient: ClientApplication = await medplum.post(
medplum.fhirUrl('ClientApplication', clientApplication.id, '$rotate-secret'),
{
resourceType: 'Parameters',
parameter: [{ name: 'secret', valueString: clientApplication.secret }],
}
);
console.log('Client secret rotated; new secret is:', rotatedClient.secret);
console.log('Previous secret is still available for use:', rotatedClient.retiringSecret);
// At this point, existing application instances should be updated to use the new secret
// Once all use of the old (retiring) secret is resolved, rotate it out of service
await medplum.post(medplum.fhirUrl('ClientApplication', clientApplication.id, '$rotate-secret'), {
resourceType: 'Parameters',
parameter: [{ name: 'retiringSecret', valueString: rotatedClient.retiringSecret }],
});
// Now only the newly generated secret value will be valid