How do I limit blast radius when an agent's credential is legitimate?
An agent's reach (its blast radius) is the total set of data it could read if it did everything its credentials permit. It matters because in most agent incidents nothing was stolen and nothing was forged: the agent held a valid credential and used it. Cloud Security Alliance and Token Security research published in April 2026 found 65% of organizations had at least one security incident caused by AI agents in the prior year, and 61% of those involved sensitive data exposure. Authentication was working in almost all of them.
Reducing reach means shrinking what a valid credential reaches, not detecting invalid ones.

Why authentication controls do not address this
Identity for non-human workloads is worth doing. Issue the agent its own identity rather than a shared credential, use short-lived tokens, rotate them.
All of that answers "is this really the agent". None of it answers "should the agent be able to read every row in this table". An agent that is correctly authenticated and prompt-injected does exactly what an authorized agent does, which is why the identity layer cannot be where this is solved.
The four dimensions worth measuring
Reach is not one number, and teams that reduce it successfully usually attack it along these axes:
- Breadth. How many tables and columns are reachable. The most common finding is an agent scoped to a schema when it needed three tables.
- Depth. Whether reachable columns return real values or transformed ones. A column the agent can read but only in redacted form is reachable without being exposed.
- Volume. How much can be retrieved before something intervenes. Unbounded is the default everywhere.
- Duration. How long the access persists. A standing credential has a permanently open radius; a task-scoped one closes when the task ends.
Most teams reduce breadth, stop, and believe they are done. Depth and volume are usually where the remaining exposure sits.
Measuring it before you reduce it
The number is computable and most teams have never computed it. For each agent: enumerate reachable tables, count columns classified sensitive within them, and record whether any volume ceiling applies.
The result is usually uncomfortable, which is the point. An agent built to summarize support tickets frequently turns out to reach the full customer record because it was granted the schema rather than the three tables it uses.
Ascent computes this as a per-identity report at GET /application/{id}/reach. It runs the live evaluator once per data repository (a protected set of records with its own keys), per record type and per view, then joins the verdicts to the inventory: how many records are reachable, how many of those are reachable as plaintext, and which fields would come back in the clear. A verdict that depends on something the evaluator cannot check in advance — address, hour, MFA — is returned as conditional rather than counted as reachable. GET /reach/summary ranks every identity in the estate the same way, and POST /application/{id}/reach/simulate answers what a proposed set of roles would change before anyone holds them.
ASCENT=https://ascent.example.com
TOKEN=$(curl -sS -X POST "$ASCENT/api/login" \
-H 'Content-Type: application/json' \
-d '{"email": "you@example.com", "password": "..."}' \
| jq -r .access_token)curl -sS "$ASCENT/api/reach/summary" \
-H "Authorization: Bearer $TOKEN"
APPLICATION_ID=42
curl -sS "$ASCENT/api/application/$APPLICATION_ID/reach" \
-H "Authorization: Bearer $TOKEN"Reducing it
In rough order of effort against effect:
- Scope to tables, not schemas. Highest effect, lowest effort, and almost always available.
- Mask rather than exclude where the agent needs a column's shape but not its value. An agent can group by region without reading addresses.
- Apply a volume ceiling so the reachable set is not retrievable in bulk even where it is legitimately readable.
- Scope access to the task rather than granting it standing, so the radius is closed most of the time.
In Ascent three of the four map onto the permission document and one does not. Breadth is the on_objects axis, which scopes down to a workspace, a data repository or a single record. Depth is the actions axis, because each of the four views is a separate action, so redacted reading can be granted without granting decryption. Duration is the grant: an approved grant carries an expiry and a use count, and the without_active_grant condition lets a rule apply only while no grant covers the request. Volume has no expression in policy at all — it is a workflow threshold counting requests, evaluated outside the document and not subject to deny-wins.

CONTAINER_GUID=aaaaaaaa-ea00-4015-907e-ef61a17ccad1
curl -sS -X POST "$ASCENT/api/container/$CONTAINER_GUID/freeze" \
-H "Authorization: Bearer $TOKEN"
# ...and back again
curl -sS -X POST "$ASCENT/api/container/$CONTAINER_GUID/unfreeze" \
-H "Authorization: Bearer $TOKEN"
JTI=86bc9974-2e93-474d-9798-3a656b43d7e5
curl -sS -X DELETE "$ASCENT/api/application/$APPLICATION_ID/token/$JTI" \
-H "Authorization: Bearer $TOKEN"What to do
Measure first. The reduction work is straightforward once the number exists, and it is nearly impossible to prioritize before then. If you have more than one agent, measure the one with the broadest grant rather than the one you worry about most. They are rarely the same agent.
How Ascent does this: Let AI agents use data without seeing it.