Adrian Saxton
Ground Truth

Narrow and high: a model for agent access

Infographic headed "A shell is never one tool." A ladder of seven layers from Intent at the top down to Firmware and hardware. A small box at the top rung, labelled "restart tool", reaches only that rung. A wide red bracket starts at the Operating system rung and spans every rung above it, labelled "a shell: everything above comes with it".

Most of what I read about MCP servers is about what a connector can do. The question I keep meeting is different: who may hold it, by which route, with which account, and what is refused outright. It has come up in conversations with people working on agent security, on a client day earlier this month about their agent harness and its integrations with data sources, at techUK's webinar on digital identity for AI agents on 22 October, and first of all in the multi-agent system I run at home.

When I audited that system at the end of September, one of 17 registered MCP servers met the standard I'd written for them. The rest had gone back to the shell, because allowing a shell command was always quicker than building a tool. The model below is my answer, written at the scale large organisations and government departments now use AI: many agents, many users, a platform team, an identity provider, a SOC and change control.

The best published starting point I know is "Careful adoption of agentic AI services", the joint guidance NCSC-UK put out this year with ASD's ACSC, CISA, NSA, the Canadian Centre for Cyber Security and NCSC-NZ. It has least privilege, approval decided by people rather than by the agent, tool output treated as untrusted, and a named owner who can stop the system. What it doesn't have is a way of saying how deep into a system an agent reaches, and that is what the model adds.

Width and height

Every integration has two dimensions. Width is what it may do: read a queue, add an item, restart a service, delete, change settings. Height is the layer it enters at. I count seven, from the top down: a purpose-built tool that expresses an intent; the application's own API; its data, the database or files behind it; the runtime, the container or process the app runs in; the host operating system; the virtualisation layer, the hypervisor or the container engine's socket; and firmware and hardware.

Entering low gives everything above that layer for free. A shell inside an application's container is full width over that app, its configuration and its API key, because it can read the config file and call the API itself. A shell is never one tool: it brings every other command with it.

The techUK panel described width well. Olly Jobling of Signable wants an agent's authority to be explicit: not just that this agent acts for him, but "this agent can do this task, up to this limit, with these counterparties, for this period of time". Jim Small of Hippo Digital named the gap: there is "no current widely accepted open standard for defining the granular delegated authority for an agent", no agreed way to say that this agent may spend £50 on one service for one person until Friday. Julie Dawson of Yoti would start every deployment with a few useful permissions and safeguards around them. All of that is width, and the hour never reached the layer an agent enters at.

Width is what least privilege already covers. Height is where the material I've read stops: the joint guidance's nearest line on depth is "limiting the action space where required, such as restricted APIs or sandboxing", and its warning never to grant an agent "broad or unrestricted access, especially to sensitive data or critical systems" describes a shell without naming it. A shell is one broad grant at a layer below everything it touches.

I call the top layer the intent layer. In the three-tier application model, the presentation tier existed so that users never touched the logic or the database. A purpose-built tool does the same for an agent: it says what, not how, and the credential, the endpoint and the validation stay behind it. The target for every integration is narrow and high: the fewest verbs, entered at the intent layer, with anything lower recorded as an exception with a reason and put through the same change control as any other privileged access.

Who sets the width, what sets the height

The width belongs to the agent's role. A service desk agent may reset a password and reopen a ticket; a SOC agent may read every log and block an address; a finance agent may read the ledger and never write to it. Each role's tool list is its ceiling, and a tool exists only because a routine, repeatable job uses it.

The height and the approval belong to the context: how the work started and who is watching. Build work changes the system itself, and it's the only work that goes in low, with an engineer approving each action as it happens. Operate work, everything an agent does on the organisation's behalf once the system is built, stays at the intent layer.

Tasking and automation

Within operate work, approval differs by how the work started. Tasking is a person asking an agent to do something: approved in the moment, up to the role's ceiling. Automation is a job on a schedule or a trigger, a nightly reconciliation or a ticket arriving in a queue. It was approved once, when the job went through change control, so its outputs and tools are fixed and are a subset of the owning role's. Anything beyond those outputs it can only propose, which turns the work back into tasking.

Writes that change a system or reach another person always need approval; an automation's own record-keeping is approved by its design. The joint guidance draws the same two lines: the decision about when a person must approve is "determined by system designers or operators, not delegated to the agentic AI system", and the checkpoints go on "actions where the cost of error is high, such as system resets, network egress or deletion of critical records".

The part with a model holds no password

The hardest case is a SOC agent that may block something it has found. The obvious design gives the agent's runtime the write credential for the firewall or the identity provider, which keeps a secret where a model can read it, and where the first successful prompt injection can read it too.

I'd propose a request broker instead. The agent's tool holds no credential and talks to no system. It writes a request: what to block, why, and who asked. A broker service with no model in it picks the request up, and only the broker holds the write account. It checks the request against policy the agent can neither see nor edit, makes the one change, and records all of it. A forged request can do no more than a real one, and there is no request that unblocks. Containment only ever adds a block; only a person removes one, and nothing expires on its own.

Figure 1. The request broker. The agent asks; a service with no model holds the only key, checks the request against policy the agent cannot see, and makes the one change.

The OWASP DevSecOps Guideline puts the principle in one line: "Permission prompts are not a security boundary against a manipulated agent; isolation is." I'd apply the broker to every write credential an agent's runtime still holds.

It is also where the techUK panel's two tests are met. Olly Jobling's test for a mandate was whether an agent can be stopped from going beyond its authority, have that authority withdrawn at once, and leave proof afterwards of what it did. Jim Small's chain of delegation ends with the relying party checking the mandate against policy before it acts. The broker does all of that, and does it where the model cannot reach it: the policy, the credential and the record are in a service the agent only ever sends a request to.

Two owners and a watcher

Every automation has two owners. A business owner is responsible for its purpose and output. A platform owner is responsible for whether it ran at all: the scheduler, the runtime, the logs, the disk. Business agents hand runtime problems across rather than gaining infrastructure tools of their own.

Security operations is the watcher, because the one who acts is not the one who audits. A SOC agent investigates with its own reads and its own read-only credentials. Its actions are containment, never operations; the platform agent's are operations, never containment. The joint guidance asks for the same separation of duties, codified as roles "such as 'Orchestrator', 'Reader' and 'Actuator' with clear boundaries".

Every tool call from every agent goes to the SIEM as an event (which agent, which app, which layer, in which context, on whose behalf), and the SOC reads those events for all agents, the platform agent included. It is logged at the tool call because, as the guidance notes, tools "may operate outside of the system's monitoring boundary, making it difficult to account for tool actions".

Taint at the level of the run

In taint analysis, the kind a static analyser such as Semgrep runs over code, a rule tracks untrusted data from a source (a request parameter, a file read) through the program to a sink (a SQL query, a system command) and reports any path that doesn't pass through a sanitiser. The model uses the same three terms for a run. A source is any read of text an outsider could have influenced: a web page, an email, a ticket, a log line, an alert, a tool response. A sink is any tool that writes to a system or reaches another person. The sanitiser is not a function. It is a person's specific approval, which starts a fresh, untainted run that does one named thing.

The rule is coarse, and deliberately so. Inside a model's context you cannot follow a value from source to sink, so the whole run is treated as tainted once a source is read. The agent keeps its reads and can say what it would do, but its sinks are gone for the rest of the run. "Restart the proxy", which reads nothing from outside, is done at once. "Look at the proxy and sort it out" ends with a proposal, and the approval starts the fresh run. That costs a second message from the person, and what it gives is a specific approval: "sort it out" would have approved whatever the agent decided after reading a log an attacker may have written to.

Figure 2. Taint at the level of the run. Once the agent reads a source, every sink is gone; a person's approval of one named action starts a clean run.

Measure, then nudge, then enforce

None of this should start with blocking. Log every tool call first. Expect the log to show routine work going below the intent layer every day, mostly through a shell. Replace each route with a tool, prove the tool on a real run, remove the route, and the routine calls below the intent layer fall. Block last, and only where the log shows the route has already stopped being used, because a block put in before the tool exists sends the work back to the shell.

Where I'd like to be challenged

Three questions I haven't settled.

  1. Time. The guidance raises it more than once: entitlements limited "to the exact resources, operations and timeframes needed", and in the NCSC blog that introduced it, "the minimum access they need, for the shortest time required". The model has width and height and no time axis. A tasking approval lasts for the run, but an automation's approval is standing, given once at change control and never again. The guidance warns that an entitlement checked once at startup leaves a stale "allow" decision for an attacker to use later, and a standing approval looks like that, except that a person gave it. Is time the third dimension, or a property of the approval rather than of the access?

  2. Identity, partly answered. The guidance wants each agent built "as a distinct principal, a cryptographically anchored identity with its own unique keys or certificates", and Microsoft's guidance on least privilege for agents adds a named owner for each agent identity and the "on behalf of" user logged on every action. What's left is what "on behalf of" says when an agent acts for several people in one run, or for a schedule that nobody asked for today: the business owner's name, presumably, but then the record says who designed the job, not who wanted it run.

  3. The taint rule, and whether a finer one can be run. CaMeL, from Google, Google DeepMind and ETH Zurich, does inside a program what can't be done inside a model's context: it tracks provenance per value, recording each value's sources and allowed recipients. A privileged model that "only sees the initial user query and never the content from potentially compromised data sources" writes the plan; a quarantined model with no tool access parses the untrusted text. On the AgentDojo benchmark it solved 77% of tasks with provable security, against 84% for an undefended system. So the finer rule exists. Its authors also say it needs security policies that someone must write and maintain, that every tool has to understand capabilities or utility drops, and that prompt injection is "not fully solved". The open question is whether an organisation can run that at the scale of a SOC and a service desk, or whether the run-level rule is the one a platform team can operate.

If you run agents against systems that matter and have drawn these lines differently, I'd like to know where, and why.

Sources

  • First-hand: the access model for the multi-agent system I run at home, and my audit of it at the end of September 2026 (1 of 17 MCP servers meeting the standard I had written). The width and height idea is my own, from the principles of network security. The enterprise roles (service desk, SOC, finance, platform team), the request broker, the two owners and the SIEM logging are a proposal written from that system; they describe no client.
  • techUK, The Agentic Angle: Digital Identity for AI Agents, members' webinar, 22 October 2026, which I attended. Panel: Georgina Becker (Kainos), Julie Dawson (Yoti), Jim Small (Hippo Digital), Olly Jobling (Signable); moderator Max Elphick (techUK). Quotations are from my own recording: Olly Jobling on explicit authority (16:26) and Jim Small on the missing mandate standard (26:53), with Jim's £50 example following it. Paraphrased: Jim Small's four-layer chain of delegation (24:53), Olly Jobling's prevent, revoke and prove test (33:25), Julie Dawson on narrow permissions with safeguards (44:58). No attribution restriction applied.
  • ASD's ACSC, CISA, NSA, the Canadian Centre for Cyber Security, NCSC-NZ and NCSC-UK, Careful adoption of agentic AI services, joint guidance, published 1 May 2026 (date from the NCSC-NZ landing page). Quoted from the PDF: broad or unrestricted access (p4); the stale "allow" decision, paraphrased (p9); tools outside the monitoring boundary (p13); distinct principal (p15); Orchestrator, Reader and Actuator (p18); limiting the action space (p19); human approval decided by designers or operators, and the high-cost actions (p22); entitlements limited to timeframes (p28). "Layers" in the guidance means overlapping controls; it has no layer or depth concept and does not mention MCP.
  • NCSC-UK, Thinking carefully before adopting agentic AI, blog, 15 May 2026 ("the minimum access they need, for the shortest time required").
  • Microsoft Learn, Least privilege for AI agents with Microsoft Entra Agent ID, undated (a dedicated agent identity with a named owner, and logging the "on behalf of" user; paraphrased).
  • OWASP, AI Agent and MCP Security, DevSecOps Guideline (the "Permission prompts are not a security boundary" line).
  • Google, Google DeepMind and ETH Zurich, CaMeL: Defeating Prompt Injections by Design, arXiv 2503.18813 v2, 24 June 2025 (per-value provenance and capabilities; the privileged model that "only sees the initial user query and never the content from potentially compromised data sources"; the quarantined model with no tool access; 77% of AgentDojo tasks solved with provable security against 84% undefended; the policy and tool-ecosystem burdens; "not fully solved").