A Claude Code Skill that runs a SOX-compliant User Access Review (UAR) campaign end-to-end, for GRC and enterprise security teams who execute quarterly access recertifications and live with the audit fallout.
It is opinionated. It assumes you have a SOX program, an ITGC scoping matrix, an HRIS that can be considered the source of truth for employment status, and at least one IAM/IGA system you can pull entitlement extracts from. If those things are not true, fix those things first.
A flat repo, intended to drop into .claude/skills/sox-uar/ (project) or ~/.claude/skills/sox-uar/ (personal). The skill loads automatically when Claude sees UAR-related work; you can also invoke it directly with /sox-uar.
| File | Purpose | When it's used |
|---|---|---|
SKILL.md |
The skill entrypoint — six-phase playbook with gates, common pitfalls, and scope guardrails. | Always (loaded on invocation). |
reviewer-guide.md |
The one-page guide reviewers receive at campaign launch. | Phase 3 — send verbatim to reviewers. |
signoff-memo-template.md |
Control owner signoff memo with the four-point completeness attestation. | Phase 6 — fill in and route for signature. |
exception-register-template.md |
Format and field definitions for the cycle's exception register. | Phase 4 onward — every late revocation, missed review, or deviation goes here. |
reconcile.py |
Three-way HRIS / extract / prior-cycle reconciliation script. Stdlib only. | Phase 2 gate — must exit 0 before campaign launches. |
- Scope & plan — GRC-signed scoping memo with system list, reviewer mapping, deadlines.
- Collect & reconcile — Run
reconcile.py; clear all P0 findings before proceeding. - Launch campaign — Reviewer notifications go out with the reviewer guide attached.
- Reviewer execution — Track acknowledgment separately from completion; escalation ladder runs on a fixed schedule.
- Remediation — Every revocation ticketed and verified by re-querying the target system. Don't trust "ticket closed."
- Evidence & signoff — Audit package assembled; control owner signs the memo.
Each phase has a gate. The skill is explicit about not skipping ahead. The most common deficiency in real-world UARs is a phase 5 that was never actually verified — revocation tickets closed, but the access was never removed.
your-repo/
└── .claude/
└── skills/
└── sox-uar/
├── SKILL.md
├── reviewer-guide.md
├── signoff-memo-template.md
├── exception-register-template.md
└── reconcile.py
mkdir -p ~/.claude/skills/sox-uar
cp -r * ~/.claude/skills/sox-uar/In Claude Code:
What skills are available?
You should see sox-uar in the list. Or invoke it directly:
/sox-uar
reconcile.py is the gate that prevents you from launching a campaign with terminated users still in the population — the single most common P0 audit finding.
Three CSVs. Column names are case-insensitive but must match these keys.
hris.csv — your HRIS extract, source of truth for employment status.
employee_id, email, status, department, role, manager_email, last_change_date
status values: active | terminated | leave
extract.csv — entitlements from each in-scope system.
system, user_email, entitlement, account_type, last_login, grant_date
account_type values: human | service | shared | break_glass
prior.csv (optional) — the prior cycle's reviewer assignments, for transfer detection and self-review checks.
user_email, system, entitlement, prior_reviewer_email, department, role
python reconcile.py \
--hris hris.csv \
--extract extract.csv \
--prior prior.csv \
--privileged-patterns "admin,owner,root,sudoers,*prod*" \
--inactive-days 90 \
--out-dir ./phase2-evidencefindings.json— structured findings, one record per issue. Attach to the audit package.summary.txt— human-readable summary suitable for the Phase 1 → Phase 2 gate review.
| Code | Meaning | Action |
|---|---|---|
0 |
No P0 findings. | Phase 2 gate clear; you may proceed to Phase 3. |
1 |
P0 findings present (terminated users with active access). | Stop. Open a security incident; do not launch the campaign until cleared. |
2 |
Input error (missing file, missing required column). | Fix the input and rerun. |
Wire the script into a CI job on your campaign-prep branch and it will fail the build until the P0 is remediated. That is the intended use.
| Type | Severity | What it means |
|---|---|---|
TERMINATED_USER_WITH_ACCESS |
P0 | User is terminated in HRIS but still holds active access. Severity-1 incident. |
SELF_REVIEW_PRIOR_CYCLE |
P0 | Prior cycle recorded the user as their own reviewer. Prior decision is void. |
ORPHAN_ACCOUNT |
P1 | Account in the extract has no matching HRIS record. Could be a service account misclassified as human, a contractor not in HRIS, or a ghost account. |
PRIVILEGED_ACCESS |
P1 | Entitlement matches a privileged pattern. Requires dual review + written justification on Keep. |
PRIVILEGED_NHI |
P1 | Privileged non-human identity. Requires dual review and explicit business justification. |
TRANSFERRED_USER_DEPT |
P1 | User's department changed since the last review. Remap reviewer; re-evaluate the entitlement. |
TRANSFERRED_USER_ROLE |
P2 | User's role changed within the same department. Re-evaluate the entitlement. |
INACTIVE_ACCESS |
P2 | Last login older than --inactive-days. Strong revoke candidate. |
NEVER_USED_ACCESS |
P2 | Access granted long ago but never used. Strong revoke candidate. |
NON_HUMAN_IDENTITY |
INFO | Service / shared / break-glass account — must be routed to the technical owner, not a manager queue. |
- Ad-hoc access reviews that aren't tied to a SOX control — overkill, use a lighter recertification flow.
- Non-SOX regulatory reviews (HIPAA, SOC 2, ISO 27001) — the phases are similar but the evidence requirements differ. Do not reuse the signoff memo verbatim.
- Joiner-mover-leaver spot checks — different control. UAR certifies standing access; JML certifies access changes at employment transitions.
If you adapt the skill for your environment, the parts most likely to need local tuning:
- Privileged patterns in
reconcile.py— adjust the--privileged-patternsflag to match your entitlement naming conventions. - Inactive threshold —
--inactive-daysdefaults to 90; some industries use 30 or 45. - Reviewer escalation ladder in
SKILL.md— the day-by-day cadence assumes a 7 business day campaign. If yours is shorter, compress proportionally; do not skip steps. - Audit package contents in
signoff-memo-template.md— if your external auditor has a different section index they prefer, match theirs.
Avoid loosening the four-point completeness attestation in the signoff memo. It exists because each point maps to a specific audit test step, and missing one creates a deficiency finding.
Internal use. Adapt freely for your organization. No warranty — your audit is your audit.