Security Basics
9 min
A leaked key is not a housekeeping task. If a Supabase service-role key, payment provider secret, deployment token or third-party API credential has reached a public repository, browser bundle, log file or unauthorised person, treat it as active exposure. Knowing how to rotate compromised keys quickly can be the difference between a contained incident and a database export, fraudulent charges or an attacker creating their own persistent access.
The goal is not merely to generate a new secret. A safe rotation removes the old credential, keeps essential services working, checks for misuse and fixes the route that exposed it. For a small team moving quickly, that sequence needs an owner, a deadline and evidence that it is complete.
First, contain the exposure before rotating anything
Start by recording what was exposed: the credential type, the affected provider or environment, where it appeared, when it was first committed or deployed, and who may have had access. This creates an incident record you can use when checking logs later. Do not paste the secret into tickets, chat messages or screenshots.
Next, assess whether the key is still usable. A key in a private repository can still be compromised if a contractor, former employee, CI integration or infected developer machine had access. A key embedded in client-side JavaScript should be assumed public, even if nobody has reported it. Front-end bundles are easy to inspect.
Remove public access to the secret where possible. Delete the exposed value from documentation, posts and active source files. If it is in a public Git repository, deleting a line in the latest commit does not erase it from commit history, forks, caches or clones. Rotation is therefore mandatory. History cleanup can reduce future discovery, but it is not a substitute for revoking the old credential.
Avoid the tempting shortcut of changing the secret in one dashboard and hoping the application catches up. An unplanned rotation can break checkout, background jobs, login callbacks and production deployments. Containment and continuity must happen together.
How to rotate compromised keys safely
The precise controls depend on the provider, but the operational pattern is consistent: identify every dependency, issue a replacement, deploy it securely, validate the change, then revoke the old value.
Map every place the old key is used
Search the repository, deployment settings, CI/CD configuration, worker configuration, local environment templates and infrastructure code. Search for the actual value if your tools permit it safely, but also search for the variable name, such as SUPABASE_SERVICE_ROLE_KEY, STRIPE_SECRET_KEY or OPENAI_API_KEY.
This step catches the failures that cause downtime after a rotation. A credential may be used by a production API, a preview deployment, a scheduled task and a GitHub Actions workflow. Replacing only the production environment variable leaves the next deployment or nightly job broken.
Separate keys by environment while you are there. Development, staging and production should not share a credential. If a development key leaks, it should not grant access to live customer data or production payment actions.
Generate a replacement with the right scope
Create a new key from the provider rather than reusing an existing secret. Where the provider supports it, choose the minimum permissions required and restrict the key to the required project, API endpoints, IP ranges or service account role.
Scope matters. A payment webhook signing secret has a narrow purpose. A cloud administrator token can alter infrastructure across an account. A Supabase service-role key bypasses row-level security and should never be delivered to a browser. If that key was exposed in front-end code, rotate it immediately and inspect the application architecture, not just the environment variables.
For signing keys, the process may differ. JWT signing secrets and OAuth client secrets can affect active sessions, callback flows and token verification. Some systems support multiple active signing keys through a key ID, allowing a controlled overlap. Others require invalidating sessions and forcing users to sign in again. The correct trade-off depends on the risk of the exposed key and the provider's capabilities.
Update secrets through the deployment path
Put the new value in the secret manager or deployment environment used by production. Do not commit it to .env, even temporarily, and do not send it through chat. Ensure local .env files are ignored by Git and that example environment files contain only variable names or safe placeholders.
Deploy the configuration change and restart the services that read secrets only on boot. Serverless functions may need a redeploy; long-running workers may need a controlled restart. For high-impact credentials, update a staging environment first if the exposure allows time. When a service-role key is publicly exposed, speed takes priority, but validation still matters.
Where a provider supports two valid secrets at once, use a short overlap period. Deploy the replacement, verify traffic is using it, then revoke the old one. Keep that overlap as short as practical. Every extra hour leaves the compromised key usable.
Validate the replacement before revocation
Test the critical path rather than relying on a successful deployment. For a SaaS product, that usually means signing in, loading an authorised record, creating a record, processing a test payment where appropriate, receiving a webhook and running a background job. Check application logs for authentication failures, provider errors and unexpected retry spikes.
Validation must include permissions. A replacement key with broader access than the original may keep the app running while creating a new security problem. Confirm that database requests still respect RLS for user-facing traffic, administrative actions are server-side only, and API routes enforce authorisation rather than trusting a client-supplied user ID.
Then revoke, disable or delete the compromised key at the provider. Do not leave it enabled as a fallback. Record the revocation time and preserve relevant logs before their retention window expires.
Investigate what the key may have allowed
Rotation stops continued use. It does not tell you whether the key was already used. Review provider audit logs, API request logs, database logs, cloud activity and deployment history from the likely exposure window through to revocation.
Look for unfamiliar IP addresses, unusual geographies, large reads, permission changes, new user accounts, unexpected token creation, webhook configuration changes, failed authentication bursts and spend anomalies. An attacker who obtains a cloud or database credential may first test access quietly, then create a new credential for later use.
The investigation should match the credential's authority. If a payment key was exposed, review charges, refunds, customer records and webhook endpoints. If an email provider key leaked, check outbound volume, templates and suppression lists. If a Supabase service-role key leaked, inspect direct data access and confirm RLS was not bypassed through a public endpoint.
If there is credible evidence of customer data access, preserve evidence and involve legal, privacy and incident-response advisers early. Notification obligations depend on the data involved, your customers and the jurisdictions affected. Do not make assumptions based solely on whether an attacker succeeded in changing data.
Fix the exposure path, not just the secret
Most repeat incidents begin with an avoidable workflow gap. AI-generated code can introduce environment variable names into client components, suggest server-side credentials in browser code or create an API route that proxies sensitive actions without enforcing authorisation. The code may look plausible and still expose a serious control failure.
Add secret scanning to pre-commit checks and CI, then configure repository secret alerts. Scan commit history after an incident, including branches that may not have reached production. Restrict production secret access to the people and systems that need it, use separate service accounts for separate workloads, and remove access promptly when roles change.
A short, tested key-rotation runbook is worth more than a policy nobody opens during an incident. It should identify credential owners, secret locations, required application tests, log sources and the person authorised to revoke production access. Run the process during a quiet period for non-emergency keys so the first real rotation is not an improvised one.
When rotation reveals a wider application problem
A leaked key sometimes exposes a deeper issue: a service credential in the front end, disabled RLS, an endpoint with IDOR, unsigned JWT acceptance or a CI token with unrestricted repository access. Replacing the value fixes the immediate exposure but leaves the same door open for the next secret.
That is the point to review the live application and repository together. HollowByte's audits combine automated secret and dependency checks with manual review of the routes, authorisation decisions and configuration mistakes that automated scanners often miss in AI-built applications. The useful output is not a vague warning. It is the affected file or setting, severity, business impact and exact fix.
Treat every compromised key as a test of your operational discipline. The right response is fast, measured and verifiable: stop access, replace the credential, prove the product still works, revoke the old value and remove the condition that made the leak possible.
Back to blog
