What it is

Manual privilege auditing and risky IAM drift get replaced with deterministic, version-controlled rule evaluation: query a CyberArk/Idira-style REST API (SCIM users/groups, tokens, MFA policy) and emit deterministic EDN/JSON audit reports — orphaned privileged accounts, dormant privilege, unvaulted accounts, missing MFA, stale tokens. The same rules run against a shape-compatible mock API built in, so the 5 fixture findings reproduce exactly anywhere with only bb.

Scope, stated plainly: this audits a shape-compatible mock API or any SCIM/OAuth2 endpoint you point it at. There is no CyberArk integration and no affiliation with CyberArk — “Idira-style” means the endpoint shapes, not a partnership. A standalone GraalVM single-binary build was evaluated and deferred (see the README): bb itself is already a GraalVM binary with millisecond startup, so a separate native binary buys nothing today.

The rules (the executable contract)

# Rule Target
1 orphaned-privileged (high) Privileged account with no human owner
2 inactive-privileged (medium) Privileged, dormant 120 days
3 unvaulted-privileged (high) Privileged, not vault-managed
4 missing-mfa (medium) No MFA enrolled
5 stale-token (medium) Token older than 180-day TTL
6 never-logged-in-privileged (high) Privileged, no recorded login — synthetic estate only (not in the 5-finding mock fixture)

Fail-closed on gaps: never-logged-in privileged accounts and tokens without :created are findings, never silent passes. Rules are pure (no I/O) — the caller passes the clock.

5-minute quickstart (mock — deterministic, exactly 5 findings)

git clone https://github.com/nurazhardotcom/idira-audit-clj
cd idira-audit-clj
bb test          # 14 tests / 45 assertions
bb audit-demo    # end-to-end audit of the built-in mock API
bb -m idira-audit.main audit --mock --format json

Start a stub API and audit a sibling service via the bridge:

bb -m idira-audit.main mock-server --port 8899
bb -m idira-audit.main audit --idszc ../idszc --format json
bb check-native   # GraalVM readiness report

Live API

bb -m idira-audit.main audit --base-url https://idira.example \
  --token-url https://idira.example/oauth2/token \
  --client-id LAB --client-secret '...' --format json
# or: --api-token '...' instead of the client-credentials trio

File map

Labs

When it gets messy — a hybrid estate with orphans, dormant privilege, and MFA gaps meets the auditor:

Lab 1 — reproduce the 5. Run bb audit-demo; map each finding to its rule row above.

Lab 2 — break a rule safely. Flip one mock fixture field (e.g. give the orphan an owner), re-run, confirm the finding disappears and tests catch the drift.

Lab 3 — JSON to ticket. Emit --format json, pipe one finding into your ticketing format — deterministic fields, no parsing surprises.

CI

GitHub Actions runs bb test + bb audit-demo on every push to main and every PR — both steps exit non-zero on failure, so the deploy job never runs on a broken audit.