agents · identity · vercel

Agents Shouldn't Own Credentials

The agent can decide what to do next. That is exactly why authority should live somewhere else.

2026-08-22 · 7 min read

Give an agent a real job and the credential problem appears almost immediately.

We want a small agent that can take a public GitHub repository, inspect the code in an isolated environment, and return an architecture and risk briefing. It needs compute and a model. It does not need to become a vault.

Yet the default implementation often starts here:

OPENAI_API_KEY=...
GITHUB_TOKEN=...
DATABASE_URL=...

That is convenient for a demo. It is a poor default for software whose defining feature is that it can decide what to do next.

Useful agents need capabilities. They do not need to own the credentials behind those capabilities.

Credential ownership versus delegated capability

Deploy the experiment

Deploy the experiment →

The runnable example lives separately in SteveVezina/agent-snippets, so deploying the experiment does not clone the blog itself.

The example deliberately does one thing: paste a public GitHub repository URL and get a fast technical briefing.

There is no GitHub token because the repository is public. More importantly, the deployed application does not need an OpenAI or Anthropic provider key. Vercel AI Gateway supports OIDC tokens for applications deployed on Vercel, so the workload already has an identity it can use instead of another permanent API key.

The repository is inspected in Vercel Sandbox, an ephemeral Firecracker microVM intended for untrusted and AI-generated code. The model call and the untrusted repository therefore do not need to share one giant security context.

browser
  │
  ▼
Next.js route
  │
  ├── Vercel Sandbox ── clone + inspect public repo
  │
  └── AI Gateway ────── architecture + risk briefing
            ▲
            │
       Vercel OIDC

This is intentionally a small proof. The interesting part is the boundary it establishes.

The confused deputy problem, now with a reasoning loop

An agent is not merely an application with a nicer interface. It consumes instructions from users, retrieved documents, websites, repositories, tool results and other agents. Some of those inputs are untrusted, but they can influence the next action.

That makes ambient authority unusually dangerous.

If the same process that interprets untrusted content also holds a broad, long-lived token, a successful manipulation does not need to steal the credential first. It can try to convince the credential holder to use it. This is a modern version of the confused deputy problem: the attacker influences a more privileged actor into exercising authority on the attacker's behalf.

OWASP's current AI Agent Security guidance recommends minimum tool access, per-tool permission scoping, explicit authorization for sensitive operations, sandboxing and separation of decision-making from irreversible execution. Those controls all point in the same architectural direction: the model should not be the authorization boundary.

Prompt injection changes the credential threat model

Traditional secret management asks: Can an attacker read the secret?

Agent systems add another question: Can untrusted context cause the holder to misuse it?

OWASP's prompt-injection guidance treats external content as hostile and recommends least privilege plus action screening against the original user intent. Its secure-coding guidance goes further for coding agents: run them in isolated environments, keep production credentials out of those environments, and prefer ephemeral credentials scoped to the task.

This is why moving GITHUB_TOKEN from source code into a secret manager is necessary but incomplete. A vault improves custody. It does not reduce the token's authority after it is injected into a compromised runtime.

The better question is:

How little authority can exist inside the agent, for how little time?

Identity first, credential second

Cloud infrastructure has been moving in this direction for years. Workloads prove who they are, policy determines what they may do, and credentials are derived only when needed.

The useful abstraction is:

workload identity
      │
      ▼
authorization policy
      │
      ▼
short-lived capability
      │
      ▼
one bounded action

That is materially different from booting a process with a bag of secrets representing every action it might ever take.

Vercel's newer agent primitives make the distinction concrete. Vercel Connect lets a deployment prove its identity over OIDC and request short-lived credentials for services such as GitHub, Slack and Linear at runtime. The provider credential does not need to live permanently in the application's environment. Vercel's GitHub integration describes the same model as credentials on demand, bound to the projects and environments allowed to request them.

Google Cloud is converging on similar language, describing agents as first-class identities governed through IAM rather than treating them as applications that inherit a human's credentials. The implementation details differ, but the direction is consistent: identity and policy should precede credential issuance.

The .env should not be the trust model

As agents become useful, they accumulate access: source code, databases, issue trackers, cloud APIs, production telemetry, internal tools.

If every new capability becomes another permanent secret in the same runtime, we eventually combine three responsibilities in one place:

  • deciding what action to take
  • executing potentially untrusted work
  • holding the credentials that authorize the action

That is an uncomfortable security boundary.

A better decomposition is boring infrastructure:

  • Reasoning: decides what should happen
  • Execution: isolated sandbox with bounded network and filesystem access
  • Identity: cryptographic workload identity, not a copied developer credential
  • Authorization: deterministic policy outside the model
  • Credential exchange: short-lived token resolved when an action actually needs it
  • Approval: human confirmation for destructive or high-blast-radius actions
  • Audit: record the identity, requested capability and resulting action

The important property is not that secrets have disappeared from the universe. They have not. The property is that the autonomous workload does not become the long-lived owner of them.

Secretless is a direction, not magic

For this experiment, secretless means no long-lived model-provider credential is stored by the deployed agent application.

That is deliberately narrower than saying “there are no secrets.” OAuth providers, infrastructure platforms and credential brokers still manage sensitive material. Local development may still need a development credential. Some upstream APIs only support static keys.

The architecture improves when those limitations are pushed behind a broker or policy boundary rather than copied into every agent runtime.

Our public-repository constraint also intentionally avoids pretending we have solved GitHub authorization. The more interesting next version is a private repository through Vercel Connect, where GitHub access is requested at runtime for the right subject rather than supplied as a permanent GITHUB_TOKEN.

A practical authority ladder

Not every agent action deserves the same mechanism. I use this rough hierarchy:

LOWER RISK
│
├─ public data                 no credential
├─ internal read               scoped workload identity
├─ user data                   delegated user token
├─ reversible write           short-lived token + policy
├─ destructive / external     token + policy + approval
│
HIGHER RISK

The important design move is to make authority explicit at the point of action. An agent can have a broad reasoning horizon while retaining a narrow execution horizon.

What the demo still does not prove

The one-click example is intentionally honest about its limits.

It does not yet demonstrate delegated access to a private repository. It does not have an approval layer. It does not implement a credential broker for arbitrary SaaS providers. It also sends a bounded representation of repository content to a model, so repository data classification still matters.

Those are not reasons to hide the example. They are the roadmap.

The next useful experiment is to replace the public GitHub constraint with Vercel Connect + GitHub, then add a data system such as Supabase and show that each capability can be independently delegated, audited and revoked without turning the agent into a secret store.

The principle

Agent security will need prompt defenses, model evaluations and better guardrails. But authorization is infrastructure. We should solve it with infrastructure properties that do not depend on the model behaving perfectly.

A prompt can ask for authority. It should not grant authority.

A model can choose an action. It should not decide whether that action is permitted.

And an agent can be extremely capable without permanently possessing the credentials behind those capabilities.

Give agents narrowly delegated capabilities. Keep authority outside the loop.

Further reading