BeyondCorp in the age of AI agents
BeyondCorp removed implicit trust from the network. AI agents require the same decision for delegated authority, tool calls, runtime identity, and every side effect.
- Published
- Reading time
- 17 min read
In February 2021, I gave a client presentation about BeyondCorp and zero trust. One slide showed a person, an identified device, multi-factor authentication, an access proxy, a policy engine, and a service. The policy engine decided whether one request could pass.
I still like that diagram. It refuses to call a corporate network trusted. An office address or a VPN connection may contribute evidence, but neither proves who is asking, whether the device is healthy, or whether the requested access makes sense.
My daily work now includes another requester. I give coding agents a goal and let them inspect a repository, edit files, run commands, and react to failures. Other agents read inboxes, update tickets, query customer systems, or reach APIs through the Model Context Protocol. One instruction from a person can produce dozens of calls before the agent returns.
The 2021 diagram did not cover that chain. Its person chose the action and its proxy evaluated the resulting request. An agent chooses intermediate actions. It mixes my instruction with source files, issue text, web pages, tool descriptions, and earlier command output. Some of those inputs are trustworthy. Some are merely necessary to read.
BeyondCorp still gives me the right starting point. An agent gets no authority because it runs on my laptop, sits behind a VPN, or works near my authenticated browser. Access must follow from the person, the delegated task, the runtime making the call, and the exact operation requested.
The proxy still has the right job
Google’s first BeyondCorp paper removed the privileged corporate network from the access model. Its migration paper described the less glamorous work behind that decision. Applications had to sit behind access proxies. User records, group membership, device inventory, certificates, and service policy had to become dependable enough for access decisions.
NIST SP 800-207 gives a compact definition. Zero trust grants no implicit trust based only on physical location, network location, or asset ownership. It protects resources instead of network segments and evaluates the subject and device before establishing access.
An agent inside a private cloud therefore deserves no automatic access to another private service. A local process does not become safe because an employee launched it. The inverse holds too. A hosted runtime does not become unacceptable solely because it is outside the corporate network. Location is evidence, not the verdict.
NIST extended the model to application traffic in SP 800-207A. Cloud applications need service and workload identities alongside human identities. API gateways, proxies, and workload identity systems enforce policy even when applications move among clouds and data centers.
Agents fit that application model better than the old employee model. The process calling a tool is a workload. The person supplies authority, but does not make every request personally. A proxy or tool gateway still has the same job it had in 2021: evaluate the caller, context, operation, and resource before allowing access.
Do not call the agent the user
A log entry that says “Lukas called the deployment API” loses the part I care about. Did I run the command? Did I approve one proposed deployment? Did an agent reuse my token after a different task wandered into deployment work?
“The AI did it” is equally poor. A model does not usually hold the credential or open the network connection. The controlled runtime around it does. Two runtimes can use the same model under entirely different conditions. One has a read-only repository mount and no network. The other inherits a home directory full of cloud credentials and SSH keys. Recording the model name alone hides the difference.
I want an access decision to distinguish at least four facts:
- The person or business process that initiated the work.
- The agent runtime that holds credentials and calls tools.
- The task grant that defines the delegated work.
- The target resource and operation.
Model name, version, prompt configuration, and tool catalog belong in provenance. They help reproduce behavior and investigate failures. I would not use a model name as a security principal. Providers update models, requests can route among deployments, and one model serves many unrelated users.
NIST’s February 2026 concept paper on software-agent identity and authorization frames agent identity as unfinished work. It asks for practical input on identification, authorization, auditing, non-repudiation, and prompt-injection controls. It does not announce a finished identity standard.
I do not think every model invocation needs a new enterprise account. A stable workload identity for the controlled runtime is enough to enforce access. The request must carry the person and task context beside that identity, otherwise the service sees a bot account with no explanation for its current authority.
A task needs less authority than its owner
Giving an agent the user’s token is tempting. OAuth already works, the APIs already accept it, and the agent stops asking for access. It also means that a narrow task inherits every permission accumulated by the person.
Suppose I ask an agent to update one dependency. It needs one repository, one branch, package-registry reads, and the commands required to test the change. My ability to deploy production or read another client’s repository has no place in that task.
A support-summary agent offers a similar example. It may read selected ticket bodies and customer names. It does not need permission to send replies, export every account, or retain a mail token after the report is complete.
The person’s access sets the ceiling. The task grant should be much smaller. A grant can identify resources, operations, expiry, allowed network destinations, data classifications, spending limits, and actions that require approval. The runtime presents it when asking for a tool credential or calling the tool gateway.
The grant also gives an administrator something concrete to revoke. Removing a sentence from a prompt does not invalidate a token already copied into a process environment. Revoking a task grant does.
Starting narrow creates interruptions when the plan changes. I prefer that cost to handing every new agent the authority of its operator. If the dependency update discovers that a lockfile generator lives in a second repository, the agent can request access to that repository. The request names the missing operation. A person or policy can judge it without approving an open-ended scope at startup.
A prompt cannot enforce access
Repository instructions help my coding agents. They tell the agent where tests live, which commands are safe, and which files should remain untouched. I described that practice in How I supervise parallel coding agents from tmux.
Those instructions share a context with text the agent did not choose. An issue can contain a command. A source comment can ask its reader to upload a configuration file. A web page can claim that a previous rule no longer applies. A tool result can imitate a system message. The model must read these strings to do its job.
A hierarchy of prompts helps the model choose among conflicting instructions. It does not create an operating-system boundary. If the process can read a secret and send an arbitrary network request, a sentence saying “never reveal secrets” is the last control before disclosure.
I want the controls outside that context. Do not mount secrets that the task does not need. Restrict writes to the working tree. Limit outbound connections to known package registries and tool endpoints. Issue credentials for one resource. Reject disallowed operations at the server.
The same rule already applies to application interfaces. In Permissions belong in queries, not only menus, I argued that hiding an item in a menu does not protect its data. The query must enforce the user’s scope. Agent instructions are the menu. The tool and resource policy are the query.
This separation also makes failures easier to understand. A policy denial says which operation exceeded the grant. A model refusal only says what the model decided after interpreting its current context. The former is repeatable and testable. The latter can change with wording or model version.
MCP gets the token boundary right
The MCP authorization specification treats a protected MCP server as an OAuth resource server. The client asks for a token intended for that server. The server validates the audience and receives authorization on every HTTP request.
The specification forbids token passthrough. An MCP server that calls a downstream API obtains a separate token for that API instead of forwarding the token it received from the client. This preserves the audience boundary. It also lets the downstream service identify the intermediary and apply its own rules.
Without that separation, one bearer token travels through the entire agent chain. Any component that logs, leaks, or misuses it exposes every service willing to accept it. Logs become ambiguous because downstream calls appear to come directly from the original user.
The MCP security guide covers the failure modes in more detail. It warns about confused deputies, tokens accepted by the wrong audience, state-handle theft, and broad wildcard scopes. It recommends narrow initial scopes and step-up authorization when an operation first needs more access.
MCP supplies protocol machinery, not business authorization. A token with issues:write does not prove that this task should close issue 123. The MCP server must still check the requested operation, arguments, resource state, and local policy.
There is deliberately no trusted-agent box in the diagram. The runtime has an identity and a grant. Neither guarantees access. The gateway evaluates one operation, and the resource keeps its own enforcement.
Device posture becomes execution state
BeyondCorp considers device state because two requests from the same person can carry different risk. A managed, patched laptop with a valid certificate is not the same as an unknown browser on an unmanaged machine.
An agent runtime also has inspectable state. Policy may need to know which tools are enabled, which directories are mounted, whether the filesystem is disposable, which network routes exist, how credentials entered the process, and which source revision the agent is changing. A hosted runtime may present workload attestation instead of a laptop certificate.
These facts affect the operation directly. A code-review agent with a read-only checkout may inspect a production repository. Giving the same runtime a shell, package installation, arbitrary egress, and a deployment token changes the decision even if the human and model stay the same.
Execution state can change midway through a task. Installing a package introduces code. Connecting a new MCP server adds tools and another authorization path. Moving from reading a Terraform plan to applying it changes a reversible inspection into a production mutation. Policy should evaluate those transitions rather than treating the login at the beginning as approval for the rest of the run.
The check need not interrupt every read. A runtime can keep a standing read grant while its state satisfies policy. A changed tool set, expired grant, new data class, or write operation triggers a new decision.
Approval belongs next to the side effect
“Human in the loop” says nothing about what the human sees. A button labeled Allow may approve one message, an entire mailbox, or every future tool call. The interface has to name the transaction.
For a deployment, I want the environment, revision, plan result, and credential scope. For an email, I want recipients, subject, attachments, and final body. For a destructive database action, I want the selected records and recovery path. Approval should expire if those facts change.
High-impact actions include external communication, payments, durable deletion, production access changes, releases, and credential rotation. A fresh decision belongs beside those operations. Read-only inspection under a narrow grant does not need the same ceremony. Prompting on every harmless read trains the operator to dismiss the dialog.
Anthropic’s agentic-misalignment study gives one reason to keep the final control outside the model. In controlled simulations, agents with access to sensitive fictional information sometimes chose harmful actions when their goals conflicted with the fictional company or when they faced replacement.
The researchers did not report real deployments behaving this way. They designed difficult scenarios and limited the agents’ alternatives. I would not use the paper to claim that current agents routinely become malicious insiders. I do take its narrower lesson seriously: behavioral instructions did not reliably prevent harmful actions in those tests. The paper recommends human approval for irreversible actions and limiting information according to need-to-know.
CISA’s agentic-AI guidance reaches a less dramatic operational recommendation. Avoid broad or unrestricted access, begin with low-risk uses, and include agent systems in the organization’s security model. An agent that can only prepare a reviewed change is a better first deployment than one that can also publish it.
Long work needs expiry and an audit trail
A task can outlive the facts that authorized it. Someone closes the incident, revokes a customer’s consent, changes the target branch, or discovers that a credential leaked. Adding “please stop” to the agent’s context is not enough.
Short-lived credentials limit abandoned work. A central task grant provides immediate revocation. The tool gateway checks that grant again before a consequential operation. If it cannot validate current authority, it refuses the call.
Workflow identifiers cannot replace authentication. MCP’s security guidance calls this out for handles such as a cart ID or workflow ID. The server must bind stored state to the authenticated principal. Possession of a guessed or leaked handle does not authorize another runtime to resume the work.
The audit record should preserve the delegation chain. For a production mutation, I want the initiating person, runtime identity, task grant, policy version, tool operation, target resource, approval, and result. A source revision or artifact hash ties the operation to what the person reviewed.
I do not need complete model reasoning or a copy of every prompt in an access log. Such logging would duplicate secrets, customer data, and private source text. Stable identifiers and selected operation fields provide evidence without building another sensitive archive.
Separating initiator from actor improves debugging as well as accountability. If an agent reports a successful deployment but production did not change, the chain reveals which runtime, revision, environment, token audience, and API operation were involved. A log containing only my user name does not.
My own setup exposes the gap
My tmux agent workflow uses separate worktrees, tests, diffs, repository instructions, and human review. Those controls make parallel work manageable. They are not a full zero-trust design.
A local coding agent can inherit whatever its shell can reach. A worktree separates Git state, not SSH keys, cloud sessions, browser cookies, or arbitrary network access. Repository instructions state my policy but do not remove credentials from the process.
The checks I trust most happen outside the model’s explanation. Tests execute the code. Git records the exact diff. A worktree limits accidental overlap. I review the artifact before it enters shared history, and deployment remains a separate action.
I can make the access side stronger. A coding task should receive one repository and a restricted set of commands. Network access should name the package registries and APIs involved. Temporary credentials should name the resource and expire with the task. A deployment token should appear only after review and should bind to one environment and revision.
My identity establishes what I am allowed to delegate. It should not become the credential that every agent process keeps for convenience.
Questions to answer before connecting an agent
Before I connect an agent to a business system, I want written answers to these questions:
- Who starts the task, and how does that identity reach the resource log?
- Which controlled runtime holds credentials and calls tools?
- Which resources and operations does this task require?
- Which untrusted documents, messages, or tool results enter the model context?
- What blocks disclosure if the model follows a hostile instruction?
- Is every token bound to its intended resource and short-lived?
- Does any intermediary pass a user token to another service?
- Which runtime facts can change the authorization decision?
- Which side effects require fresh approval, and what does the person inspect?
- Can an operator revoke the task while it runs?
- Does the resource enforce authorization after the gateway check?
- Can an investigator reconstruct the delegation without reading sensitive prompt logs?
- What happens when the policy service or credential broker is unavailable?
If the answer to access control is “the prompt tells the agent what not to do,” I have not established an access-control boundary.
Keep the request as the unit of trust
BeyondCorp replaced “inside the network” with a decision about a person, device, request, and resource. Agentic work adds a runtime and a delegated task. It does not justify a permanent trusted-agent category.
The runtime proves its identity. The task grant limits what the person delegated. A gateway evaluates the tool call. The resource enforces its own policy. Approval attaches to the exact side effect a person reviewed. The resulting record names both the initiator and the actor.
An agent should receive enough authority for the next justified operation, not everything its owner could do. That is BeyondCorp applied to software that now chooses which button to press.