RBAC and PIM for Spokes¶
A spoke gets four Entra ID groups (Owners, Contributors, Readers, Support) and a service principal. This page explains how those groups get their Azure rights, which rights are standing and which are activated through Privileged Identity Management (PIM), and how to change that. The consumer's view is in Access, groups and PIM.
Two layers of access¶
| Layer | Scope | Controlled by |
|---|---|---|
| Subscription roles | The whole subscription | Fixed by the spoke canvas: Owners = Owner, Contributors = Contributor, Readers = Reader. The spoke service principal is a permanent member of Owners. |
| Role map | The whole subscription, for specific roles | A built-in role map that you can override. Used for roles such as Key Vault and Storage data-plane roles. |
The membership of the team in each group comes from ProductTeamGroupNames and the PIM profile in PIMGroupConfig
(Spoke JSON reference).
PIM profiles¶
A profile decides how the team's group becomes a member of a spoke group. Profiles are defined in pim_configurations
(Spoke common settings) and referred to by name.
| Profile | Membership of the team group | Approval |
|---|---|---|
nopim |
Permanent (active assignment). No request needed. | None |
self-approve |
Eligible. The user activates it in PIM. | None |
approval |
Eligible. The user activates it in PIM. | Required |
PIMGroupConfig sets one profile for each of Readers, Contributors and Owners. The Support group is not
configurable: the deployment logic sets it.
A typical pattern, as used in one implementation (an example, not a rule):
| Group | Dev and test | Acceptance and production |
|---|---|---|
| Owners | Eligible, with approval | Eligible, with approval |
| Contributors | Eligible, automatic approval | Eligible, with approval |
| Readers | Permanent | Permanent |
Support group¶
The Support group has no rights of its own. During support hours (outside office hours) it is made a member of the Owners group. People in the Support group can then use PIM to activate Owner, but only outside office hours.
The role map¶
The role map grants Azure roles through a standing or PIM-eligible assignment at the subscription scope. One assignment covers every matching resource in the subscription, whether or not the resource exists yet. It does not depend on the subscription roles above. Any built-in Azure role can be used, not only data-plane roles.
By default:
| Group | Key Vault and Storage Account data plane |
|---|---|
| Readers, Contributors, Owners | Standing read access (Key Vault Reader, Storage Blob Data Reader) |
| Contributors | PIM-eligible read/write roles (Key Vault Secrets, Certificate and Crypto User roles, and Storage Blob Data Contributor), self-approve profile |
| Owners | PIM-eligible full-control roles (Key Vault Secrets, Certificates and Crypto Officer roles, and Storage Blob Data Owner), approval profile |
The spoke service principal also gets Key Vault Administrator on the Key Vault and blob owner rights on the storage
account when they are deployed.
Subscription scope, not per resource
The assignment is at the subscription. A Contributor who activates Storage Blob Data Contributor can read and write
blobs in every storage account in that subscription, also those that the team created later. Keep this in mind when you
decide which profile a role gets.
Override the role map¶
You can change the map for all spokes, or for one spoke. A spoke setting takes precedence over the common setting.
| Where | Setting | Applies to |
|---|---|---|
| Common settings | override_defaults.pim_assignments |
All spokes |
| Spoke file | adInfo.PIMAssignments |
One spoke |
Both are maps keyed by the exact Azure role name, for example Storage Blob Data Contributor. Each entry has two fields:
| Field | Meaning |
|---|---|
levels |
The spoke group levels that get the role, for example ["Owner"]. |
pim_profile |
The name of a profile from pim_configurations that decides how the role is granted. |
Rules:
- Set one field to change only that field. A field you leave out keeps its built-in value.
levels: []removes the role completely (for that spoke, or for all spokes when set in the common settings).- A role that is not in the built-in map must set both fields.
- No change to the Terraform modules is needed to add a role, for example a SQL or Cosmos DB data role.
Example in a spoke file: make Storage Blob Data Owner require approval for this spoke only.
"adInfo": {
"PIMAssignments": {
"Storage Blob Data Owner": { "pim_profile": "approval" }
}
}
Example that adds a role that is not built in. Both fields are required:
"PIMAssignments": {
"<exact role name>": { "levels": ["Contributor"], "pim_profile": "self-approve" }
}
Change access safely¶
| I want to | Do this |
|---|---|
| Give another team access | Add the group to ProductTeamGroupNames (Change spoke) |
| Make a group's access need approval | Change the profile in PIMGroupConfig |
| Remove standing data-plane access for one spoke | "<role>": { "levels": [] } in adInfo.PIMAssignments |
| Change a default for every spoke | override_defaults.pim_assignments in the common settings. Treat it as a platform change with review. |
Read the plan after each change. Removing a standing assignment removes access for people who work with it today.