Skip to content

Workload Identity Vending

Workloads need machine identities all the time: an app reading a database, a function writing to storage, a job calling an API. Sending each one through the platform team's Lane A process would make the platform a bottleneck. It also isn't necessary. Most workload identities can be managed identities that the workload's own pipeline creates, inside its own subscription, within guardrails.

Status: planned

Workload pipelines can create managed identities today, because they hold Contributor on their own subscription. The guardrails below are not yet in place: a constrained role-assignment identity, the approved role list, and enforced naming and tagging policy.


Lane A or Lane B?

Lane A (a request to the platform team) if the identity needs any of these Lane B (the workload pipeline) if it meets all of these
An Entra ID app registration or service principal It is a managed identity (user-assigned or system-assigned)
Microsoft Graph permissions or Entra ID directory roles It needs no Graph permissions and no directory roles
Azure roles at management group scope, or in another subscription All its roles are within the workload's own subscription
Privileged roles (Owner, User Access Administrator, RBAC Administrator) Its roles come from the approved list below

Prefer system-assigned identities

Type Use when
System-assigned One resource needs the identity. It is created and deleted with the resource, so it is never left behind. This is the default.
User-assigned Several resources share it, it must exist before the resource does, or GitLab signs in with it through a federated credential

Guardrails

1. A constrained role-assignment right

Creating a managed identity is easy. The risk is in what it is granted. The workload's role-assignment identity should hold Role Based Access Control Administrator on its own subscription, with a condition that limits:

  • which roles it can assign, to the approved list only;
  • which principal types it can assign to (ServicePrincipal, which covers managed identities).

That way a compromised workload pipeline can't grant Owner, or give itself more rights than the list allows.

2. The approved role list

Role Typical use
Reader Read-only monitoring or discovery
Storage Blob Data Reader / Contributor Apps reading or writing blobs
Key Vault Secrets User Apps reading secrets at runtime
Azure Service Bus Data Sender / Receiver Messaging
Monitoring Metrics Publisher Custom metrics
AcrPull Pulling container images

Add to the list by MR to the platform. Never add Owner, User Access Administrator, Role Based Access Control Administrator or Contributor.

3. Policy and detection

  • Naming and tags on Microsoft.ManagedIdentity/userAssignedIdentities, through the tagging standard.
  • Governance reporting (AzGovViz, the RBAC extract) flags any role assignment outside the approved list. See Governance Reporting.
  • Federated credentials on user-assigned identities are limited to the workload's own GitLab project path.

Why this is safe in Lane B

The worst case of a compromised workload pipeline is limited to one subscription, and that pipeline already has Contributor there. A managed identity:

  • is an Azure resource, not an Entra ID object, so creating one doesn't write to the directory;
  • can't have a secret added to it, so the "add a credential and keep access" attack doesn't apply;
  • can only be granted roles from the approved list, within the subscription.

That adds very little risk beyond what the pipeline already has, and removes a queue from the platform team.