Skip to content
redactsure
Book a demo

Explore.

Data Report · By Chris Sowa · Published
Last updated

Why Should Each Service Enforce Agent Permissions Separately?

Because one component holding every permission is a single target, and a compromise there speaks for every service it fronts. Ask which component enforces each permission, what it holds while enforcing it, and what a compromised one could still release.

A credential reference travels from a browser record through a bounded route to a separate API destination.

Every agent deployment inherits a permission model, and most put the check in one place: one service decides whether the agent may act, and everything behind that decision runs on the answer. That concentrates authority. A component that answers for every service is worth attacking once, and the answer it gives after a compromise looks the same as the answer it gave before. Divide the check instead, so the component that proposes work, the one that verifies the grant, the browser that renders the page and the one that performs the action each enforce their own part.

The argument can be tested against what each component holds. A verifier that caches every grant holds every grant. A browser holds whatever the page displays. A planner holds the task and the pages it read. The question for a buyer is which of those a compromise converts into release: a credential, a value on a screen, or an approval the person never gave.

The sections below take the question in order: the scope of the claim, why a central gatekeeper is a single target, what vendors document about scoped and workload-bound identity, one record worked through a compromised planner, and the control class that makes a divided check hold.

Key findings

  • A study of code completion tools found that "two valid credentials were identified during our experiments" and that the tools "can not only return the precise piece of their training data," so a component that read a credential can repeat it later (Huang et al., 2024).
  • AWS states that "the resulting session's permissions are the intersection of the role's identity-based policy and the session policies," so a session can be narrower than the role behind it (AWS, 2026).
  • Microsoft states that "this token acquisition doesn't require any secrets and is automatically authenticated based on the environment where the code runs," which ties authority to the component that holds it (Microsoft, 2026).
  • Cognition's Devin documentation places credentials at four scopes, organization, personal, repository and session, and calls a session credential "scoped purely to the current session and are not saved for any future sessions" (Cognition, 2026).
  • A governed environment replaces values with consistent tokens before any model reads the screen, so a component composing a task from a page holds placeholders, not records (Enterprise Browser or Render-Layer Tokenization?).
  • Real values resolve only at the approved destination at the moment of an approved action, so the authority to release a value sits with a named person, not the component that asked (What Is Least Exposure?).

What does each service enforce, and where does that enforcement run?

Start with scope, because the answer differs by surface. A governed browser environment covers what an agent reads and does on a rendered page: a dashboard, a console, a settings page, an issue page or a sign-up form. It does not cover the terminal, the IDE, the local filesystem, direct API calls or MCP. A permission enforced where the page renders governs the page and says nothing about the shell command the agent runs next, which the sandbox governs if the team configured it to.

Within that scope, separate enforcement is a division of labor among components that see different things. A planner turns a request into steps, a verifier decides whether a step is covered by a grant, the browser renders the page the step acts on, and an execution component performs the action and checks the grant again at the point of use. Each can be fooled only about what it can see: a hijacked planner can propose a step, and a verifier that never read the page cannot be talked into releasing a value it does not hold.

Cognition's Devin documentation applies the idea to credentials: scopes are organization, personal, repository and session, and a session credential is "scoped purely to the current session and are not saved for any future sessions" (Cognition, 2026). Four scope levels are four answers to which component may read a value.

The limit is authority, not reach. A tether is a description of authority, not of capability: a tethered agent goes anywhere its supervisor could go, so dividing enforcement does not narrow what the agent can do (What Is a Tethered Agent?). It changes who has to agree before a value leaves the page.

Why is a central permission check a single point of failure?

A gatekeeper is efficient because one decision covers many services, and that is what makes it the target: an attacker who controls the component answering for every service inherits their authority, and each downstream log records the gatekeeper's approval as the agent's own.

Teleport's documentation states the requirement directly: "Your agents need a verifiable, cryptographic identity tied to where they're running, not a shared API key" (Teleport, 2026). An identity bound to where the agent runs cannot be replayed by another component, which a shared key allows.

OWASP's non-human identity list names both failure modes a gatekeeper converges on: credential leakage, the "leakage of sensitive NHIs such as API keys, tokens, encryption keys, and certificates to unsanctioned data stores," and overprivileged identities (OWASP, 2025). A gatekeeper tends toward both: it stores the keys it checks and needs the union of the permissions it grants.

The reach is measured: an environmental injection attack on generalist web agents reached an attack success rate of up to 70 percent in stealing users' specific personal information (Can an AI Agent Sign Up for Developer Services Without Seeing Your Payment Card or Identity?). A durable top-level credential is the same risk, which is why AWS states that it strongly recommends not creating access keys for the root user (Is It Safe to Let an AI Agent Set Up Your Cloud Environment?).

What do the vendors themselves say?

Two vendors document scoped, time-bound authority, and one documents where the value meets the page; none describes a single central check for everything an agent touches.

AWS's AssumeRole documentation states that "the value specified can range from 900 seconds (15 minutes) up to the maximum session duration set for the role," and that "role chaining limits your AWS CLI or AWS API role session to a maximum of one hour" (AWS, 2026). The first sentence makes the lifetime a property of each session; the second caps what a chain of services adds up to, so authority cannot be extended by passing a request down a line of components.

Cognition's Devin documentation describes where a credential meets the page: "In the browser, Devin types the value directly," while "for shell commands, it binds secrets as environment variables whenever needed" (Cognition, 2026). Typing the value directly is the route a rendered-page control has to intercept, and the environment variable is the sandbox's route. Devin also states that "all secrets are encrypted at rest," a statement about storage; whether the model sees the value in the browser is not described in the pages reviewed.

Doppler states the per-agent version: "Give every coding agent its own scoped, read-only, expiring set of credentials," and says credentials are "injected at runtime instead of written to a .env, so agents can't read, log, or commit them" (Doppler, 2026). The page does not say whether an agent can read the environment variables injected into its own process, so the claim covers the file and not the process.

Vendor What its documentation states What it settles for this page What a buyer should verify
AWS STS Session permissions are the intersection of the role policy and the session policy; 15 minutes up to the role maximum; role chaining capped at one hour A grant can be narrower than the identity, and a chain of services has a ceiling Whether the workload calls AssumeRole for itself or holds a long-lived key
Cognition Devin Four credential scopes; browser values typed directly; shell values bound as environment variables; encrypted at rest The same product already separates scope by the context that uses it What the model receives at the moment the browser types the value
Doppler Per-agent scoped, read-only, expiring credentials; runtime injection rather than writing a file Custody can be per agent and time-bound Whether the injected variable is readable by the agent's own process

What can a compromised planner do when each service enforces its own part?

The record type is a planner composing a task from two rendered pages in a console: an issue page that lists the work and a settings page that holds a token field. The planner is compromised in the sense that a page it read carried instructions it followed.

Under a single central check the planner holds the answer. It read the settings page, so the token was in its context, and the issue page gives it a destination. The compromised step is a paste: the value moves from the field that displayed it into a comment or a new record, and the gatekeeper is never asked because the planner's grant already covers writing to the issue.

Under a divided check the same compromise yields a token. The browser renders TOKEN_004 where the value sat, and the planner composes the task on TOKEN_004. The execution component checks the grant when the call is actually made, against the destination in the proposal, and the release endpoint resolves the real value only for an approved action. The planner can propose the paste; it cannot perform the resolution, because the mapping lives in a component it cannot address.

The volume argument points the same way. TruffleHog detected "11,908 Live Secrets" in 400TB of web data, and "2.76 Million Web Pages contained live secrets" (Truffle Security, 2025); the post does not establish that any named corpus included those pages. GitGuardian counted "28,649,024 new secrets exposed in public GitHub commits across 2025," with "24,008 unique secrets exposed in MCP configuration files" (How Do You Let an AI Agent Manage API Keys Without Reading Them?).

How should a team divide enforcement between services?

Two things are worth measuring before choosing the split. Datadog reports that "37 percent of customers who send CloudTrail logs to Datadog are using IAM users in their GitHub Actions" (Datadog, 2025), a pattern in which one long-lived identity serves many steps instead of a role per job; the sample is Datadog's own customer base and the report does not say how representative it is. A survey of 353 IT professionals found 80 percent of organizations reporting agents taking unintended actions, about 40 percent reporting agents accessing unintended systems and 31 percent reporting agents sharing inappropriate data (Why Do AI Agents Access Information Outside Their Assigned Tasks?).

The division that follows has five parts, and each one is worth testing on its own:

Layer What it enforces What it holds What fails if it is the only layer
Grant verifier That a proposed step sits inside a grant, before the step runs Every grant it has checked A compromise answers for every service behind it
Render layer Which values the model is shown on a page The mapping from token to value A page outside the policy renders in full
Planner The order of steps and the destination The task and the pages it read A hijacked plan proposes a step that looks ordinary
Execution component The grant again, at the point of use The connection it opens A grant checked once is trusted for everything after
Named approver The consequential action itself The decision and its reason Nothing distinguishes an approval from a default

A broad identity handed to one component is the same mistake as a central check: it makes one account responsible for work it was never scoped to do.

The test is to take one task a week and list, for each step, which layer enforced it. A step with two layers survives one compromise. A step with none is the one to fix first, and a step where the same component proposes and approves is not a check at all.

What does a governed environment change?

A governed environment is a control class that acts where a page is rendered. Values chosen by policy are replaced with consistent tokens for the whole run, so a component composing a task from a page works on placeholders such as TOKEN_004 and ACCT_001. Real values resolve only at an approved destination, at the moment of an approved action. A named person confirms the tokenization policy and approves each consequential action. Every screen as tokens, every action and every approval is written to a record that exports to the organization's own monitoring.

For this page it changes what a compromise can convert into release. The planner that read the settings page holds a token, not a value, so the paste it was tricked into proposing carries nothing that resolves outside the environment. The check at the execution point does not depend on the planner's account of its own permission; it reads the grant and the destination at the moment of use. And the record names the component that enforced each step, so a review can ask which layer stopped a step rather than whether the agent behaved.

Three properties follow. The model reads tokens before it reads anything real, which makes the reading itself harmless. The real value exists at one destination for one approved moment, which makes the release auditable. The approver is a person with a name, which makes the authority to release a decision rather than a default.

The scope stays what it was: the rendered page. A shell command the agent runs after the page is governed by the sandbox, and an API call it composes by hand is governed by the token it was issued. A governed environment does not replace those controls; it covers the surface they cannot see.

Methodology and limitations

This page rests on four kinds of record: vendor documentation from AWS, Microsoft, Cognition, Teleport and Doppler; a standard from OWASP on non-human identity risk; vendor measurement from Truffle Security and Datadog; and existing RedactSure research pages. Vendor pages were read between October 20, 2026 and October 21, 2026, and each Sources line carries the date for its page. Quoted facts are cited to the page that states them, and every figure is reported as its publisher gives it, not as an independent measurement. The 70 percent injection figure attributed to Liao et al. reaches this page through an existing RedactSure page rather than through the paper itself.

RedactSure did not test any named product hands-on. Where a vendor page does not describe a behavior, this page says so, and that phrase means the pages reviewed and not a claim about the product's full documentation. Vendor features change, and a reader should treat a release after October 21, 2026 as unreviewed until the check below is repeated. Statements about RedactSure describe its current design, and RedactSure is deploying now with enterprise and government customers. The example describes a record type, a planner composing a task in a records console, and not an organization.

Determinations about whether a permission model meets a contractual, regulatory or audit requirement belong to counsel, assessors and the organization's own security and compliance officers. Nothing here replaces a test of the organization's own agent against its own services, repeated after each release. Keep the written answers beside the test result, so a later review reads what was claimed and what was measured.

What the record shows

The record supports an answer in pieces. A credential one component holds is a credential that component can lose, and the vendors that document scoping already separate a credential by context rather than by service: four scope levels in one product, a session policy narrower than the role it runs under, a lifetime that ends. What none of those designs changes is what a component was shown before it acted. A scoped key still belongs to whoever holds it, and a lifetime still expires after the value has been read.

The answer to the title is that separate enforcement limits what one compromise can convert into release, while a central check converts everything behind it at once. RedactSure's environment is built on the version of that division that also governs what a model reads. For a practical test, a buyer should name one agent and one task, list which component enforced each step, and ask what the model received on the page where the value appeared.

Frequently asked questions

Why should each service enforce agent permissions separately?

Because one check in front of every service is one component holding every grant, and a compromise there is inherited by everything behind it. Separate enforcement means the component that proposes work, the one that verifies the grant, the page that renders the value and the one that performs the action each answer for their own part. A failure in one is then a narrow failure rather than a permission. That is the difference between a check and a division of checks.

Is separate enforcement the same as least privilege?

Not quite. Least privilege limits what an agent may do, and it is the right starting point for the grant. Separate enforcement asks where each limit is checked and what each component holds while checking it. An agent can satisfy least privilege in full and still have every value on a page shown to a planner that needed none of them, which is the gap between the permission and the reading. Ask for both, since a limit nobody enforces is a line on a page.

What does a central permission service get wrong?

It is not that the check is wrong; it is that the check is all in one place. A central service needs the union of the permissions it verifies and the keys it stores, and both are what an attacker wants. Duplicating the check at the point of use costs less than it looks, because the second check reads the same grant and does not need its own copy of the value. The copy is where the exposure lives.

How does a rendered page fit into per-service enforcement?

The page is where a value becomes visible to a model. A browser control replaces policy-chosen values with tokens before the model reads the screen, so the component composing the task holds a placeholder. The execution endpoint still checks the grant, and a named person approves the release. Both checks cover different surfaces, and neither depends on the other's account of what happened. The page control does not replace the endpoint check, and the endpoint check cannot see the page.

Can vendor scopes replace enforcement in the environment?

They answer a different question. A vendor scope says which of its own credentials a given context may use, and it is useful: four levels in one product, a session policy narrower than a role, a lifetime with a ceiling. None of them describes what a model receives once a page renders, which is the surface a governed environment covers. Read the scopes as one layer and ask what the layer above them does. A scope is evidence of intent, not of enforcement on the page.

What should a security team put in writing?

Which component enforces each permission, what that component holds while it does, which values the model is shown on the page, who approves a release, and what record names the approver. A vendor that cannot answer the first two has a central check whatever its diagram says. Repeat the questions after each release, since a new integration is a new component with its own view of the data. A written answer that names a component can be tested; a diagram cannot.

About the author

Chris Sowa is a founder of RedactSure and a former CEO of an AI company; he started it years before ChatGPT existed. He previously led AI at Accenture, served as Global VP of Strategy & Innovation at Schneider Electric, was CCO of Sovos, and spent more than a decade at Oracle, with earlier roles at SAP and IBM.

How RedactSure Keeps a Compromised Planner From Releasing a Credential

A check in one place is one answer to defend, and the designs reviewed each scope, bind or time-limit a credential only within their own boundary.

The environment that enforces this is built by RedactSure, an AI agent controls, governance and data protection company.

Before: the planner reads the token settings page, the field renders the live value, and the model can paste it into the issue. Inside the governed environment the same page renders TOKEN_004, the execution component reads the grant and destination when the call is made, and a named person approves the release.

RedactSure is deploying now with enterprise and government customers. A survey of 353 IT professionals found 80 percent of organizations reporting agents taking unintended actions.

Everyone else controls where data can go. RedactSure controls what the AI can see.

See it on your own workflow

A compromised planner should not be able to release a credential on its own. Bring a task with several steps and see, with test values, which component releases the real value and who approves it. Book a demo

Book a demo

Book a demo

Having trouble? Open the booking page or email us.