Agent Access Enforcement
An AI agent can inherit a person’s access in minutes. The platform could show that it had happened — it couldn’t stop it. This is how a one-off block became a rule, and why no rule goes live until it has been run against production first.
- Scope
- Condition
- Action
- Dry run
- 14 agents — blocked, no recent activity
- 2 agents — ran in the last 24 hours
- 1 agent — holds a scheduled production job
Scope of the work — not performance claims
The Problem
Visible, and still not stoppable
The platform was good at showing that an AI agent held access it shouldn’t. Doing something about it meant leaving the platform, opening someone else’s console, and revoking by hand — without being able to see what that would break.
So it mostly didn’t happen. Findings were acknowledged and deferred, quarter after quarter. The gap wasn’t detection. It was that nobody could be sure enough to act.
Access Review Sessions
Watched the people who sign off quarterly access reviews work through a list that now included agents.
- Agents arrived with no named owner to ask
- Nobody could say which were still in use
- Removal was deferred rather than decided
Ticket & Incident Review
Traced what actually happened the handful of times an agent’s access was pulled.
- Every block was manual and one agent at a time
- Blast radius was discovered after the revoke
- Rollback meant re-granting permissions by hand
Engineering Walkthrough
Established what enforcement can promise, and at which moment it can promise it.
- The block executes in the source system, not ours
- Confirmation is asynchronous and can fail hours later
- Identity attributes are reliable; ownership is not
Constraints
Three facts about enforcement that decided the shape of the flow
The undo isn’t symmetrical
Blocking takes one click. Restoring means re-granting each permission by hand, in the source system, and any job that failed in between has already failed.
Ownership is usually missing
Agents are created by automation and inherit their access from a human, a service account, or another agent. More often than not there is no person to route the decision to.
We don’t own the moment of enforcement
The rule is written here and executed elsewhere. The target system can accept it, partially apply it, or reject it — and tell us hours later.
The hard part was never writing the rule. It was letting someone be certain before they were committed.
Decisions
What I considered, what I chose, and what made the difference
Select agents from a list and block the selection.
A rule keyed on identity attributes, with the matched set resolving live underneath it.
A saved list is stale the moment it’s saved. Agents are created continuously, and the access that matters most belongs to the one that doesn’t exist yet.
An optional “preview matches” link beside the save button.
A dry run as the mandatory fourth step. The rule cannot be activated until it has run against production data.
Constraint 01. A preview you’re allowed to skip is the one that gets skipped on the day it mattered — and the cost of the wrong rule is a live workflow stopping mid-run.
A one-time action on the agent row — press it and it’s done.
A rule as a persistent object with its own lifecycle and six named states.
Enforcement is continuous, not an event. A state a rule can sit in is a state someone can be shown, alerted on, and asked to review.
Retry quietly in the background and keep the rule showing as active.
“Failed to land” as a first-class state on the rule, carrying the reason the target system gave.
Constraint 03. A rule that reports active while the block was rejected is worse than no rule — it removes the reason to check.
Draft
Scope and action set. Nothing is enforced and nothing is promised.
Dry run complete
Matched set resolved against production, timestamped. Activation unlocks here.
Active
Applied and confirmed by every target system in scope.
Partially applied
Landed in some systems, not others. Names which, and why.
Failed to land
Rejected downstream. The rule exists; the block does not.
Retired
Turned off deliberately, with the matched set it last held kept on record.
States 04 and 05 are the two that don’t appear in any happy-path spec — and they’re the reason the lifecycle exists at all.
A dry run has a date on it
The result is stamped with when it ran and against what. If the environment has changed since, the rule re-flags and asks for a fresh run rather than quietly activating on a week-old picture.
Blocked is not deleted
The rule stops access; it never removes the identity. The word “block” is used at every step — in the builder, on the rule, in the audit entry — so nobody has to guess whether something is recoverable.
Outcome
What shipped, and what it changed
Enforcement moved inside the platform
The block is written where the finding is read. No second console, no manual revoke, no gap between noticing and acting.
A rule that catches the agent created tomorrow
Attribute-based scope means enforcement doesn’t decay between access reviews the way a saved list of names does.
Certainty before commitment
Every rule shows what it would do, against real data, before it is allowed to do it — and flags the matches that carry real risk instead of returning a count.
Failure that says so
Six states, two of them failures with names. A rule can no longer look like it’s protecting something it isn’t.
What I’d do differently
I designed the creation flow before the rules list. But the list is where you land when something has already gone wrong, and it got the last two weeks instead of the first. Next time I’d design the screen you open under pressure first, and let the builder inherit its vocabulary — not the other way round.
All visuals rebuilt with synthetic data. Product and vendor names withheld under NDA.