I Built a PAM Audit CLI to Learn Identity the Hard Way
Hiring managers open repos they can clone, run, and interrogate — not certificates. So I built the thing my target role touches daily: a privileged-access audit tool.
The result is idira-audit-clj: a zero-dependency Babashka/Clojure CLI that queries Identity/PAM-style REST APIs and reports exactly five classes of rot. Release v0.1.0 is out under MIT.
1. The Problem: Privilege Rots Quietly
Every PAM assessment I studied names the same failures. They are never exotic — they are accounts nobody owns anymore:
| Finding | Severity | What it means |
|---|---|---|
| Orphaned privileged account | High | Vault admin with no active human owner |
| Dormant privilege | Medium | Service identity idle 120 days, still scoped |
| Un-vaulted privileged account | High | Password outside vault brokerage |
| Missing MFA | Medium | Active account, policy requires MFA, none enrolled |
| Stale token | Medium | API credential 200 days old against a 180-day TTL |
Nested inside each: the sponsor-binding gap — a
privileged non-human identity with nobody accountable. My sibling
project (idsvc, a hand-built Clojure identity service)
enforces this as a validation rule, so pointing the auditor at it
returns a clean report. That clean report is itself the evidence.
2. The Design: Pure Rules, Fixed Clock
mock/real Idira-style API → fetch (SCIM/OAuth2) → pure rule engine → EDN/JSON report
Two decisions carry the whole design. Rules are pure
functions over plain maps — no I/O, no clock reads inside. The
caller passes now as epoch seconds, which makes every audit
byte-deterministic: same estate, same findings, every
run. The mock API serves a fixture estate with exactly 5 findings, so
the test suite asserts exact counts, not vibes: bb test →
11 tests, 34 assertions, 0 failures.
The mock server itself is ~60 lines over raw JDK
ServerSocket — because Babashka’s runtime does not expose
com.sun.net.httpserver, and zero-dependency was the
constraint. Constraints that force simpler code are
features.
3. Built With AI, Disclosed Like It Matters
Research on 2026 hiring is blunt: reviewers assume AI assistance, and the red flag is code you cannot defend, not tool use. So the repo ships an AI_DISCLOSURE.md: architecture and code drafted by an AI agent under my direction, verified by a test suite that caught three genuine bugs (a keyword-vs-string compare, a CLI parser that silently dropped flags, a mock router bound to the wrong path segment).
Honest scope, stated in the README: mock API only, no
CyberArk affiliation, no compiled binary yet — the GraalVM
native-image step is roadmap, and today it runs on
bb, which is itself a GraalVM binary with millisecond
startup.
4. Run It in Three Commands
git clone https://github.com/nurazhardotcom/idira-audit-clj && cd idira-audit-clj
bb test
bb audit-demo
That is the whole pitch: clone, test, audit. If a hiring manager’s first minute is a skim for reproducibility, this repo is built for that minute — and for the hour after, when the questions get specific.
Learning identity by building the audit trail beats reading about it.