Use when preparing or running a user access review, checking that leavers lost their access, finding orphaned or ownerless service accounts, answering an auditor's access-control request for SOC 2, ISO 27001, PCI DSS, HIPAA or NIST 800-53, or checking whether a finished review campaign will hold up. Diffs the HR roster against account exports, tests the campaign for coverage, self-review, unremoved revokes and rubber-stamping, and maps every exception to the controls it breaks.
87%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Portability: 3 stdlib scripts, no network, no IdP or HR connection. Export CSV, run, keep the output as evidence. Not audit advice. Periods and thresholds are your policy; the scripts make you state them.
Access reviews fail audits in four ordinary ways: the review ran on an incomplete export, someone approved their own access, a revoke was decided and never carried out, and leavers kept working accounts nobody looked at. Each script catches one class of these before the auditor does.
# 1 - Diff: who has access that the HR roster says they should not?
python scripts/access_diff.py --roster hr_roster.csv --accounts accounts.csv \
--inactive-days 90 --privileged-review-days 90 --as-of 2026-10-31
# 2 - Campaign: did the review cover everything, and did the revokes happen?
python scripts/access_review_campaign.py --decisions campaign.csv --population accounts.csv \
--remediation-days 10 --close-date 2026-10-20
# 3 - Map: which controls do the exceptions break, and what evidence do you keep?
python scripts/control_evidence_mapper.py --diff diff.json --campaign campaign.json --framework soc2,iso27001Step 1 joins each account to the roster on employee ID, then email. A terminated person with an enabled account is a blocker; one who logged in after their exit date is a worse one. Accounts that match nobody are orphans; service accounts need a named owner. Inactivity and privileged-review age use your periods.
Step 2 checks the campaign against the export it was built from. An enabled account missing from the campaign means the review did not cover the population, whatever the sign-off sheet says. It also catches undecided lines, self-review, revokes not removed inside your window, late decisions, and a reviewer who kept every line of a large batch at machine speed.
Step 3 turns findings into a per-control table: FAIL, EXCEPTIONS, NO_EXCEPTIONS, PARTLY_TESTED, NOT_TESTED or NOT_COVERED, each with what an auditor tests and the evidence to keep. There is no PASS.
--inactive-days and --remediation-days have no default. PCI DSS 8.2.6 says 90 days; your policy may differ.| Script | Role | Exit codes |
|---|---|---|
scripts/access_diff.py | Roster vs account export: leavers, orphans, ownerless service accounts, movers, privileged review age, inactivity | 0 clean · 2 findings · 3 bad input · 4 blocked |
scripts/access_review_campaign.py | Population coverage, undecided, self-review, unremoved revokes, late decisions, rubber-stamp signal | 0 · 2 · 3 · 4 incomplete |
scripts/control_evidence_mapper.py | Findings → per-control status for ISO 27001, SOC 2, NIST 800-53, PCI DSS, HIPAA, SOX IPE | 0 · 2 exceptions · 3 · 4 fail |
All support --help, --sample and --output json.
references/joiner_mover_leaver_standards.md — what each framework requires for provisioning, change and removal (7 sources)references/access_review_campaigns.md — population, reviewers, cadence, remediation, what auditors reject (6 sources)references/control_crosswalk.md — finding codes to controls across six frameworks, with the caveats (7 sources)assets/hr_roster.example.csv, assets/accounts.example.csv, assets/campaign.example.csv — input formatsassets/access_review_signoff.md — campaign sign-off with the evidence fields a reviewer fills inalirezarezvani/claude-skills
08cd8a9
Also appears in
since Oct 29, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.