Open the permissions on the service identity your AI agent uses and you will probably find more than the job requires. It can read the table it needs, plus four it does not, plus write access nobody remembers granting. The agent works, so nobody trims it. That gap between what the agent uses and what it can do is the blast radius, and it only grows.
Least-privilege access closes that gap: the agent gets exactly the operations its task needs and nothing more. This guide enforces least-privilege access for AI agents whose identity comes from Microsoft Entra, applied at the infrastructure boundary by hoop.dev. The roles, stated clearly: Entra is the identity provider that authenticates the agent and asserts its group. hoop.dev is the relying party that reads that group and grants a narrowly scoped connection to a database or service. hoop.dev scopes the connection. Entra is the identity it trusts to do so.
Why least-privilege access erodes over time
Scopes get widened to make something work and never get narrowed once it does. An agent that needed one write ends up with full write. Multiply that across a fleet of agents and you have a large attack surface made of conveniences. Least-privilege access is not a one-time cleanup. It is a default that the system enforces on every connection, so the easy path is also the narrow one.
Scoping an agent down, step by step
Take an agent that should only read order status from a Postgres database.
- In Entra, place the agent identity in a dedicated group, for example
order-status-readers, separate from any broader group. - Configure hoop.dev to verify Entra tokens against your tenant.
- Create a hoop.dev connection backed by a database role limited to selecting from the order tables.
- Bind the Entra group to that connection, read only, with recording on.
connection: orders-read
type: postgres
db-role: orders_ro
access: group:order-status-readers
mode: read-only
record: true
The scope is enforced twice: the database role limits what the credential can do, and the hoop.dev policy limits which Entra identity can use it. The agent inherits the narrow path and cannot widen it.
Verify the agent cannot exceed its scope
Have the agent attempt a write or a read against a table outside its scope. Both should be refused, and the refusal should appear in the session record tied to the Entra identity. Then check that the legitimate read still works. One model gives the agent a broad grant and trusts it to use only part. The other gives it only the part. The recorded refusals are your proof the boundary is real.
Pitfalls
- Do not bind agents to the same Entra group humans use. Their needs differ, and shared groups grant agents human-scale access.
- Do not enforce scope only in the policy and leave the database role wide. Scope both layers.
- Do not widen the group to fix a single failed operation. Add a narrow connection for that operation instead.
Let the Entra group be the unit of scope
The reason this stays manageable is that the Entra group is the single unit you reason about. Each group maps to one scoped connection in hoop.dev, so the question of what an agent can do reduces to which group it is in. There is no per-agent exception list to maintain and no drift between what you intended and what is enforced, because the enforcement reads the live group on every connection.
When a task changes, you change the connection bound to the group, and every agent in that group inherits the new scope at once. When a new agent needs the same narrow access, you add it to the group and it gets exactly that, nothing wider. The identity provider asserts the group. hoop.dev turns that group into a bounded path to infrastructure.
hoop.dev is open source, so the policy model that enforces least-privilege access is something you can read and verify, not a claim on a slide. The getting started guide covers connecting a scoped database role, and the learn library has patterns for least-privilege access across agent fleets.
FAQ
Does Entra enforce the least-privilege scope?
Entra asserts identity and group. hoop.dev enforces the scoped infrastructure access against that identity at the connection.
Can I scope two agents differently with the same provider?
Yes. Put each agent in its own Entra group and bind each group to a separate scoped connection in hoop.dev.
Where do I start?
Get the gateway from the hoop.dev GitHub repository and bind one read-only connection to a dedicated agent group.