This tool is in early early development, expect a bad experience.
Finds users with Conditional Access enforcement gaps and reports what authentication conditions (if any) apply per resource and client app type.
Built on top of CAPSlock - it's essentially a targeted audit layer over CAPSlock's evaluation engine, using the same roadrecon data and CA semantics. My fork of CAPSlock must be installed for gaplock to function.
A gap is an access path where a user can authenticate with no CA control enforced. Paths where enforcement only exists in Report-only mode, or where a user is explicitly excluded from an enforcing policy, are classified separately.
- Python 3.8+
- roadrecon — to collect tenant data into
roadrecon.db - CAPSlock — the CA evaluation engine gaplock depends on
pip install git+https://github.com/Jacob-Ham/CAPSlock.git@legacy-client-app-fix
pip install git+https://github.com/Jacob-Ham/gaplock.gitOr from a local clone:
pip install ./CAPSlock
pip install ./gaplockAudit and report are split into two steps.
Audit all privileged admin role members:
gaplock find --admins --db roadrecon.dbAudit specific users from a file:
gaplock find --users-list targets.txt --db roadrecon.dbAudit every user in the database:
gaplock find --users --db roadrecon.dbCombine sources — admins plus an explicit list:
gaplock find --admins --users-list extras.txt --db roadrecon.dbRestrict to on-prem synced accounts only with admin Entra roles:
gaplock find --admins --synced --db roadrecon.dbCheck a specific resource instead of all discovered ones:
gaplock find --admins --resource 00000002-0000-0000-c000-000000000000 --db roadrecon.dbgaplock reportReads capslock_gap_audit.summary.json and capslock_gap_audit.users.jsonl (produced by find) and prints a text report, writing capslock_gap_audit.report.html.
Use --out on both commands to change the file prefix:
gaplock find --admins --db roadrecon.db --out my_audit
gaplock report --out my_audit| Flag | Description |
|---|---|
--admins |
Members of built-in privileged directory roles |
--users |
All users in the database |
--users-list FILE |
Specific UPNs from a file (one per line, # comments ignored) |
--synced |
Restrict to on-prem synced accounts (dirSyncEnabled=True) |
--include-disabled |
Include disabled accounts (default: enabled only) |
At least one of --admins, --users, or --users-list is required.
| Type | Meaning |
|---|---|
NO_POLICIES_APPLY |
No CA policies target this user for this path |
REPORT_ONLY_BYPASS |
Coverage exists but only in Report-only mode |
EXCLUDED_BYPASS |
An enforcing policy exists but the user is explicitly excluded |