Autonomous Security
Stop Giving AI Agents Direct Access to Secrets
September 10, 2026
Ariel Shiftan

Stop Giving AI Agents Direct Access to Secrets

agentsgatewayssecrets

Many useful AI agents need access to sensitive systems. A coding agent needs GitHub. A support agent needs Slack or Salesforce. An operations agent may need a production database or cloud API. To reach those systems, the agent needs authentication, which usually means giving it access to a credential somewhere.

The natural answer is to use the security tools we already trust: environment variables, secrets managers, password vaults, OAuth, or configuration files that keep credentials outside the prompt. Those tools solve an important problem: where should the secret live?

AI agents introduce another one: what happens once the agent can use it?

For agents, the stronger security principle is simple: give agents access to the actions they need, not the credentials behind them. An agent should be able to open a pull request, query a database, or post a message without receiving the GitHub token, database password, or API key that makes the action possible.

Protecting a credential at rest and controlling how an autonomous system uses it are two different problems.

If the agent can access the secret, the agent is inside the trust boundary

An AI agent does not operate like traditional application code. Its next action can depend on a README from a dependency, the contents of a support ticket, a web page it fetched, output from another tool, or instructions embedded inside a repository. Some of that input is trusted. Some of it is not. The model interprets all of it and decides what to do next.

If the agent can retrieve a credential, then a model driven system whose actions are influenced by untrusted input has access to that credential.

The obvious risk is exposure. If the agent prints a secret into its context, the value may also end up in session transcripts, conversation history, summaries, debugging output, telemetry, or observability systems, depending on how the agent is deployed.

But the secret does not have to appear in the prompt for the underlying problem to exist. Consider an environment variable:

curl -H "Authorization: Bearer $TOKEN" https://api.example.com

The shell expands $TOKEN, so the model never needs to see its actual value. That is a reasonable way to reduce exposure.

Now consider what happens when the request fails with a 401. The same agent can run:

echo $TOKEN

It may do that because of prompt injection, a bad plan, or simply because it is debugging the failure exactly the way a developer would.

The problem is not that a safe way to use the credential does not exist. The problem is that the agent gets to choose whether to take the safe path. If the agent never has access to the credential, that choice disappears.

Direct access also gives the agent everything the credential permits. Suppose an agent only needs to read information from a production database, but the database credential available to it can also modify or delete data. The agent's task says "read customer 123." The database sees a credential that says "you can access this database." It evaluates the credential, not the reason the agent made the call.

Where a system supports a genuinely narrow credential, use it. A read only database user is clearly better than an administrative one. The challenge is maintaining that level of isolation across every agent, user, task, tool, and target system.

The same issue appears with identity. Imagine twelve agents using the same service account. Your secrets manager records that the account retrieved a credential at 03:14. The destination records that the same account performed an action at 03:16. Which agent did it? Which user initiated it? Was the action part of the task it was supposed to perform?

Having logs is not the same as having useful attribution, especially for unattended agents where one credential retrieval may support hundreds of later operations.

A secrets manager sees the fetch. It is usually not in the path of every subsequent API call.

Retrieval and use are different security events.

undefined

How the common approaches compare

There is no single way organizations give credentials to agents today. Some approaches are obviously dangerous. Others provide strong security properties and are entirely reasonable in the right environment. The important question is where each approach places the security boundary and whether the agent itself can ultimately reach the credential.

Approach What it gives you Where it breaks Works unattended

The tool's own login

gh auth, IDE sign in

The application or client can hold the token instead of exposing it directly to the model. The target sees a real user identity, and there may be nothing additional for the agent to store or rotate. The agent may inherit most or all of the human user's permissions. Its actions may also appear under that user's identity, making it harder to distinguish between something the person did and something their agent did. Revoking one agent without affecting the user can also be difficult. After setup
Hard coded in a skill or prompt Almost no setup. It works immediately and is easy for the agent to consume. The credential is directly available to the model. Skills and prompts are frequently copied, shared, committed, and reused. The secret can also enter transcripts and other systems that process the agent's context. There is no meaningful security boundary between the model and the credential. Yes

MCP client config

mcp.json

The MCP client can attach the credential to requests, so the agent does not normally need to read the secret itself. This is meaningfully better than putting the value directly into a prompt. The credential still exists in the local environment and may remain accessible to the agent or tools it can invoke, depending on the client's isolation model. Project scoped configuration can also be committed accidentally, and one file may hold credentials for several servers. "The agent does not need to read it" is not the same as "the agent cannot read it." Yes
Environment variable Universal, easy to automate, and compatible with almost every existing tool. The value can be consumed by a subprocess without ever being printed into model context. The credential is available inside the process environment. Child processes may inherit it, other processes with sufficient local access may be able to inspect it, and debugging or verbose errors can expose it. If the agent can invoke a shell with that variable in scope, it can usually print or copy it too. Yes

Cloud secrets manager

AWS Secrets Manager, GCP Secret Manager, Azure Key Vault

Strong protection at rest, centralized access control, rotation, and retrieval auditing. Once the plaintext credential is returned to the agent or its environment, the secrets manager is no longer involved in every subsequent use. The identity allowed to retrieve secrets may also have access to more secrets or resources than the current task requires. Retrieval logs show that a secret was fetched, but not necessarily every action performed with it afterward. Yes

Password manager

1Password and similar tools

Strong protection at rest. Interactive retrieval can be tied closely to a real human using device authentication or biometrics. Human authentication does not translate cleanly to unattended agents. Automation usually requires a service or machine identity. Once the credential is released into an environment the agent can access, the same post retrieval problem remains. Partly
MCP built in OAuth One of the strongest options when supported. The MCP client can hold and refresh the token without exposing its value to the model. Authorization can be tied to a real user and scoped to a particular MCP server. The target continues to enforce its existing permissions. It depends on the target supporting the appropriate OAuth flow and usually requires an initial authorization step. The available scopes are also defined by the target. That may establish that a user can access a service without letting you express a narrower rule for what this specific agent may do. Central policy and auditing across many services require another layer. After authorization
MCP / API gateway The destination credential stays outside the agent. The agent authenticates to an MCP or API gateway, which performs or forwards the authorized request. It introduces infrastructure that must itself be secured and operated. It also governs only traffic that passes through it. Local shell commands, direct filesystem access, and credentials already present elsewhere on the machine remain outside that boundary. Yes

What the table tells us

The approaches above improve different parts of the problem. Moving a credential out of a prompt and into an environment variable is an improvement. Moving it into a secrets manager provides a much stronger storage boundary. OAuth can go further and keep the credential out of the agent's reach altogether.

The important dividing line is whether the agent can ultimately obtain the credential or the agent can perform the required action without receiving it.

That distinction is architectural. A credential still needs to live somewhere secure, whether that is a secrets manager, vault, OAuth client, or another trusted service. The question is which side of that boundary the agent sits on.

If the credential is delivered to an environment the agent controls, policy ends largely at retrieval. If the credential remains behind another component, that component can participate every time the agent tries to use the capability.

That gives you something storage alone cannot: a place to make a decision at the time of the action.

Keep the credential behind the action

OAuth already demonstrates this model well. The client can hold and refresh a token while the agent simply uses the authorized service. The model does not need the token itself.

But the target's authorization model and the permissions you want for an agent are not always the same thing. A developer might be an administrator of a GitHub organization while their coding agent only needs to read repositories, create branches, and open pull requests. You may not want that agent changing branch protection, modifying organization settings, or deleting repositories simply because the underlying user can.

For systems without suitable native delegation, or when you need more granular agent specific policy, the same principle can be implemented through an MCP or API gateway. Instead of giving the agent a database password, expose the database operations it is allowed to request. Instead of handing it a GitHub token, expose the GitHub actions it is permitted to perform.

The gateway holds or obtains the destination credential. The agent does not.

Because the gateway is in the call path, it can make decisions using the actual request: which agent is acting, on whose behalf, which tool it wants to call, what system it is reaching, and what arguments it supplied. It can allow or block the operation and record what actually happened.

This does not govern everything the agent can do. An MCP or API gateway only sees traffic that passes through it, so local files, shell execution, or credentials already available on the endpoint remain separate security surfaces. But for systems that can be placed behind this boundary, the agent no longer needs direct access to their secrets.

Ask whether the agent needs the secret at all

Security teams have spent years getting better at answering: where should this credential be stored? That question still matters.

For AI agents, there is now another question worth asking first: does the agent need access to the credential at all?

If it only needs to perform an action, give it a controlled way to request that action while the credential stays outside its reach. Apply identity and policy when the request is made, and audit what the agent actually did.

Give agents access to the actions they need, not the credentials behind them.

Last updated: September 11, 2026
Back to Blog