Skip to content

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:

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:

  1. 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 named default. Update it to accept the new key by name, for example auth: 'secret:rotated_secret_key'. For details, see Service-to-service calls. If a Database Webhook or pg_net call sends the legacy service_role key on the Authorization: Bearer header, send the new secret key on the apikey header instead. For details, see Database Webhooks and pg_net.
  2. If the compromised key is a legacy service_role key, also replace the legacy anon key with a publishable key in your browser and mobile clients. Retiring the compromised key deactivates both legacy keys.
  3. 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 anon or service_role key, 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.