Skip to content

Quarterly Service Principal Permission Review

Status: Runbook Owner: Infrastructure (Kobe executes, Rory approves all scope changes) Schedule: First business day of January, April, July, October (aligned with SP cleanup) Related: quarterly-sp-cleanup.md, lpriv-baseline.md

Purpose

Verify every service principal holds only the minimum permissions needed for its documented purpose. Over-privileged SPs are a HIPAA least-privilege finding and an elevated compromise risk.

Review Criteria

For each SP with Owner, Contributor, or any other broadly-scoped role:

  1. Does it have documented automation duties?
  2. Do those duties require the assigned role, or would a scoped role suffice?
  3. Is there a custom role in iam.tf that would be a better fit?
  4. Is the assignment's scope correct (subscription-wide vs RG-scoped vs resource-scoped)?

Any SP holding a broader role than required = reduction candidate. Scope reductions require Rory's explicit approval.

Procedure

1. Enumerate role assignments

az login --tenant <tenant>
az role assignment list --all --query "[?principalType=='ServicePrincipal'].{sp:principalName, role:roleDefinitionName, scope:scope}" -o json > /tmp/sp-roles.json

Per subscription if the global query is too large:

for sub in $(az account list --query "[].id" -o tsv); do
  az role assignment list --subscription $sub --all --query "[?principalType=='ServicePrincipal']" -o json > /tmp/sp-roles-$sub.json
done

2. Classify role breadth

Flag assignments with:

  • Owner role (full control including RBAC)
  • Contributor role (full control excluding RBAC)
  • User Access Administrator role
  • Subscription-level scope on any role
  • Management-group-level scope on any role

3. OIDC deploy SPs

OIDC SPs used by GitHub Actions CI/CD should hold only the custom github-deploy-main role (defined in azure-infra/main/iam.tf and equivalent per stack). Any broader role = reduction target.

SPIntended RoleExpected Scope
github-deploy-appgithub-deploy-mainPer-subscription
github-deploy-ddegithub-deploy-mainDDE main + billings
github-deploy-awsAWS role github-deploy-mainPer-account

4. Arctic Wolf SP

Arctic Wolf has its own custom roles in iam_arctic_wolf.tf and iam_arctic_wolf_roles.tf. Verify it is not also holding Contributor or Reader at subscription scope.

5. Kobe SPs

SPExpected Role
kobe-cloud-pcCustom scoped role (CloudPCRole)
kobe-security-auditReader (subscription-scoped, read-only)

6. Permissions diff report

For each candidate capture:

  • Current role + scope
  • Proposed role + scope
  • Justification (what duties require this level of access)
  • Risk of reducing (what would break)

Write report to /tmp/sp-permission-review-<YYYYQN>.md.

7. Approval

Post to SecOps:

POST /api/changes

Body: proposed scope changes. Tag Rory. Wait for explicit approval.

8. Apply reductions (only after approval)

Scope reductions happen in Terraform (preferred):

az role assignment delete --assignee <appId> --role "Contributor" --scope "/subscriptions/<sub>"
az role assignment create --assignee <appId> --role "github-deploy-main" --scope "/subscriptions/<sub>/resourceGroups/<rg>"

For Terraform-managed assignments: open a PR updating iam.tf.

9. Evidence

aws s3 cp /tmp/sp-permission-review-<YYYYQN>.md s3://cirius-hipaa-evidence/sp-permission-review/<YYYYQN>/
curl -s -X POST -H "X-API-Key: $SECOPS_API_KEY" -H "Content-Type: application/json" \
  -d '{"evidence_type":"sp-permission-review","period_start":"<ISO>","period_end":"<ISO>","s3_key":"sp-permission-review/<YYYYQN>/sp-permission-review-<YYYYQN>.md","source_system":"PROD"}' \
  https://soc.bedrockcybersecurity.org/api/evidence

Success Criteria

  • [ ] All SP role assignments enumerated across both tenants
  • [ ] Broad-scope assignments classified and justification requested from owner
  • [ ] OIDC SPs confirmed holding only github-deploy-main
  • [ ] Reduction candidates compiled and sent to Rory
  • [ ] Approved reductions applied via Terraform PR
  • [ ] Evidence uploaded and registered

Schedule

Aligned with SP cleanup: Q1 January, Q2 April, Q3 July, Q4 October.

Change Log

DateChangeAuthor
2026-04-16Initial runbookKobe

Internal use only — Cirius Group