The 1966 Paper That Already Solved Prompt Injection
Sovereignty
Dennis and Van Horn designed protection for a machine full of programs that could not trust each other. That machine is back, and it is called an agent runtime.
By VK Singh Vashisht — Datura Labs
Prompt injection is not an AI problem. It is the oldest problem in shared computing, and the paper that solved it was published in March 1966, in the third issue of the ninth volume of Communications of the ACM, under a title nobody would click on: “Programming Semantics for Multiprogrammed Computations.” Jack Dennis and Earl Van Horn wrote it at MIT’s Project MAC, for a world where several users’ programs would run on one machine at the same time. The question they were answering was not how to make programs smarter. It was how to let a program you do not trust do work on your behalf without handing it the keys to everything you own.
I run agents on my own affairs. They read my mail, watch my calendar, query my brokerage, and write to my ledgers. So the question is not academic for me. It is the exposure I underwrite every morning: if someone else gets one sentence into this thing’s context window, what can it do with what it is holding? I have come to believe that the industry’s consensus answer to that question is wrong in a way that will look obvious in hindsight, because the correct answer is sixty years old, and we already know why it lost the first time.
What consensus says, and who it serves
Give consensus its due: the argument is not stupid.
A language model takes one input stream. Instructions and content arrive in the same channel, in the same tokens, with no hardware distinction between what the user said and what a web page said. Therefore, the argument goes, the boundary between command and data has to be learned. Train the model to privilege its system prompt. Reward it for ignoring instructions embedded in retrieved content. Red-team it against ten thousand injection templates. Put a classifier in front and a monitor behind, allowlist the tools, and you have defense in depth—the doctrine every security professional already believes in.
Look at who benefits from framing the problem this way. The model labs, because it keeps the problem inside the model, where their capability advantage compounds. The security vendors, because classification and monitoring are products with recurring revenue. And every builder of agent frameworks, because it lets them ship on the credentials model they already have: the agent runs as you, holding your tokens, and the model is trusted to be careful.
That last clause is the tell. Strip the vocabulary and consensus is protecting one thing: ambient authority. The agent holds everything you hold, all the time, and safety is delegated to the judgment of the component that is, by construction, the thing under attack.
The deputy was confused in 1988, and it was not stupid
Norm Hardy gave the structural version of this failure its name in 1988: the confused deputy. A compiler on a timesharing system had permission to write a billing file so it could log usage. Users could not write that file, but a user could hand the compiler an output path. Hand it the billing file’s path and the compiler—doing exactly what it was told, with permissions it legitimately held—overwrote the bill. No authentication was broken. No privilege was escalated. A trusted service with broad authority was steered by an untrusted input into misusing that authority.
That is a prompt injection, described in 1988, with no language model in sight.
The point Hardy made, and the point consensus keeps missing, is that the compiler was not confused because it was dumb. It was confused because the system gave it authority that was not tied to the request. The compiler held the right to write the billing file whether or not the current caller did. No amount of intelligence in the compiler fixes that, because the information needed to decide—which of its powers is this caller entitled to invoke?—was never in the channel. The compiler had a permission list. What it needed was to be holding, for this call, only what this caller was entitled to hand it.
Substitute “agent” for “compiler.” An agent with ambient access has authority to execute actions whether or not the untrusted text that just landed in its context is entitled to make it do so. Train the model to be suspicious of inbound text and you have raised the cost of one attack template. You have not changed the fact that the authority is ambient—present on every turn regardless of what the turn is for. The attacker’s job is to find any input the model will treat as legitimate, and the space of such inputs is the space of everything the model can read. Monitoring narrows that space. It does not close it. A classifier has a false-negative rate; an instruction hierarchy has a jailbreak rate; both fall with effort and neither reaches zero, and an adversary who can send you ten thousand payloads only needs one.
Defense in depth is the right doctrine when every layer removes authority. It is theater when every layer is a filter in front of the same unrestricted credential.
What the 1966 paper actually built
Dennis and Van Horn did not have a language model to worry about. They had something structurally identical: a machine on which computations of different origins, written by people who did not know each other and had no reason to trust each other, would share memory, share procedures, and call into one another’s code. Their design problem was to make that safe without making it useless—to let a computation invoke a procedure it did not write, or serve a caller it did not vet, and have the damage either could do to the other bounded in advance by what had been explicitly granted.
Their answer was to stop asking who a computation was and start asking what it was holding. A computation could reach an object—a memory segment, a file, a device, another process—only if it possessed an unforgeable token naming that object together with the specific actions permitted on it. They called that token a capability, and the private list of them that defined a computation’s reach its C-list. The set of everything a computation could touch through its C-list they called its sphere of protection. The consequence is total: if you do not hold the capability, the object is not merely forbidden. It has no name in your world. It is unreachable.
Three properties of that design map onto the agent problem without translation:
- Possession over lookup. Authority is possessed, not looked up. Under the identity model, the system asks who you are at the moment of access and consults a table. Under the possession model, the system asks what you are holding, and what you are holding is exactly what was handed to you for this job.
- Attenuation. Authority can be attenuated on the way down. A computation calling a procedure passes capabilities into it, and can pass a narrower one than it holds. The callee operates in a sphere the caller drew.
- Mutual distrust. The paper’s motivating case is not a benign program with an occasional bug. It is a shared machine on which the code you are running was written by someone else, and the code calling you was too. That is an exact description of an agent runtime: model weights trained by one party, tools written by others, context assembled from a fourth party’s web page, all executing on behalf of a principal who wrote none of it.
Under capabilities, Hardy’s compiler cannot be confused, because it has nothing to be confused with. It never holds a standing right to write the billing file. It receives, from the billing subsystem, a capability to write that one file, and from the user, a capability to write whatever the user was entitled to write—and those are different tokens. The user cannot hand over a capability the user does not hold. The deputy dissolves not because it got smarter, but because the authority it could misuse was never in its hands.
Why the paper lost, and why the loss has expired
The possession model lost anyway, and it is worth being precise about why, because the reasons are the argument.
It lost because tagged memory cost transistors. It lost because Unix shipped with users and permission bits and was “good enough.” And it lost because for fifty years the actors invoking services were humans, at human speed, with human accountability. Identity was cheap to check and the adversary was expensive to be. Every serious attempt to revive it—the CAP machine at Cambridge, Hydra, KeyKOS, the object-capability tradition that runs through E and seL4—was correct and inconvenient, and inconvenient lost. That is the entire history of why ACLs beat capabilities: not correctness, but convenience. And convenience was the right trade against the adversary that existed.
It is the wrong trade against the adversary that exists now. An agent is a cheap, tireless, instruction-following deputy carrying its principal’s credentials, sitting inside the trust boundary, reading untrusted text all day. The cost of confusing it has fallen by orders of magnitude. The cost of the identity model’s failure has risen to match. The paper’s assumptions did not change. The world’s did. Dennis and Van Horn designed for a machine on which untrusted code executes with your resources on your behalf, and in 1966 that was a research condition. In 2026 it is the default condition of every workflow that puts a language model between a data source and an action.
Why this is necessary for every AI-native workflow
Here is the general claim, and it is stronger than “capabilities are a good idea.”
Any AI-native workflow has three components: a model that reads, a set of tools that act, and a context assembled from sources the operator does not fully control. The moment a workflow has all three—and a workflow without all three is a chatbot, not an agent—it has recreated the 1966 machine exactly. The model is untrusted code. The context is untrusted input. The tools are the objects in the sphere of protection. The only open question is whether the sphere is drawn by what the model is (identity, ambient) or by what it is holding (possession, per call).
If an agentic runtime or workflow grants permissions using any of the following patterns, it falls squarely into the vulnerable ambient-authority population:
- Persistent credentials — long-lived authentication tokens (permanent OAuth tokens, API keys, session cookies) that remain active across multiple independent execution turns.
- Broad scopes by default — broad resource access rather than fine-grained, task-specific permissions.
- Ambient invocation — a tool or model executing actions with the principal’s full standing privileges automatically, without a dynamically minted, single-use token per invocation.
- Content-based filtering as the boundary — treating security as a matter of instruction tuning, classifiers, or prompt guardrails while leaving standing credentials attached to the execution context.
If the sphere is ambient, the workflow’s security reduces to the model’s judgment, and the model’s judgment has a failure rate that an adversary with volume will find. That is not a property of today’s models. It is a property of any component that must decide, from the content of a request alone, which of its powers the request is entitled to invoke—which is precisely what Hardy showed cannot be decided from the request alone. The information is not in the channel. It was not in the channel in 1988, and no amount of training puts it there.
If the sphere is drawn per call, the failure rate of the model’s judgment stops being the security boundary. The model can be fooled and the blast radius is the capability it was holding, which the orchestrator chose, which dies with the turn. The injection can land. It arrives in a deputy with nothing to be confused with.
So the design rule falls out of the problem’s structure. An agent should hold no ambient credentials. Each tool invocation carries a capability scoped to the object, attenuated to the operation, valid for this turn. The agent reading a source holds a read capability on that source; when the plan calls for an outbound action, the orchestrator mints a capability for that one action, that one target, this turn. Nothing the model reads in an untrusted input can conjure a capability it was never handed. This is not a security feature added to an agent. It is the condition under which the word “agent” describes something an owner can safely deploy.
None of it is exotic. Every system that took protection as a design constraint rather than a feature is built this way: seL4, whose kernel exposes nothing but capabilities; Google’s Fuchsia, where every handle is one; Capsicum on FreeBSD; the WebAssembly component model; and, at the hardware layer, CHERI, which adds the tag bits the commodity CPU never adopted. The pieces exist. What does not yet exist at scale is the discipline of building agent runtimes on them instead of on a bag of OAuth tokens.
The standard the firm holds itself to
Datura’s controls state the first half of this: every response is treated as untrusted input, capabilities ship in least-privilege manifests, and agents propose while humans approve. The second half—that no tool receives a standing credential, that the orchestrator holds the C-list, and that the model is treated as untrusted code that proposes actions and holds no keys—is the specification every runtime the firm builds is measured against. It is more work than handing the agent a token. It is also the only architecture under which I can state, rather than estimate, the blast radius of a poisoned input. A deliverable you cannot audit is a promise; an authority boundary you cannot state is the same thing.
Watch vendors accordingly. The ones selling capability discipline—scoped, attenuable, per-call authority—are building on 1966. The ones selling a smarter filter in front of the same credential are building on 1988’s mistake with a bigger model, and they will describe it in capability vocabulary because the vocabulary is now fashionable. The test is simple: can the token an agent holds be attenuated by its holder, and does it die with the turn? If not, it is an access control list with a press release.
The bet
My bet is that within two or three years the serious agent platforms converge on possession-model authority; that prompt injection is reclassified from a model-safety problem to an authorization-architecture problem; and that “the agent runs as you” is remembered the way “the service runs as root” is remembered.
What would prove me wrong is what proved Dennis and Van Horn wrong four times before: convenience wins again. Monitoring plus allowlists turns out to be good enough for the attacks that actually occur, the labs push injection rates low enough that nobody pays for structural fixes, and object capabilities stay the substrate of a few kernels and a research community. That outcome has the base rate on its side. I am betting against the base rate because, for the first time since 1966, the cheap side of the trade has switched—and I would rather hold the position early and be embarrassed by the timing than hold the credential and be embarrassed by the blast radius.