Azure-Samples / Azure-Samples/azuresandbox
PIM JIT elevation (Reader -> Owner) with approval for the CD runner identity
- Dominant language
- PowerShell
- Stars
- 154
- Forks
- 75
- Avg merge
- 15h 2m
- Merged PRs (30d)
- 45
Description
## Summary
Prerequisite for #173 (CD). Provide a **least-standing-privilege** RBAC path for the self-hosted
runner's managed identity, as a selectable alternative to standing **Owner**, so both paths can be
exercised by the CD workflow.
## Background
The sandbox apply **writes role assignments** and **creates/populates AAD groups**, so during the
apply window the runner identity needs **Owner** (or **User Access Administrator + Contributor**) at
subscription scope — **Reader alone cannot apply**.
Two RBAC modes (the #173 workflow should select between them via an input, e.g.
`rbac_mode = standing_owner | pim_jit`):
- **Option A — standing Owner (default):** permanent subscription Owner on the MI. Simple; matches
today's manual SPN; large blast radius.
- **Option B — PIM JIT (this issue):** MI holds only standing **Reader**; **Owner** is activated
just-in-time per run and requires **human approval**, then deactivates.
## Why PIM for Groups
Azure PIM activation is not a service-principal user flow. Implement via **PIM for Groups**: the MI
is a member of a **role-assignable group** that is *eligible* (not active) for subscription Owner.
A workflow step requests activation of the group's eligible Owner assignment via the **Microsoft
Graph PIM API** (`roleAssignmentScheduleRequests` / `roleEligibilityScheduleRequests`), an approver
approves, the apply runs, then the activation expires (or is explicitly deactivated).
## Acceptance criteria
- [ ] Terraform/scripted setup for the PIM-for-Groups model: role-assignable group, MI membership,
**eligible** Owner assignment for the group at subscription scope, and an **approval policy**
(approver(s), max duration, justification required).
- [ ] A reusable activation step/script: request Owner activation via Graph PIM API with
justification, poll until approved/active (timeout + clear failure), usable from the #173
workflow before `terraform apply`.
- [ ] A deactivation/teardown step that ends the activation after apply (and on failure/cancel).
- [ ] Selectable from the #173 workflow via `rbac_mode` so **both** standing-Owner and PIM-JIT
paths can be tested; standing-Owner remains the default.
- [ ] Requires Microsoft Entra ID **P2**; documented prerequisite. README/docs updated.
- [ ] The MI's **Graph app permissions** (User.Read.All, group management) remain standing,
least-privilege scoped (out of scope for JIT) — documented.
## Notes
- Coordinates with #173 (consumer), #499 (runner host / MI), #496 (secretless auth).
Contributor guide
Research direction
Start by reading the consumer workflow in #173 and the coordination notes for #499 and #496. Define the Terraform/scripted setup and reusable activation and teardown steps around the stated PIM-for-Groups and Graph API requirements, then verify the rbac_mode selection, approval behavior, failure cleanup, P2 prerequisite, and README/docs updates against the acceptance criteria.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, powershell, terraform
- Domain
- authorization, cloud, devops, infrastructure, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100