DEV Community

dev.to staff for Daily Context

Posted on

An Agent’s Plan Isn’t Permission

AI Engineer Conference Coverage

When a coding agent investigates a production bug, it might need to read a repository, query logs, and open a pull request. If it finds something suspicious in another service, reading that service’s logs could be a reasonable next step. Whether it should have access depends on the investigation, but its credentials often grant the same permissions regardless of the task.

API keys and tokens usually say little about what the agent was asked to do, who assigned it, or how the task reached the agent. Intent-based authorization uses that purpose and context to determine access for each task. It evaluates the requested access against the permissions of the person or system that assigned the task, the agent’s assigned purpose, and organizational policy. A request to retrieve HR records, for example, should remain outside a customer-support agent’s remit even if its tools could reach them.

Access follows the task

Consider an alert reporting errors in a payments service. An orchestrator proposes an investigation, and an authorization service evaluates it using the authenticated trigger, the agent’s permitted role, and policy established outside its control. It then grants an incident agent read access to that service’s logs for the previous hour.

As the investigation progresses, the agent finds evidence pointing to an authentication service and requests those logs too. Policy may permit that additional access automatically or require human approval, but the runtime blocks the request until access is granted. The agent can follow a new lead without deciding for itself which permissions come with it.

If the incident agent delegates log analysis, the receiving agent uses its own verifiable identity and gets only the access needed for its part of the task, within its own permissions. That handoff can narrow the existing grant but cannot expand it, and it preserves the task context and records who passed it along.

Throughout the investigation, authorization must distinguish trusted context from untrusted content. An authenticated alert can contain a log line written by an attacker, so trusting the alert’s source does not mean instructions inside it can authorize access to another system.

Running a software factory

In a software factory, agents increasingly propose tasks as well as execute them. An orchestrator can watch incidents and scanner findings, pick up bugs without a ticket, and dispatch agents to investigate and propose fixes. Its ability to identify useful tasks doesn’t give it permission to assign whatever access those tasks might require. The factory needs an independent authorization decision, with limits enforced as the agents run.

Those limits extend beyond access because an agent can pursue a legitimate task badly. It might make thousands of unnecessary requests or produce a change that passes review but fails in production. Budgets help limit consumption, while checks and tests help determine which changes can advance. Audit records outside the agent’s control preserve what happened, and revocable access gives operators a way to stop activity when something goes wrong.

The Software Factory reference architecture, developed by Keycard, Docker, Barclays, Socket, and Aaron Stanley, shows how these controls fit together. Built on Agent Baseline, it defines four boundaries: identity and access, supply chain, sandbox, and network. These boundaries hold as autonomy increases, combining task-scoped access with controls on the software agents use, where they execute, and which systems they can reach.

A factory can let agents decide what to investigate next while keeping decisions about access under independent control. That separation allows it to take on more responsibility and autonomy without giving every agent broader standing permissions.

Read the reference architecture at agentbaseline.org.

Top comments (4)

Collapse
 
cekuu35 profile image
Cenk KURTOĞLU •

The intent-based model is the right shape, and “an authenticated alert can contain a log line written by an attacker” is the part most designs skip. The complement worth adding: the authorization service becomes the single place that decides, so it also becomes the single point that can be bypassed — by the enforcement point. If the incident agent’s tools reach the log store with one shared service credential, the authz decision is metadata attached to the call, not a constraint on it, and a tool that builds the request slightly wrong reads everything that credential can.

Two things make the guarantee hold at the last hop:

  1. Make the enforcement point the data store, not the orchestrator — a per-task scoped credential, or a row policy keyed on the task/tenant id, so “no grant” means “zero rows”, not “the client didn’t call it”.
  2. When a delegate narrows a grant, the narrowed scope has to ride in the credential itself rather than a reference to it — otherwise the receiving agent’s “own identity” can still carry the parent’s access.

“The runtime blocks the request until access is granted” is only provable if the store refuses too. I keep a two-account probe that asserts that exact no-grant → zero-rows behavior on the database side: github.com/cekuu35/supabase-rls-le...

Collapse
 
alexshev profile image
Alex Shev •

The plan/permission distinction becomes operational only when a grant is bound to a stable task ID and an expiry. For delegated work, how would you model the audit link back to the original grant without letting the delegate inherit the parent agent’s broader token? That seems like the point where provenance needs to be a first-class authorization input, not just a log field.

Collapse
 
kevin_hall profile image
Kevin Hall •

The same principle applies to money, and that is where most harnesses are weakest: a metered data API grants the agent whatever its key can buy, regardless of the task. What worked for me was treating the paid call like your incident agent's log access. The plan (count the rows, show a random sample) runs freely; the spend is a separate grant. Concretely: the tool exposes a count mode that returns no rows, the agent reports the number, the human writes an approval with a row cap, and a PreToolUse hook refuses any paid call without that approval on disk. When the hook blocked a 25,000-row pull, the agent did not argue; it proposed a 100-row sample. Intent-based authorization with a cost dimension, enforced outside the model. The three sessions, including the one with no instructions at all: dev.to/kevin_hall/a-spend-gate-for...

Collapse
 
mahmaddafzal profile image
Ahmad Afzal •

The revocation bit deserves its own test. Grant access, queue a delegated task, revoke the grant, then let the queued task wake up. Does it still get the logs?

A stop button that only prevents new plans can leave yesterday’s permission doing today’s work. I’d want the product to be explicit about whether cancellation stops future calls, in-flight work, or both.