|
| 1 | +The workload can authenticate. The next question is what it should be allowed to do. That answer comes from what the workload's task actually requires, mapped to the specific permission planes that control access to those resources. |
| 2 | + |
| 3 | +## Identify which permission planes the workload needs |
| 4 | + |
| 5 | +Start from the workload's task. List what it actually does: read secrets from Key Vault, call an AI services endpoint, query user profiles from Microsoft Graph, invoke an operation on a custom API. Each of those tasks maps to a different permission plane, and each plane has its own assignment mechanism, consent model, and scoping rules. |
| 6 | + |
| 7 | +- **Azure RBAC**: The workload accesses Azure resources such as storage accounts, Key Vault, or AI services. Roles are assigned at a specific scope: resource, resource group, subscription, or management group. |
| 8 | +- **Microsoft Graph application permissions**: The workload reads or writes directory data or Microsoft 365 resources. These permissions are granted on the app registration and require admin consent. |
| 9 | +- **App roles**: The workload calls a custom application or API. The target application defines the available roles. |
| 10 | + |
| 11 | +Most AI workloads touch more than one plane. A workload that reads secrets from Key Vault and queries user profiles needs both an Azure RBAC role assignment and a Graph application permission. Treating these planes as interchangeable leads to permissions assigned in the wrong place or at the wrong scope. |
| 12 | + |
| 13 | +:::image type="content" source="../media/ai-workload-least-privilege-access.png" alt-text="Diagram of an AI workload with three granted permissions and one not granted, showing least-privilege access." border="false"::: |
| 14 | + |
| 15 | +## Right-size Azure RBAC role assignments |
| 16 | + |
| 17 | +The principle is straightforward. Find the narrowest built-in role that covers what the workload actually does, and assign it at the resource level. In practice, "what the workload actually does" is often broader than expected when AI workloads span multiple services. |
| 18 | + |
| 19 | +Assigning Contributor at the subscription level when the workload only needs to read from a single storage account grants write access to every resource in the subscription. The same over-privilege happens at the resource group level. An AI workload that only needs to read secrets from Key Vault and call an Azure OpenAI endpoint doesn't need write access to every resource in the group. Resource-level role assignments for those specific services cover the actual workload task. |
| 20 | + |
| 21 | +For AI services specifically, the distinction between inference and management matters for role selection. A workload that sends prompts and receives completions needs only inference access. A workload that also deploys or deletes models needs management access. These are different roles with different blast radii. The specific role choices come into play when assigning access to Azure AI services, Key Vault, and storage. |
| 22 | + |
| 23 | +Can you name every Azure resource your workload accesses and the specific operation it performs on each? If not, the RBAC assignments aren't ready yet. |
| 24 | + |
| 25 | +## Scope Microsoft Graph application permissions to the workload's task |
| 26 | + |
| 27 | +Graph application permissions apply tenant-wide, so each one should be justified by a specific workload task. Choosing the right scope matters here because Graph permissions vary widely for what sounds like similar access. |
| 28 | + |
| 29 | +A workload that reads user profiles for grounding data needs `User.Read.All`. `Directory.Read.All` would also work, but it grants access to groups, roles, and other directory objects the workload doesn't need. `Directory.ReadWrite.All` grants write access that most AI workloads should never have. The difference between "reads user profiles" and "reads and writes the entire directory" is one permission selection. |
| 30 | + |
| 31 | +Every Graph permission should map to a specific workload operation. If a permission doesn't map to something the workload actually does, it shouldn't be on the app registration. For SharePoint access specifically, use the `Sites.Selected` permission to limit access to specific site collections rather than all sites in the tenant. |
| 32 | + |
| 33 | +## Evaluate app roles before assigning them |
| 34 | + |
| 35 | +App roles apply when the workload calls a custom application or API. Unlike RBAC and Graph, the target application's developer defines the available roles. That means you need to understand what the roles actually grant before assigning them. |
| 36 | + |
| 37 | +If the target application exposes a single broad role like "Application.FullAccess," that role might grant more operations than your workload needs. Ask the application owner whether narrower roles exist or can be created. Accepting a broad role because it's the only one available carries the same over-privilege risk as assigning Contributor at the subscription level. |
| 38 | + |
| 39 | +App roles are scoped to the target application, so they don't grant access to Azure resources or Microsoft Graph. Each permission plane must be configured independently. |
| 40 | + |
| 41 | +## Record why each permission exists |
| 42 | + |
| 43 | +When someone reviews this identity six months from now, or during an incident, they need to understand what access was granted, why, and whether it's still justified. Without that record, excess permissions persist because no one can determine whether they're needed. |
| 44 | + |
| 45 | +For each permission assignment, record: |
| 46 | + |
| 47 | +- Which identity holds it |
| 48 | +- Which role or permission was assigned |
| 49 | +- The resource boundary or scope |
| 50 | +- The workload task it supports |
| 51 | +- When it was assigned |
| 52 | + |
| 53 | +This record is what makes future access reviews possible without re-investigating every permission from scratch. |
0 commit comments