Vercel Breach OAuth Supply Chain IBM Verify + Vault Agentic Runtime

When the AI Integration Becomes the Attack Vector
The Vercel Breach Was an Architecture Problem

Three hops, no zero-day. The Vercel breach started in an AI tool, pivoted through OAuth, and ended in plaintext environment variables. Every failure mode in the chain has a direct architectural counter.

Robert Graham Global Product Architect, IBM Verify · May 2026

00 Three Hops to Plaintext

On April 19, 2026, Vercel disclosed that an attacker had read non-sensitive environment variables out of a subset of customer projects. The follow-up reporting kept widening. Hundreds of accounts. Many organizations. AWS keys, Stripe keys, database credentials, signing keys, whatever a developer hadn't bothered to mark as sensitive in the dashboard.

The attacker did not exploit a Vercel zero-day. They did not exploit an Ivanti or Citrix appliance, did not chain a CVE through a perimeter device, and did not crack any cryptography. They walked across three trust boundaries that an enterprise Google Workspace, an OAuth grant, and a SaaS platform's environment variable model had quietly stitched together.

The Vercel attack chain: three hops from infostealer to plaintext environment variables

Hop one: a Context.ai employee got hit with Lumma Stealer in February 2026, reportedly from downloading game-exploit scripts. The infostealer harvested Google Workspace credentials, OAuth tokens, and keys for Supabase, Datadog, and Authkit. Two months of dwell time, undetected.

Hop two: a Vercel employee had previously signed up for a Context.ai product with their enterprise Google Workspace account and granted “Allow All” OAuth permissions. The attacker replayed the stolen OAuth token from their own infrastructure. MFA did not fire because OAuth bearer-token use is not gated by re-authentication, and the consuming app had no continuous-evaluation signal to act on.

Hop three: from inside a Vercel employee's Workspace, the attacker pivoted into Vercel itself, called GET /v9/projects/{idOrName}/env, and got back a JSON array. Variables not explicitly flagged as “sensitive” came back as plaintext.

The shape of the breach

An AI productivity tool was the initial vector. An OAuth grant was the bridge. A platform secret-storage model was the payout. None of those layers individually did anything obviously wrong. The architecture, in aggregate, did.

If you only remember one thing

Move the runtime boundary from the platform to the token. A secret that doesn't exist until a valid token mints it cannot be stolen by hijacking the identity that could have read it.

01 The .env Problem, Now Hosted

If you have read the earlier posts in this series, you know I have been beating one drum for months: secrets do not belong sitting at rest. Not in .env files, not baked into container images, not in deployment pipelines as build-time constants, and not in a SaaS platform's environment variable store. The Vercel breach is that pattern moved up one layer of abstraction.

It is worth being precise about what Vercel built and where the gaps actually sit, because the answer is not “the platform was negligent.” The Vercel environment variable model has two tiers. Variables marked sensitive are stored encrypted and cannot be read back through the API or the dashboard once saved; that is a real security control, and the implementation works as advertised. Variables not marked sensitive decrypt to plaintext on read by anyone with project access.

The two-tier design is a defensible product decision, not a flaw. Defaulting every variable to sensitive eliminates the readback path entirely, but it also means a developer cannot view the value to debug it, cannot rotate it by editing in place, and cannot export it cleanly for a local environment. Plaintext-by-default optimizes for developer velocity. Sensitive-by-default optimizes for blast radius. Reasonable platforms split this differently, and Vercel's pre-incident split sat within the industry's normal range. Post-incident, Vercel changed the default to sensitive, a reasonable response to learned data, not an admission that the original choice was indefensible.

The user configuration gap is a separate problem. Marking a variable sensitive is a checkbox, and humans miss boring security checkboxes: predictably and consistently, especially in preview-branch deployment flows where the cost of speed is lower than the cost of careful configuration. The breach exposed exactly the variables you would expect from that failure mode: the ones developers thought were “just config” until they were not.

Platform Boundary fallacy

Developers assumed that because the platform was secure, anything inside the dashboard was safe. The dashboard is not the boundary. The session cookie in the developer's browser is the boundary. The OAuth token granted to a third-party AI tool is the boundary. Once those move, “sensitive” vs “not sensitive” becomes a distinction the attacker enforces, not the platform.

The architectural critique is not that Vercel chose the wrong default or that developers were careless on a specific Tuesday. It is that the entire framing (pick your tradeoff between developer convenience and credential exposure) only exists because the credentials are sitting at rest in the first place. Move the credential out of rest entirely, mint it per request, scope it by token, and the tradeoff disappears. There is nothing to read back, sensitive or otherwise, because there is nothing stored.

02 Token-Scoped, Not Identity-Scoped

The architectural hinge of a working agentic runtime is this: the secret is scoped by the token, not by the user identity.

At Vercel, secrets were bound to the user or team identity. Hijack the user, get every secret bound to that user. Hijack the team, get every secret bound to that team. The blast radius of a compromised identity is everything that identity could ever read, because the credentials are sitting at rest waiting to be retrieved.

In a token-scoped runtime, the credential does not exist until it is asked for, and the request itself carries the intent. The agent presents an access token. The token carries authorization_details describing what is being attempted: the path of the secret being requested and the business operation being performed. The credential engine reads those routes from the token in a trusted way and uses them to determine the permissions on the dynamic secret it issues.

The architectural inversion

Secrets are not stored with permissions; they are minted with permissions, per request, derived from the token presented at the moment of issuance. Steal the user identity, get a session. Steal the session, get the ability to ask. The thing you want (the credential itself, scoped to the operation you intend) only comes into existence when the runtime mints it, and it is gone again when the lease expires.

What this would have meant for Vercel: the attacker would have hijacked the Workspace, pivoted into the Vercel account, and found nothing to read. The dashboard does not display the credentials. The API does not return them. There is no plaintext to enumerate.

Each downstream call would require minting a fresh credential bound to a specific intent, signed by a runtime the attacker does not control, and the runtime would not mint one because the attacker cannot present a valid intent.

03 Two Routes, One Token

The mechanism that makes token-scoped credentials work is “two routes, one token.” Every request the agent makes carries an authorization_details array (RFC 9396, Rich Authorization Requests) with two entries: a business route describing the operation, and a path route describing the secret being touched.

Concretely, when an agent asks the runtime to issue a credential for a banking transfer, the wrapper builds a fresh RAR array per request:

// Per-request RAR composed by the wrapper from the actual tool args
[
  {
    "type": "urn:smt:agent:banking",
    "operationDetails": { "action": "transfer_funds" },
    "instructedAmount": { "amount": 1000, "currency": "USD" }
  },
  {
    "type": "vault:path_access",
    "path_constraint": "verify-rar/creds/banking-transfers",
    "action": "update"
  }
]
RFC 9396 · authorization_details

The first entry is the business RAR: type urn:smt:agent:banking, action transfer_funds, the actual amount and currency the agent resolved from the user's prompt. The second entry is the path RAR: derived programmatically from the Vault path the wrapper is about to read. The wrapper knows it is about to hit verify-rar/creds/banking-transfers, so it appends a constraint for exactly that path.

Different tools build different shapes: a SCIM add_user_to_group call builds {type:"scim_group_update", groupId, userId}, an update_user builds something different again.

The wrapper posts the array to IBM Verify's Token Exchange endpoint with grant_type=urn:ietf:params:oauth:grant-type:token-exchange, the user's access token as subject_token, the workload's SPIFFE SVID as actor_token, and the JSON-encoded RAR array as authorization_details.

Verify mints an on-behalf-of token with a fresh jti and grant_id that ride with the RAR back to the runtime. Vault's plugin walks the array, pulls out the business RAR, matches type|action against a configured role mapping, and issues a credential scoped accordingly.

Why this matters here

Zero hardcoded RAR strings anywhere downstream. Every credential, every audit row, every Vault lease is a 1:1 fingerprint of this specific tool call by this specific user with these specific arguments. The attacker cannot replay because there is no static credential to replay. They cannot mint a new one because they cannot synthesize a valid business RAR from outside the agent runtime.

04 Where the Runtime Breaks the Chain

Map each failure mode in the Vercel attack chain against the corresponding control in a token-scoped agentic runtime, and the picture is uncomfortable for any platform that still stores secrets at rest:

Failure 01 · Plaintext at rest
Env vars sit on the platform
API key, DB credential, signing key: all decryptable to plaintext on read by anyone with the right session via GET /v9/projects/{idOrName}/env.
Control · Dynamic secrets
Mint on demand, lease, expire
Credentials issued at request time with a TTL lease and revoked when the lease ends. Nothing to read at rest.
HASHICORP VAULT · IBM VERIFY VAULT ENGINE PLUGIN
Failure 02 · OAuth replay
Token works forever once issued
Stolen OAuth token replayed from attacker infrastructure with no MFA prompt and no session re-evaluation.
Control · Continuous evaluation
Re-evaluate or revoke on signal
Anomalous geo, device posture change, or risk signal feeds CAEP (continuous access evaluation) and SSF (shared signals) streams. Tokens get stepped up or revoked mid-flight.
CAEP · SSF · IBM VERIFY SSF ANTENNA
Failure 03 · Coarse OAuth scopes
"Allow All" is the only choice
OAuth scopes describe categories of access, not transactional intent. Once granted, the token can do anything in scope.
Control · Rich authorization
Scoped per request, per intent
Every action carries explicit authorization_details (type, action, parameters) bound to a single transaction.
RFC 9396 · IBM VERIFY RAR · TOKEN EXCHANGE
Failure 04 · Identity-bound secrets
Hijack identity, get every secret
Credentials are bound to the user or team identity. Compromise the identity and the entire credential set is reachable.
Control · Token-scoped issuance
Secret bound to the request, not the user
Permissions on the issued credential are derived from the token's authorization_details, not the requester's identity profile.
RFC 8693 TOKEN EXCHANGE · RFC 9396 RAR
Failure 05 · No workload attestation
Anything with the token can use it
Tokens do not prove they are being presented by the workload they were issued to. Replay from an attacker laptop works.
Control · Cryptographic identity
Workload-bound, short-lived SVIDs
Every workload proves who it is via a SPIFFE (workload identity standard) SVID issued through node attestation. Replay from a different host fails attestation.
SPIFFE / SPIRE · ACTOR_TOKEN
Failure 06 · Audit blackout
Scoping was a forensic exercise
The platform logged reads but not the business intent behind them. Determining “what was actually accessed” took time and outside expertise.
Control · Per-call attribution
JTI + TXN + RAR fingerprint
Every credential issuance carries a unique jti, transaction id, and the RAR that authorized it. Audit join across systems is a key lookup, not an investigation.
IBM VERIFY · VAULT AUDIT · CAEP SET

Six failure modes in the breach. Six controls in the runtime. None of them are theoretical: every one is a working component of the agent security runtime IBM and HashiCorp shipped together. The architectural answer to a Vercel-class breach is not a better checkbox. It is a different secrets model entirely.

05 “Allow All” Is Not a Permission Model

The OAuth grant that the Vercel employee approved was the moment the trust boundary moved silently from the enterprise to a third-party AI tool. The grant said, in effect, this app can do anything I can do, indefinitely, until I revoke it, which I will not, because I will forget I installed it.

OAuth scopes describe categories of access. https://www.googleapis.com/auth/drive. https://www.googleapis.com/auth/gmail.readonly. They do not describe this specific action with these specific parameters at this specific moment. Once granted, the scope is the permission, and the permission lasts until the refresh token cycles or the user revokes the app.

RAR is the standard answer to this gap. Every action carries structured authorization_details describing the intent of the action. The token is no longer a generic capability; it is a transaction-bound assertion that the bearer is authorized to do this thing, with these arguments, right now. The credential issuance system can refuse to mint a credential when the RAR does not match what is being attempted.

Why most IDPs in market today cannot do this

Most consumer-focused IDPs that focus on SSO and human MFA cannot generate OAuth tokens granular enough for transactional context. They lack RAR support, lack actor + subject token semantics for delegation, and cannot prove on-behalf-of cleanly enough to satisfy compliance for what an agent did on behalf of a user. The standards are public. Production-grade implementations of all of them, in a single platform, are not common.

This is why the “why do I need both Verify and Vault” question gets answered with attribution and correlation, not with a feature checklist. Verify mints the OBO token carrying RAR. Vault honors the RAR when minting the credential. Both sides agree on the transaction id. Neither side can be replayed without the other.

06 The Granularity Reality Check

Token-scoped credentials are bounded by what the target system can enforce. This is worth saying out loud because the architectural ambition can outrun the downstream reality.

Postgres CRUD only
A database role can grant SELECT on a table or REVOKE on a column. It cannot enforce “this credential is only valid for the specific transaction transfer 1000 from account 107 to account 108.” The blast radius is shrunk by the lease TTL, not by the action itself.
Mainframe / fine-grained APIs Transactional
RACF and modern APIs that expose Authorization Detail Types can actually enforce the transactional intent. The credential issued is valid for that specific operation, with those specific parameters, and nothing else.

The honest framing for customers is that we shrink the blast radius everywhere, and we eliminate it on systems that support fine-grained authorization. The breach economics still change (a stolen Postgres credential with a 60-second TTL is a fundamentally different risk than one that lives in .env for 18 months), but the model does not pretend every target system is RACF.

07 Where VIP Would Have Caught This

Architecture solves the runtime side of the problem. Discovery solves the side everyone forgets: knowing the AI integration was even there in the first place.

The Vercel breach has at least four discovery surfaces that the IBM and HashiCorp partnership illuminates without deploying another agent on the endpoint or in the browser. IBM Verify Identity Protection (VIP) covers the identity fabric. HashiCorp Vault Radar covers code and configuration. Together they give a security team coverage on both sides of the secret lifecycle, identity exposure on one console and code/config exposure on the other:

DISCOVERY 01
Shadow AI tooling
The Context.ai browser extension was installed by a Vercel employee and connected to enterprise Google Workspace via OAuth. VIP discovers unsanctioned AI integrations across the identity fabric.
AGENTLESS · NO ENDPOINT INSTALL
DISCOVERY 02
OAuth grant inventory
An “Allow All” consent on an enterprise account is exactly the broad-scope OAuth grant VIP surfaces as a risk. Most organizations have hundreds of these and no inventory of them.
CROSS-IDP · CONSENT VISIBILITY
DISCOVERY 03
Vault Radar secret discovery
HashiCorp Vault Radar scans code repositories, CI/CD pipelines, and SaaS configurations for plaintext credentials. The Vercel scenario, where API keys and database credentials sit decryptable in the platform, is the textbook case. Radar surfaces the exposure on the code and config side; VIP carries the identity-side context for the same user or workload.
VAULT RADAR · CODE & CONFIG
DISCOVERY 04
Behavioral anomaly
Token replay from new geography, unusual API surface enumeration, off-hours session activity. These are the patterns that drive the CAEP signals into the runtime so it can revoke or step up.
CAEP / SSF · CONTINUOUS

The VIP differentiator is method. Most discovery tooling depends on browser agents, endpoint sensors, or vendor-supplied APIs that ask the AI vendor “tell me which agents the customer has.” VIP does not need any of that. It infers from the identity fabric (the OAuth grants, the directory traffic, the anomalies in user-to-app behavior) what is actually running and where it sits in the trust topology.

The before-during-after

Before: VIP would have flagged the Context.ai OAuth grant as a broad-scope consent on an enterprise account, the kind of finding that lands in the weekly identity risk review. During: VIP would have raised the OAuth replay anomaly into the CAEP stream the moment the stolen token was used from new infrastructure. After: Vault Radar's code and configuration scan would have surfaced the plaintext environment variables across the SaaS portfolio, giving the security team a defensible scope for the rotation work and a clear picture of which secrets actually needed to be replaced.

08 Attribution Is the Differentiator

When Vercel engaged Mandiant, the hard part was not finding the attacker's footprints; that work happened. The hard part was scoping what was actually accessed. Which secrets? On behalf of which user? For which downstream system? The platform logged the reads. It did not log the intent behind them, because there was no intent to log; the secrets were just sitting there to be read.

In a token-scoped runtime, every credential issuance has a 1:1 fingerprint:

Audit join across systems becomes a key lookup. Show me every credential issued in the last 24 hours that carried a banking-transfer RAR for amounts over $10,000, by which user, with which agent, against which Vault path. That query runs in seconds because the identifiers ride together through every layer.

Compliance reframed

Customers cannot prove compliance for what an agent did on behalf of a user without delegation semantics that survive audit. Most IDPs cannot generate that. The identity story for agentic AI is not “can you SSO me into the AI tool.” It is “can you produce a defensible audit trail for every action the AI tool took, with the user it acted for, the policy that allowed it, and the credential that was used.”

09 The Pattern Is Industry-Wide

Vercel is not the first platform to lose customer credentials this way, and it will not be the last. The pattern repeats because the architecture repeats:

2021 · Apr
Codecov Bash Uploader. Modified script in CI/CD pipelines exfiltrated environment variables for roughly two months before disclosure. Reuters reported the customer base potentially exposed at up to 29,000 organizations including Twitch, HashiCorp, and Confluent.
2023 · Jan
CircleCI. SSO session token stolen via malware on an employee's personal device. Used to access internal CircleCI systems and exfiltrate customer secrets and encryption keys.
2025 · Aug
Salesloft Drift. OAuth tokens for the Drift integration stolen from Salesloft's environment, then used between Aug 8–18 to access Salesforce instances of roughly 700 organizations. UNC6395 (GTIG attribution).
2026 · Mar
LiteLLM, Axios. PyPI and npm package compromises within days of each other. Credential-stealing payloads in trusted packages downloaded millions of times per week. TeamPCP / UNC1069 attributed.
2026 · Apr
Vercel. OAuth pivot from Context.ai through Google Workspace into the platform's environment variable store. Plaintext secrets exfiltrated for hundreds of customer accounts.

Each one of these is a platform that stored customer credentials at rest, was breached through identity rather than infrastructure, and had to ask its customers to rotate everything afterward. The defense pattern that actually works against this class of attack is architectural: stop storing the credentials at rest, mint them per request, scope them by token, and bind them to the workload that issued the request.

That is not a Vercel-specific solution. It is the industry-wide answer to an industry-wide failure mode.


The breach didn't need a zero-day.
It needed a checkbox and a stolen cookie.

IBM Verify and HashiCorp Vault ship this architecture today.

Architecture is the only durable answer.

Read the Architecture
Secretless by Design — Zero-Trust Agentic AI on AWS EC2
The full technical walkthrough of the agent security runtime: SPIFFE workload attestation, IBM Verify Vault Engine Plugin, CAEP warning escalation, Token Exchange, and RAR policy enforcement.
Read the Problem Statement
The Weakest Link — Agentic AI Agents
Why agentic AI agents are the new weakest link in enterprise security, and what a zero-trust agent architecture looks like.
Read the Field Notes
"So You Have a Dashboard?" — RSAC 2026 Field Notes
RSAC 2026 was full of dashboards. We showed a working agent security runtime. Here's what the floor actually looked like.