AI agent permissions: how to bound what an autonomous agent can do
Identity answers one question: who is this agent, and who owns it. It does not answer the next one, which is the question a counterparty actually has to decide in the moment: what is this agent allowed to do here, right now, for how much?
That second question is a permission boundary. Without one, a verified identity just means you know the name of the thing doing whatever it likes. Agents run unattended, they chain tool calls faster than a human can read them, and they are driven by natural language that an attacker can influence. Bounding them is not paranoia, it is the design.
Why key scopes are not enough
Most teams reach for the tool they already have: API key scopes. Scopes were built for long-lived server integrations, and they carry the assumptions of that world.
- They describe endpoints, not intent. write:orders does not distinguish a $12 refill from a $40,000 order. The agent needs a limit, not a door.
- They have no clock. A scope granted in March is still live in September, at 3am, from anywhere. Agent work is bursty and session shaped.
- They stop at your edge. Your key governs calls into your API. It says nothing about which counterparties the agent may transact with on the other side.
- They are mutable and invisible. Scopes get widened quietly during an incident and never narrowed back. Nobody outside your org can see what the agent is currently permitted to do.
An agent boundary has to travel with the agent, be readable by whoever the agent shows up at, and cover money and time as well as endpoints. See AI agent identity vs API keys for the layer underneath this one.
The five dimensions worth bounding
AstraSync expresses the boundary as PDLSS, five dimensions every registered agent declares. The names are ours, but the dimensions are what any serious agent authorization model has to cover.
Purpose. The action categories the agent may perform, plus explicit allow and deny lists. Read data, write data, execute actions. A support agent may create and update tickets and is denied delete_account outright, whatever a prompt talks it into wanting.
Duration. Session length, token lifetime, and the days and hours the agent may operate in, in a stated timezone. An agent scoped to weekday business hours cannot be driven at 2am on a Sunday, which removes an entire class of quiet-hours abuse.
Limits. Money, as two per-transaction numbers rather than one ceiling. At or below the Autonomous Limit the agent proceeds alone. Between the Autonomous Limit and the Hard Limit the purchase is held and the owner approves or denies it. At or above the Hard Limit it is rejected outright, with no approval path. Declare neither and every paid transaction is refused, which is the right default for an agent that was never meant to spend.
Scope. Which resources, which jurisdictions, and crucially which counterparties. This is where an agent declares that it will not deal with unverified counterparties, or will only deal with those above a trust threshold. The boundary protects the agent's owner as well as the merchant.
Self-instantiation. Whether this agent may spawn sub-agents, how many, how deep, whether children inherit the parent's permissions, and whether spawning needs approval. Multi-agent systems make this the difference between delegation and an uncontrolled fan-out. Note that this governs an already-registered orchestrator minting workers inside its own envelope. A primary agent still needs human approval or a crypto keypair to register in the first place.
Full field-level reference, with a complete worked example, is in the PDLSS documentation.
Why the boundary is immutable, and how change works
On AstraSync, PDLSS is fixed for the life of an agent version. You cannot patch it. When an agent's boundary no longer fits, you upgrade the agent: the Upgrade flow mints a successor version carrying the corrected boundary, the old identity is retired and stops verifying immediately, and the lineage between versions stays visible to the owner. The successor carries the predecessor's trust score, so fixing a boundary does not cost the agent its history. The usual trigger is concrete: a verify-access denial whose failure names a pdlss. dimension is the platform telling you the declared boundary does not cover a request the agent genuinely needs to make.
Per-version immutability sounds inconvenient, and it is the point. A boundary that can be edited in place is a boundary an attacker can edit in place, and it is one that quietly loses meaning over months of small widenings. Immutability makes the boundary a fact rather than a setting: when a merchant reads an agent's PDLSS during verification, they are reading what that version declared and committed to, not whatever was true five seconds ago. Permission changes become visible events, a new version with its own identity, instead of an invisible diff. In multi-admin organisations a successor also waits for a second admin's approval, which keeps one compromised login from quietly widening an agent's authority.
The same logic is why revocation is separate from modification. You can stop an agent instantly. You cannot silently promote it.
How a counterparty uses the boundary
The boundary is only worth declaring if someone checks it. In practice one call does both halves of the job: the counterparty sends the agent's identity and the intended action to POST /api/agents/verify-access, and gets back live registration status together with whether this specific action sits inside the agent's declared boundary.
That means a merchant does not need to model agent permissions themselves. They ask a question about a concrete action and get an answer they can act on. This is the mechanism behind verify before transact, and it is the same call whether the agent arrives at an API, an MCP server, or a website. The inbound vs outbound guide covers how the policy differs by direction.
Setting a boundary you will not regret
- Start at the smallest boundary that lets the agent finish one real task. Widen by upgrading to a successor version when a real denial shows the need, never by expecting to loosen a live version in place.
- Set the Autonomous Limit to a number you would not escalate about, and the Hard Limit to a number you would never approve. If a wrong purchase at the first would ruin your week, it is too high. The Hard Limit is the one that bounds a single transaction; do not lean on per-period caps for that.
- Use deny lists for the irreversible things. Deletion, data export, ownership changes. These belong in an explicit deny, not in the gap left by an allow list.
- Default unverifiedCounterpartyPolicy to deny. An agent that transacts with anyone is an agent whose good identity is doing no work.
- Bound self-instantiation before you need it. Depth and count caps cost nothing to declare and are painful to retrofit.
- Declare model and framework metadata while you are there. It strengthens the agent's trust score, which is what counterparties weigh when they decide how much room to give it.
Where to start
- Agent developers: decide your five dimensions before you register. They are fixed per version, and while the Upgrade flow can always mint a successor, every upgrade retires the old id and repoints your integrations, so a boundary you got right the first time is cheaper. The Agent Access Guide walks the registration flow.
- Merchants and API owners: you do not have to design any of this. Gate access on one verify-access call and read the answer. Start at how to let AI agents access your API safely.
- New to the idea entirely: start with what is Know Your Agent.

