Rotate a leaked or compromised API key
Replace a leaked secret key or service_role key with a new secret key, then retire the compromised key so it stops granting access to your project. To learn what each key type can access, see API keys.
Prerequisites#
Fix the root cause of the leak before you rotate anything. Otherwise the new key can leak the same way. The OWASP Risk Rating Methodology helps you judge the severity of the incident and plan your next steps. If someone is actively using the leaked key, retire it right away with the steps in Retire the compromised key, even though components that still use it stop working until you replace it.
To follow the Management API path, you also need:
- A personal access token. If you use a scoped personal access token, it needs the API Keys permission with Read-write access. An OAuth application needs the
secrets:readandsecrets:writescopes. jq, to filter the responses.
If you use the Management API, set your project reference and access token in your terminal:
export PROJECT_REF="your-project-ref"export SUPABASE_ACCESS_TOKEN="your-personal-access-token"Create a new secret key#
Create a new secret key in the Settings > API Keys section of the Dashboard.
Replace the compromised key#
To move your application to the new key:
- Replace the compromised key with the new secret key everywhere your application uses it. If an Edge Function checks the key with
withSupabase({ auth: 'secret' }), it accepts only the secret key nameddefault. Update it to accept the new key by name, for exampleauth: 'secret:rotated_secret_key'. For details, see Service-to-service calls. If a Database Webhook orpg_netcall sends the legacyservice_rolekey on theAuthorization: Bearerheader, send the new secret key on theapikeyheader instead. For details, see Database Webhooks andpg_net. - If the compromised key is a legacy
service_rolekey, also replace the legacyanonkey with a publishable key in your browser and mobile clients. Retiring the compromised key deactivates both legacy keys. - Confirm that every component now uses the new key.
Retire the compromised key#
Unless someone is actively using the leaked key, wait until every component uses the new key before you start. Deleting a secret key can't be undone. If you find a client you missed after you deactivate the legacy keys, move it to a new key rather than re-enabling them, because re-enabling restores the compromised key.
In the Settings > API Keys section of the Dashboard, do one of the following:
- For a secret key, delete it.
- For a legacy
anonorservice_rolekey, deactivate the legacy keys.
If the compromised key is a legacy service_role key, also revoke the legacy JWT secret. The legacy keys are JWTs signed by that secret, so anything that still trusts the secret can accept the leaked key. To move to JWT signing keys and revoke the legacy secret, see Getting started in the JWT signing keys guide.
The compromised key no longer grants access to your project.