
PLAYBOOK
Managing Agent Permissions at Scale
Azure caps a subscription at 5,000 role assignments and will not raise it. The quota ceilings, propagation delays and review mechanics that decide how many agents you can actually govern.
TL;DR
The thing that stops a growing agent fleet is not judgment. It is arithmetic, and the numbers are published. Azure supports up to 5,000 role assignments per subscription and Microsoft's own documentation says that limit "is fixed and cannot be increased". A Google Cloud allow policy holds 1,500 principals. An AWS managed policy stops at 6,144 characters and a role accepts 20 of them by default.
Grant one bespoke identity and one bespoke policy per agent and you can compute, today, the agent count at
which your provisioning starts returning RoleAssignmentLimitExceeded. Nobody in that conversation will
have made a bad security decision.
The usual framing says the problem at scale is consistency, and templates fix it. Templates do help, and NIST documented the reason they eventually stop helping twenty years ago: pushing per-request context into static roles produces roles "that are ad hoc and limited in membership, leading to what is often termed 'role explosion'".
We are not arguing against templates. We are arguing that a template is a source artifact, not an enforcement point, and that the enforcement points have ceilings, propagation delays and review mechanics you have to design around.
What to do this week: count your assignments against each provider's published quota, move per-agent grants onto groups so one assignment covers many principals, and turn on the usage reports that already exist. Google's IAM recommender compares granted permissions against the last 90 days of use, and AWS reports unused roles and unused actions without you writing anything.
Overview
Managing permissions for one agent is tractable. You know what it does, you know what it touches, and the access it holds fits in a paragraph. Somewhere between the tenth agent and the hundredth, that stops being true, and the techniques that worked for one agent quietly stop scaling.
A longer checklist does not fix this, and neither does more care. The gap between "each agent looks fine" and "the fleet is actually governed" is partly organisational, and partly the platforms refusing to hold what you are asking them to hold. Only the first half gets written about.
This post is about the mechanics: the published ceilings, the delay between changing a grant and the change taking effect, and what review and usage data can tell you. What permissions an agent should hold is a separate question, covered in our posts on agent authorization and permission models. Here we assume you decided correctly and now have to do it four hundred times.
The shift at scale is from decisions people make one at a time to a system that keeps making them consistently. A permission model that lives in someone's memory or a spreadsheet does not survive the tenth team, let alone the hundredth agent.
The Ceilings You Will Hit
Start with the numbers, because they set the shape of everything else. These are the published, current quotas on the three clouds most agent fleets touch.
| Limit | Value | Adjustable |
|---|---|---|
| Azure role assignments per subscription | 5,000 | No. "Fixed and cannot be increased" |
| Azure role assignments per management group | 500 | No, also documented as fixed |
| Azure custom roles per directory | 5,000 (2,000 for Azure operated by 21Vianet) | Not documented as adjustable |
| Google Cloud principals per allow policy | 1,500 across all role bindings and audit-logging exemptions | No |
| Google Cloud domains and groups per allow policy | 250 | No |
| Google Cloud custom roles | 300 per organization, 300 per project | No |
| AWS managed policies attachable per role | 20 by default | Yes, to 25 |
| AWS customer managed policies per account | 1,500 by default | Yes, to 10,000 |
| AWS managed policy document size | 6,144 characters | No |
| AWS inline policy total per role | 10,240 characters | No |
| AWS roles per account | 1,000 by default | Yes, to 10,000 |
Table 1 — Published ceilings, read from each vendor's own quota pages. The Azure numbers are the ones to design around, because they are the ones the vendor says it will not raise.
Two of these rows change architecture rather than capacity planning.
The Azure subscription limit is the sharpest. Five thousand sounds like plenty until you notice it counts assignments at subscription, resource group and resource scope together, and that the fix Microsoft recommends first is to stop assigning roles to principals at all: "add principals (users, service principals, and managed identities) to groups and assign roles to the groups instead." One assignment for a group of four hundred agents costs what one assignment for one agent costs. Not a tidiness preference. The only version that fits.
The AWS policy-size limit bites differently. A managed policy caps at 6,144 characters with whitespace excluded, and a role holds 20 of them by default. Writing one tightly scoped policy per agent archetype is fine. Writing one per agent, with resource ARNs enumerated inline, runs into a character count that no quota increase will lift.
Design the grant so that adding the four-hundredth agent adds no new objects. A new principal in an existing group, mapped to an existing role, is free. A new role with a new policy and a new assignment is a decrement against a ceiling you cannot raise.
Templates, and What They Cannot Encode
Most agents fall into a small number of recognisable archetypes, and each archetype has a predictable access pattern worth capturing once. An HR onboarding agent reads role definitions, creates directory accounts and assigns starter groups, but never touches payroll. A procurement intake agent reads vendor catalogues and drafts purchase requests, and cannot approve spend or edit a contract. A data analytics agent queries read-only replicas and writes to a sandbox schema.
A template is a small, version-controlled artifact that security reviews once and teams adopt without re-litigating every grant.
template: procurement-intake
version: 3
tools:
- vendor-catalog:read
- purchase-request:draft
data:
- suppliers:read
- contracts:read
denied:
- spend_approval
- contract_modify
review_cadence: quarterlyThe templates become the unit of governance. Instead of auditing thousands of individual grants, a team audits a few dozen templates and checks that agents map cleanly onto them. Exceptions become visible because they break the pattern.
What a template cannot do is encode the part of the decision that depends on the specific request. A finance-reporting agent can read and summarise ledger data all day; the action that deserves a second look is one transfer above a threshold, or one touching a flagged account. NIST SP 800-162 describes what happens when you try to push that sort of context into static role definitions anyway. It "would require the creation of numerous roles that are ad hoc and limited in membership, leading to what is often termed 'role explosion'", which is exactly how a clean set of eight templates becomes three hundred and then hits Google Cloud's 300-custom-role limit.
So keep templates coarse and put request-specific checks at the call. And treat exceptions as data rather than folklore: when a request is stopped by a condition no template anticipated, record why and route it to an owner. An exception that fires once is a one-off. The same one across forty agents is a template that is wrong.
Where a Permission Lives
Every template line has to land somewhere real, and the choice of where changes what you can review, how
fast you can take it back, and what the ceiling is. This is the decision we would make explicitly rather
than by default. The Agent Access Control Taxonomy asks it as one dimension: the first four rows below land
in the target system (aact:enforcement-point/target-system), the last in a gateway
(aact:enforcement-point/gateway).
| Enforcement point | Granularity | How fast you can take it back | Ceiling to watch |
|---|---|---|---|
| Cloud IAM role assignment | Resource and action | Minutes, not instant. Azure documents up to 10 minutes for assignment changes to take effect | 5,000 per Azure subscription; 1,500 principals per Google allow policy |
| Directory group membership | Whatever the group's roles grant | Slowest. Azure warns managed-identity group changes can take "several hours" because the backing cache holds per resource URI for around 24 hours | Group count, plus Entra access reviews not supporting groups over 600 users |
| Provider OAuth scope | Per API family, per consenting user | Depends on the provider's revocation endpoint, and clearing your own copy is not revoking the grant | Scope vocabularies are the provider's, so you cannot subdivide below them |
| Service account with domain-wide delegation | The whole domain | Manual, and the blast radius is everyone | Google states plainly that "the app has access to the data belonging to all of your users" |
| A broker in front of the tool call | Per action, per user, per agent | Immediate, because you own the decision | Your own availability, and the discipline to keep it on the only path |
Table 2 — The same permission, enforced in five places, with what each one costs you operationally.
Two rows deserve emphasis. Domain-wide delegation is the one people reach for when per-user consent feels slow, and Google's own documentation is unusually direct about what it buys: permission "to access your Workspace users' data without requiring their consent." At fleet scale that is one object to manage and one compromise to regret. Google's mitigation advice is a "regular review of service accounts" and periodically removing scopes that are not actively used, which is a review burden, not a technical boundary.
The broker row is the only one that gives per-action, per-user decisions with immediate effect, and MCP's 2026-07-28 revision assumes it. The tool list a server returns "MAY vary by the authorization presented on the request, for example, returning only the tools the caller's granted scopes permit", because credentials are per-request input rather than connection state. That is the mechanism that makes an intersection of user scopes and agent scopes expressible at all.
Bind Permissions to Lifecycle State
Permissions should track where the agent actually is. An agent in early experimentation has no business holding the access of one that has been reviewed and promoted.
Figure 1 — Permission scope should expand and contract with lifecycle state, not sit fixed from the day the agent was created.
A legal contract-analysis agent under development reads from a sample document set, not the live matter repository. It gains read access to active matters once it is reviewed against its template. As it winds down, high-impact scopes come off first. Once it is decommissioned, permissions are removed rather than left dormant.
The decommissioned state is the one that matters most and gets neglected most often. An agent that is no longer running but whose access was never pulled is an unmonitored path into your systems.
The transitions are also where the interesting bugs live, and they are not all yours. Azure documents that role assignment changes can take up to 10 minutes to take effect, and that changes to a managed identity's group or role membership can take "several hours" because the backing services cache per resource URI for around 24 hours. A demotion is not a demotion until the cache expires. OWASP's Identity and Privilege Abuse entry gives the agent-shaped version of this, which it calls workflow authorization drift: a procurement agent validates approval at the start of a purchase sequence, the user's spending limit is reduced hours later, "but the workflow proceeds with the old authorization token, completing the now-unauthorized transaction."
That is a straightforward argument for short credential lifetimes over careful revocation. NIST's zero trust tenets say the same thing from the other direction: access is granted "on a per-session basis", and "all resource authentication and authorization are dynamic and strictly enforced before access is allowed." A long-lived grant you can revoke quickly is still worse than a short-lived one that expires on its own.
Automated Reviews
Permissions decay. Agents accumulate access for tasks they no longer perform, and a scope justified six months ago becomes standing risk nobody is looking at.
Reviews should be risk-weighted. An agent with read-only access to a marketing calendar can be reviewed lightly. A security-operations agent that can quarantine endpoints, or a sales agent that can issue customer credits, needs a tighter cadence and a named owner who attests that each permission is still necessary.
The mechanics already exist in the identity platforms, and knowing their edges keeps you from trusting them too far. Microsoft Entra access reviews can recur weekly, monthly, quarterly or annually, and can attach decision helpers. The inactive-user helper marks a principal inactive when it has not signed in to the tenant within the last 30 days and gives it a recommended action of Deny, with the sign-in date evaluated once "when the review begins" and not updated while the review runs. For reviews of application assignments it checks activity in the app instead of the tenant. Useful, and two caveats matter at fleet scale: the machine-learning affiliation helper does not support groups with more than 600 users, and a recommendation stays a suggestion until someone acts on it.
A review that depends on someone remembering it will not happen consistently across a fleet. A review the system initiates and tracks will. Silence should narrow access, not preserve it.
Usage Monitoring
Reviews ask owners what access they think they need. Usage data shows what was actually exercised, and the gap between granted and used is the cheapest path to least privilege that does not break anything.
Both large clouds will compute that gap for you. Google Cloud's IAM recommender "generates policy insights
by comparing a principal's total number of permissions with the permissions that the principal used in the
last 90 days", and it treats service accounts like any other principal. It also emits lateral movement
insights, which flag roles letting a service account in one project impersonate one in another project
through permissions such as iam.serviceAccounts.actAs. For a fleet where agents call other agents, that
second signal is the more interesting one.
On AWS, an unused access analyzer "continuously monitors all IAM roles and users" and reports unused roles, unused access keys and unused passwords, plus unused services and actions for roles that are still active. IAM Access Analyzer will also generate a policy from the access recorded in CloudTrail, which is a defensible way to tighten an agent that was provisioned broadly and has now run long enough to show what it needs.
Usage also surfaces the opposite problem. An agent suddenly reaching for a scope it rarely touches is worth a look, not because it is necessarily wrong, but because divergence from an agent's own history is the cheapest anomaly signal available.
The Fragmentation Problem
Everything above assumes permissions can be seen in one place. In most enterprises they cannot, and that is the hardest part of the job. Agent permissions scatter across an inventory no single team owns: SaaS platform roles, OAuth grants delegated by individual users, long-lived API keys in services, service accounts in directories, internal access lists, and cloud IAM roles.
Figure 2 — One agent, four grants, four different review owners and one of them missing. The full picture only exists once somebody correlates across all of them.
OWASP names two ways this compounds for agents specifically. Un-scoped privilege inheritance, where a high-privilege coordinator delegates without narrowing and the worker receives its full access context. And identity sharing, where an agent holds access on behalf of the person who built it and then "allows other users to leverage that identity implicitly by invoking its tools as that identity." Neither shows up in any one provider's console, because in each console the grant looks correct.
This is why permission management at scale is an operations problem rather than something one tool solves. The value comes from pulling the fragmented grants into one model where templates, lifecycle, review and usage all reference the same view of who can do what.
Where Fabriq Fits
Agentic Fabriq holds credentials per user in a vault and attaches them server-side at the moment of the call, so an agent never handles the secret. Access is default-deny across organisation, team and member, and an agent's effective tool list is the intersection of the user's scopes and the agent's, so adding an agent does not add a new object to a provider's assignment ceiling. Every call carries two identities, the agent and the acting user, and produces an audit record.
What it does not do is reach into the provider for you. Clearing a vault copy of a token is not the same act as invalidating a grant upstream, so the call to the provider's revocation endpoint is still yours to make.
Frequently Asked Questions
How many agents can one enterprise actually manage? Ask the platforms. If each agent gets its own identity and its own role assignment in one Azure subscription, the hard stop is 5,000 assignments and Microsoft says it will not raise it. Collapse principals into groups and the same subscription holds however many agents your groups do. The governable number is set by how you model the grant, not by headcount.
What is the difference between a permission template and a role? A template is a source artifact you review and version; a role is what a provider enforces. One template usually compiles into several provider-side objects, so the mapping needs writing down rather than remembering.
How often should agent permissions be reviewed? Weight it by what the agent can do rather than by the calendar. Entra access reviews support weekly through annual cadences and will pre-mark principals inactive after 30 days without a tenant sign-in, which is a reasonable default for low-impact agents. Anything that can move money or change production deserves tighter.
How do I find unused agent permissions? Use what the cloud already computes. Google's IAM recommender compares granted permissions against the last 90 days of use, including for service accounts, and AWS Access Analyzer reports unused roles, keys and actions continuously. Neither needs a pipeline first.
Does removing a permission take effect immediately? Usually not. Azure documents up to 10 minutes for role assignment changes, and several hours when the change is to a managed identity's group or role membership, because the backing cache holds per resource URI for around 24 hours. Plan for a window in which the old grant still works, and prefer short credential lifetimes to fast revocation.
Should an agent inherit the permissions of the user who created it? Not implicitly. OWASP lists identity sharing, where an agent holds its maker's access and other people invoke tools as that identity, as an example of privilege abuse. Carry both identities per call and compute the intersection instead.
What happens when we hit a role assignment limit? Azure returns RoleAssignmentLimitExceeded for
assignments and RoleDefinitionLimitExceeded for custom roles. The documented remedies are group-based
assignments, removing redundant assignments at lower scopes, combining several built-in roles into one
custom role, making assignments eligible through Privileged Identity Management, and adding a subscription.
Only the last of those buys time without improving the model.
Is domain-wide delegation a reasonable shortcut for an agent fleet? It is a shortcut with the widest possible blast radius. Google's own documentation says the app gets "the data belonging to all of your users" without their consent, and offers scope review rather than a narrower boundary. We would use per-user credentials.
Permissions as Infrastructure
At enterprise scale, permission management cannot depend on memory or a spreadsheet that is accurate the day it is written. The number of agents, how fast they get created, and the breadth of systems they touch outrun manual control, and the providers stop cooperating at numbers you can look up in advance.
The organisations that stay in control treat permissions as infrastructure. Templated for consistency, mapped deliberately onto enforcement points whose ceilings and delays are known, bound to lifecycle so they expire on their own, reviewed by a system rather than a reminder, and checked against usage.
Managing permissions for one agent is a decision. Managing them for a fleet is a system, and the first test of that system is whether adding an agent costs you a new object. If it does, the arithmetic decides how far you get.
Sources
All URLs read 2026-09-29.
- Agent Access Control Taxonomy — the enforcement-point dimension, whose four terms are the places a permission can actually be checked: the prompt, the agent's own code, a gateway, and the target system.
- Troubleshoot Azure RBAC limits — the 5,000 role assignments per subscription and 500 per management group, both stated as fixed, the 5,000 custom roles per directory, the two error codes, and the group-based remedy.
- Troubleshoot Azure RBAC — up to 10 minutes for role assignment changes, and the managed-identity cache held per resource URI for around 24 hours.
- IAM and AWS STS quotas — managed policies per role, customer managed policies per account, the 6,144-character managed policy and 10,240-character inline role policy limits, and roles per account.
- Google Cloud IAM quotas and limits — 1,500 principals per allow policy, 250 domains and groups, and 300 custom roles per organization and per project.
- Google Cloud IAM recommender overview — recommendations computed against the last 90 days of permission use, and lateral movement insights for service account impersonation.
- Using AWS IAM Access Analyzer — continuous monitoring of all roles and users, findings for unused roles, keys and actions, and policy generation from CloudTrail activity.
- What are access reviews? (Microsoft Entra ID Governance) — recurring review cadences and where each review type is created.
- Review recommendations for access reviews — the 30-day inactivity definition, the Deny recommendation evaluated at review start, and the 600-user ceiling on affiliation recommendations.
- Control API access with domain-wide delegation (Google Workspace) — access to all users' data without their consent, and the recommendation to review service accounts and scopes regularly.
- NIST SP 800-162, Guide to Attribute Based Access Control — the mechanism behind role explosion when per-request context is pushed into static roles.
- NIST SP 800-207, Zero Trust Architecture — tenet 3 on per-session access and tenet 6 on dynamic authorization enforced before access.
- OWASP Top 10 for Agentic Applications, v1.0 — ASI03 on un-scoped privilege inheritance, workflow authorization drift and identity sharing.
- MCP specification 2026-07-28: Tools — the tool set varying by the authorization presented on the request, since credentials are per-request input rather than connection state.