Quick answer: Claude Code is running in your repository with full file access, full shell access, and — unless you've thought about it — full access to every API key in your environment.
Most developers set it up with keys in .env or as shell environment variables, give it a spin, and move on. It works. And for a solo developer on a side project, that's probably fine.
But if you're using Claude Code seriously — on a production codebase, with real API keys, across a team — the default credential setup deserves a second look.
Quick answer
Claude Code reads API credentials from your environment by default: .env files, shell variables, and anything it encounters while reading project files. Those credentials are typically full-account keys with no scope boundary and no audit trail.
A better pattern: don't put credentials in the environment at all. Connect Claude Code to an MCP server that retrieves credentials at runtime, scoped to what the current task actually needs, with every access logged against Claude Code's agent identity. Revocation is then a single toggle rather than an emergency key rotation.
How Claude Code uses API credentials
When Claude Code starts a session, it inherits the environment of the shell it was launched from. That means:
- Any variable in your shell session (
STRIPE_SECRET_KEY,GITHUB_TOKEN,VERCEL_TOKEN) is in scope .envfiles in the project root are typically loaded automatically or by the tools it runs- Any file it reads during the session — including dotfiles and config files — can contain credentials it can then use
This is the same model as any other process launched from your terminal. There's nothing Claude Code-specific about it. The issue is that AI agents make a much wider range of tool calls than a deterministic script — and they do it in response to prompts that can contain unexpected instructions.
The risk: full-access keys with no scope boundary
The standard setup has three gaps:
No scope. A Stripe secret key gives access to the entire Stripe account — customers, payment methods, payouts, webhook endpoints, everything. Claude Code working on webhook configuration has the same permissions as Claude Code working on a refund — because the key doesn't know the difference.
No audit trail. When Claude Code makes an API call using credentials from the environment, there's no record that it was Claude Code that made that call. The Stripe dashboard shows a request came in. It doesn't show which agent made it, what task it was executing, or what the preceding prompt was.
No clean revocation. If you want to pull Claude Code's access to Stripe, you rotate the key. But that key is also used by your CI pipeline, your backend server, and your local dev setup. Rotating it to revoke one agent's access breaks everything else.
These aren't hypothetical risks. They're the same risks that exist for any system using shared, full-access credentials — AI agents just make them more visible because agents make more calls, more autonomously, in response to a wider range of inputs.
A better pattern: scoped credentials via MCP
Instead of credentials in the environment, Claude Code can retrieve credentials at runtime via MCP — the Model Context Protocol that Claude Code already supports natively.
The flow looks like this:
- Claude Code needs a Stripe credential to complete a task
- It calls
get_credentialon the MCP server rather than reading from the environment - The MCP server checks Claude Code's access policy — is this agent allowed to access Stripe?
- If yes, it returns the credential and logs the access against Claude Code's agent identity
- If no, it returns a structured error explaining what's allowed and what to do next
The credential never lives in the environment. Claude Code's access policy defines exactly which services it can reach. Every access is logged. Revoking access is a profile toggle — the underlying key is untouched.
Setting up Claude Code with Gazebo's MCP endpoint
Step 1: Create an agent profile in Gazebo
Go to Gazebo → Agents and create a new agent. Name it something specific — claude-code-stripe for a Claude Code session working on billing, claude-code-infra for one working on Cloudflare and Vercel. Specific names make the audit log readable.
Set the access policy: which services does this session need, and which HTTP methods? A session working on webhook configuration probably needs Stripe with POST and GET, but not DELETE.
Step 2: Add the MCP config to Claude Code
Claude Code reads MCP configuration from .claude/mcp.json in your project root (or your home directory for a global config). Add the Gazebo MCP endpoint:
{
"mcpServers": {
"gazebo": {
"url": "https://gazebohq.com/api/mcp",
"headers": {
"Authorization": "Bearer YOUR_AGENT_TOKEN"
}
}
}
}
Copy the bearer token from the agent profile you created. This token identifies Claude Code to Gazebo — it's how the access policy gets applied.
Step 3: Remove the credentials from your environment
The point of the MCP setup is that Claude Code retrieves credentials on demand rather than inheriting them. If STRIPE_SECRET_KEY is still in your shell session, Claude Code can still read it directly — bypassing the MCP layer entirely.
Remove service credentials from the environment for sessions where Claude Code is running via MCP. The credentials live in Gazebo's vault; Claude Code fetches what it needs, when it needs it.
Step 4: Verify with get_identity
Have Claude Code call get_identity at the start of the session. It returns the agent name and the full access policy — which services are allowed, which methods are permitted. This confirms the MCP connection is working and Claude Code is operating within the expected scope.
What you gain
Per-session audit logs. Every credential access is logged against the agent identity — which service, which method, when, whether it was allowed. If something unexpected happens, you know which agent accessed what and when.
Revocation without rotation. Pulling Claude Code's access is a profile toggle. The underlying Stripe key stays in the vault, untouched. Your backend server, CI pipeline, and other agents continue working.
Scope enforcement at the request level. Claude Code can only retrieve credentials for services in its access policy. A Claude Code session configured for Stripe can't accidentally retrieve your GitHub token — the MCP server rejects the request and logs the attempt.
Structured denial handling. If Claude Code hits a scope boundary, it gets a machine-readable error explaining what's allowed and what to do next. It can surface this to you clearly rather than failing silently or trying to work around it.
Caveats and limits
This setup protects against credential overreach and gives you audit visibility. It doesn't protect against a compromised or prompt-injected Claude Code session that knows it has Stripe access and misuses it within scope — that's where approval gates come in, and where you'd add human review steps to high-risk workflows.
It also requires that Claude Code actually uses the MCP layer rather than reading directly from the environment. The setup above removes credentials from the environment for that session — that's the critical step, not just adding the MCP config.
Team setups: per-developer vs. per-project profiles
When multiple developers use Claude Code on the same codebase, there are two ways to structure access profiles:
Per-developer profiles. Each developer has their own Gazebo profile with a unique bearer token. The audit log records which developer's Claude Code session made each credential request. This is the right model when developers work on different tasks and you need to attribute actions to individuals — for compliance, incident response, or debugging.
Per-project profiles. All developers working on a project share a profile and the same bearer token in their .claude/mcp.json. This simplifies credential management — one profile to update when scope changes — at the cost of per-developer auditability. Appropriate for small teams on a single project where individual attribution isn't a requirement.
In either case, production access should use its own profile, separate from development access. A Claude Code session with production Stripe or production database credentials is a different risk profile from one scoped to staging, and that difference should be reflected in a distinct profile with a distinct token. Developers shouldn't need to swap tokens mid-session — the right answer is separate profiles for separate environments.
Common mistakes after setup
Forgetting to remove credentials from the environment. The single most common mistake after adding the MCP config is leaving STRIPE_SECRET_KEY or other service keys in .env or the shell session. Claude Code reads the environment first — if the key is there, it never calls get_credential. The MCP setup looks correct (it is configured correctly), but Claude Code bypasses it entirely.
Using the same token across multiple developers. If two developers share a bearer token, the audit log can't distinguish between their sessions. This isn't a security problem on its own, but it eliminates the per-developer attribution that makes the log useful for debugging and incident response.
Not testing the permission denied case. Verify that Claude Code gets a clear, structured error when it tries to access a service outside its profile. A well-configured setup should surface "permission denied — Cloudflare not in access profile" as a readable message, not a cryptic network error. If the error handling isn't clear, Claude Code may try to work around the denial rather than surfacing it to you.
Further reading
- MCP security: what developers need to know — the credential risks that come with MCP tool exposure, and how scoped tokens change the picture
- Why pasting an API key into an agent prompt is riskier than it looks — the baseline risk model for credentials in AI contexts
- Gazebo agent setup — create an agent profile and get the MCP endpoint for Claude Code
Last reviewed: July 2026. Independent editorial — not affiliated with or endorsed by Anthropic. Claude Code is evolving rapidly — verify against Anthropic's current documentation for the latest on MCP configuration and permission model details.