labs/zava-learning/sre-config/agent-config/skills/rbac-audit/SKILL.md
Use when an operator or a scheduled task requests a periodic RBAC / least-privilege audit of the Zava Learning resource group — enumerate the real role assignments effective on the group, correlate each identity against actual Activity-Log usage to find standing access that is never used, flag over-privileged and directly-assigned (versus group-governed) identities and stale troubleshooting access, and recommend least-privilege corrections. Read-only; produces findings for a report.
npx skillsauth add microsoft/sre-agent rbac-auditInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Resource Group: @@RG@@. Read-only audit — never create, modify, or remove a role assignment.
This is a weekly governance review of who can do what here, and whether they actually use it. The
goal is real least-privilege hygiene: surface over-privileged identities, direct (ungoverned)
assignments, and standing access that has gone unused so a human can clean it up.
The principals under audit (their display name / UPN / objectId and role) are the subject of this
report — show them; an RBAC finding that hides the identity is useless. This is NOT the learner-PII
the redaction standard protects. Still apply SearchMemory("zava-redaction") redact() to strip any
secrets, tokens, credentials, or learner/customer PII that happen to appear, and never print
secret values — but DO name the admins, service principals, and groups being audited.
Where the names come from (do NOT call Microsoft Graph): take the identity name from the
principalName field that az role assignment list already returns, plus principalType. Do not
run az ad user/group/sp list|show or az rest https://graph.microsoft.com/... to resolve names or
look up guest/enabled status — the SRE Agent's managed identity has no Graph directory-read
permission, so those calls fail with Insufficient privileges AND are gated as PendingAuthorization,
which would stall this unattended weekly run. If a principalName is blank, identify that principal by
its principalId (objectId) + principalType and note "display name unavailable (directory lookup not
permitted)". A UPN containing #EXT# (when present in principalName) still indicates a guest.
az role assignment list --scope /subscriptions/<sub>/resourceGroups/@@RG@@ --include-inherited -o json.principalName, principalType (User / Group / ServicePrincipal), roleDefinitionName,
scope, description, and createdOn where present. These fields are sufficient — everything you
need to name and classify a principal is already in this output; no follow-up directory calls.Standing access that is never exercised is the prime cleanup target. Pull who has actually operated in this RG and join it to the assignment list:
-g server-side filter on the activity log is unreliable here — query subscription-wide and
filter client-side on resourceGroupName == @@RG@@. Use a bounded, valid query (the API rejects
oversized requests with HTTP 400 "Bad Request"): a window of 30 days and --max-events 1000,
e.g. az monitor activity-log list --start-time <UTC now-30d> --end-time <UTC now> --max-events 1000 -o json.
If that still 400s, halve the window (e.g. 7-14 days) and/or add --query "[].{c:caller,r:resourceGroupName,t:eventTimestamp}".
Then keep events where resourceGroupName is the RG; aggregate distinct caller values (these are
UPNs or principal objectIds) with their last-seen timestamp.createdOn/description signals alone. Finishing the audit with a clear caveat is required;
stalling on usage correlation is a failure.az rest https://graph.microsoft.com/...auditLogs/signIns) — the agent identity is not permitted and
the call would stall on approval / fail. Base usage purely on the Activity Log window above.zava-audit-report model)#EXT# in principalName) or orphaned principal; a clearly temporary / break-glass grant still present (telltale
description like "temp", "break-glass", "INC-####", "troubleshooting", or an old createdOn).This subscription carries first-party security & governance service principals — do not flag them as
risky; acknowledge them as expected. These include Microsoft Defender for Cloud, Azure Policy /
remediation, AzSecPack, Wiz (Wiz*), Illumio, Connected Machine / Arc, Backup / Recovery Services,
and the SRE Agent's own managed identity and the platform's user-assigned identity (AcrPull, Key Vault
Secrets User, Network Contributor for the agent). Note them in an "expected platform identities"
appendix rather than the findings table. Focus the findings on human users and non-platform
principals.
One row per finding:
Identity (type) · Role · Scope (direct/inherited) · Governance (direct/group) · Last used · Finding · Severity · Recommendation.
Sort SEV1 → SEV3. Recommendations should be concrete least-privilege moves: remove unused standing
access; replace a direct user grant with membership in a governed group; convert standing
privileged grants to PIM eligible (JIT); down-scope from subscription to the specific RG/resource;
remove stale break-glass access. Also produce a posture summary (Healthy / Needs attention / At risk,
counts by severity, # of identities with privileged-but-unused access, the single most important
action). Cite Azure least-privilege / PIM guidance via microsoft-learn_microsoft_docs_search.
This skill does not remediate. Pass the posture summary, the findings rows (each with its severity),
and the recommendations to the zava-audit-report skill, which renders the single branded,
downloadable PowerPoint deck and returns its download link. Surface that link to the operator.
development
Use to package a completed Zava Learning incident analysis for the audience. First present a branded in-thread executive summary (markdown with the before/after visuals inline), then produce the downloadable deliverables — a PowerPoint deck, an HTML email, and a Teams notification — using the Zava corporate template. The calling agent may narrow this to a subset (e.g. only the HTML report). Produces content and artifacts; it does not send them. Assembles the output of rca-analysis, evidence-before-after, recommendations-next-steps, and pr-delivery.
development
Use to package a completed Zava Learning weekly governance audit (NSG / network security, RBAC / least-privilege, or cloud cost) into a single branded, downloadable PowerPoint deck in the Zava house style. The calling audit agent passes its findings (a list of rows with severity) and a short posture summary; this skill renders the deck, applies redaction, and returns the attachment download link. Produces the artifact; it does not send it.
development
Use whenever a Zava Learning investigation produces a durable fix that needs change management — after a GitHub PR is opened for an Infrastructure-as-Code or application code root cause, raise a ServiceNow Change Request referencing the PR and attach the RCA report. The single owner of ServiceNow Change Request and attachment operations.
development
Use whenever you are about to emit operator-visible content — a chat/thread message, a PagerDuty or ServiceNow note, a commit message or pull-request body, or any report artifact (HTML, PowerPoint, Teams card). Deterministically masks secrets, credentials, tokens, private keys, URI-embedded passwords, and PII so they never appear in the thread or in any deliverable. This is a cross-cutting guardrail invoked by the output-producing skills, not a runbook step.