Azure-Samples / Azure-Samples/azuresandbox

PIM JIT elevation (Reader -> Owner) with approval for the CD runner identity

Open
#500 0 comments 0 reactions 0 assignees View on GitHub
enhancement
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.