Rotating Secrets After a Supply Chain Attack: A Practical Guide

Rotating Secrets After a Supply Chain Attack: A Practical Guide

pr0h0
securitysupply-chainsecretsincident-response
AI Usage (90%)

The Vercel incident is a useful reminder that deleting a project is not a cleanup plan. If an attacker can read env vars, touch a developer account, or pivot through a third-party OAuth app, you should assume some secrets are already burned.

What the Vercel incident changed for secret handling

The key detail in Vercel's bulletin is not just that an internal system was accessed. The attacker reached a point where they could enumerate and decrypt non-sensitive environment variables, and those values included things like API keys, tokens, database credentials, and signing keys.

That changes how you respond.

A lot of teams treat env vars as safe enough because they are not committed to Git. After an incident like this, the better assumption is simpler: if a secret lived in a place the attacker could read, rotate it.

Start by assuming non-sensitive values are exposed

Why environment variables are not all equal

Vercel called out non-sensitive environment variables as the first impacted set. That wording matters. Some systems store secrets with stronger protection, but many teams still keep valuable credentials in plain environment variables because it is convenient.

A rule I use:

  • public config can stay as-is
  • shared credentials need review
  • anything that grants access gets rotated

That means database passwords, third-party API keys, JWT signing secrets, webhook secrets, and private OAuth client secrets should be treated as exposed unless you can prove otherwise.

Why deleting a project does not revoke access

Deleting a project removes a deployment target. It does not invalidate:

  • a database password already copied out
  • a token used by CI
  • an OAuth refresh token
  • a signing key embedded in app code or runtime config
  • a deployment protection token

If the attacker already has the credential, removing the project does not make the credential stop working.

⚠️

Rotation has to happen at the source system, not just inside Vercel or your hosting provider.

Build a rotation order that matches real blast radius

Inventory secrets by system impact

Start with a list, not random changes. I split secrets into three groups:

GroupExamplesImpact if abused
IdentitySSO, OAuth, admin tokensAccount takeover
Data accessDB creds, storage keysRead/write production data
Trust and signingJWT secrets, webhook signing keysForgery, impersonation

If you have a secret inventory, use it. If you do not, pull from your deployment dashboard, CI variables, and app configs.

Rotate API keys, database credentials, and signing keys first

These are the credentials that usually turn a config leak into a real incident.

My usual order is:

  1. database credentials
  2. signing keys
  3. cloud and third-party API keys
  4. webhook secrets
  5. less privileged service tokens

If a key is shared across environments, separate that next. Shared secrets turn one compromise into a wider outage.

Replace tokens used by deployment protection and automation

Vercel also recommends rotating Deployment Protection tokens. That is easy to miss because people treat them as platform plumbing, not as credentials.

Do the same for:

  • CI/CD deploy tokens
  • preview environment tokens
  • release automation credentials
  • bot accounts that can publish or approve deployments

If a token can push code or unlock environments, it belongs near the front of the queue.

Check access paths that outlive the initial compromise

OAuth apps and Google Workspace access

The incident reportedly started with a compromised third-party AI tool and an OAuth app used in Google Workspace. That is the kind of path that survives normal app cleanup.

Check:

  • connected OAuth apps
  • granted Workspace app permissions
  • admin consent logs
  • refresh tokens for SSO-connected tools

If a tool should not still have access, revoke it explicitly.

Activity logs and suspicious deployments

Review your activity logs for:

  • new logins from unusual locations
  • secret reads
  • env var exports
  • unexpected deploys
  • config changes outside normal release windows

If the platform gives you CLI access to logs, use it. UI review alone is too slow when you are trying to reconstruct scope.

Third-party tools and shared admin accounts

Shared admin accounts are a quiet risk here. If one person's account was compromised through a third-party app, the attacker may inherit more than that person's workstation access.

Check:

  • password managers with broad team access
  • shared support accounts
  • vendor consoles
  • SaaS integrations with workspace-wide access

A practical rotation workflow you can run this week

Freeze risky changes and capture evidence

Before rotating anything, freeze non-essential deploys and note what you found:

  • affected accounts
  • exposed secret classes
  • last known good deploys
  • suspicious activity timestamps

That helps if a rotated key breaks a production path.

Rotate in a safe order with rollback notes

Use one owner per system and write down the rollback path before changing credentials.

rotation-checklist.js
const rotationPlan = [
"database password",
"JWT signing secret",
"webhook signing secret",
"external API keys",
"deployment tokens"
];

for (const item of rotationPlan) {
console.log("rotate:", item);
console.log("verify:", "old credential no longer works");
console.log("rollback:", "documented before change");
}

Verify old credentials are truly dead

Do not stop at “new secret is deployed.” Test that the old one fails:

  • old API key returns 401 or 403
  • old DB password cannot connect
  • old signing key fails verification
  • revoked OAuth app no longer appears in account grants

If the old credential still works anywhere, the rotation is incomplete.

Hardening steps that reduce the next incident

Enforce MFA and passkeys

Vercel explicitly recommended MFA, authenticator apps, and passkeys. That is not generic advice here; it cuts off the account takeover path that often follows a third-party compromise.

Use sensitive secret storage where available

If your platform has a “sensitive secret” mode, use it for values that should never be readable in plaintext through the dashboard or logs.

That does not remove the need to rotate. It just narrows future exposure.

Tighten deployment protection and review defaults

Set deployment protection to a real baseline, review who can approve it, and remove stale tokens. Defaults are usually optimized for convenience, not incident response.

What to tell engineers after the cleanup

Be blunt:

  • a secret in env vars is still a secret
  • a deleted project does not revoke credentials
  • third-party OAuth access is part of your attack surface
  • deployment tokens need the same treatment as API keys

The practical lesson from this incident is simple. When access is uncertain, assume the credential is compromised, rotate it at the source, and verify the old path is closed.

Conclusion

If you were touched by a supply-chain or identity-chain incident like this, do not try to “clean up” by deleting resources first. Inventory the secrets, rotate by blast radius, revoke stale OAuth and admin access, and confirm the old credentials are dead. That is the work that actually shrinks the blast radius.

Share this post

More posts

Comments