SKILL.md — Users and Apps Audit

From version 0.1.0 of Users and Apps Audit, shown publicly by its creator. 3.5 KiB · SHA-256 a19fd7c02257b265fa323ea1edc23ed985f59a44572ad15e2729fc84bfa6e9e0.

---
name: users-and-apps-audit
description: Read-only Microsoft Graph users, licenses, apps, roles and guests report.
license: MIT
---

# Users and Apps Audit

Run `python3 scripts/users_and_apps_audit.py report` from this package. The CLI requires Python 3.10+, Microsoft Graph application permissions, and the three credential environment variables in SETUP.md.

Use `--sections users,licenses,apps,roles,guests` to select sections, `--expiring-days 30` to set the credential and sign-in window, `--json` for structured output, and `--out PATH` to create a private new file. For `--out`, run the same command with `--dry-run` first, then supply its `--approve DIGEST` to create the file. The digest binds the resolved destination and directory identities plus full report content. The command is read only with respect to Microsoft Graph. A required section failure produces `incomplete`, lists skipped work, and exits 2 unless `--allow-partial` is set. Sign-in activity is optional and is marked skipped when AuditLog.Read.All is unavailable.

Treat names, user principal names, role membership and creation dates in output as personal data. Review the report before sharing it. Remote strings in text output are escaped onto one line; JSON remains JSON. The companion agent in `agents/users-and-apps-audit-agent.md` may summarize risk but must change nothing.

Supported platforms: macOS and Linux with POSIX directory-descriptor and no-follow APIs; Windows is unsupported and fails before file or network I/O.

The approval digest binds the selected and fully resolved file path, exact report content, and device/inode identities of the existing destination directory and its parent. Live creation walks the resolved path with no-follow directory descriptors, verifies identities and the selected path resolution, and creates the file relative to the directory descriptor with exclusive/no-follow flags at mode 0600. A swapped parent is refused before writing. All output directories must already exist; no folders are created.

Section selection restricts Graph queries, but users, licenses or guests each fetch the full selected users field set for all paginated users; report filters run after those reads. The no-sign-in list uses lastSignInDateTime, which records a sign-in attempt and does not prove successful sign-in or actual inactivity. Named activated roles are a fixed English display-name set; this is an inventory, not a policy evaluation.

The token POST sends tenant identifier in the URL and client ID, client secret, scope and grant type to login.microsoftonline.com. Graph GETs send the bearer access token and query paths to graph.microsoft.com, including role identifiers and same-host pagination paths obtained from Graph responses. Fetched pagination path/query contents are sent as received; display-name and UPN fields are not explicitly resent. Report content is not uploaded. Hostnames are given to the configured system resolver or proxy; no application DNS lookup of fetched user names occurs. Proxy settings may introduce a configured proxy destination.

Each JSON fixture and HTTP response body is limited to 8 MiB before parsing; oversized or malformed input fails with a clear error. Pagination is limited to 1000 pages per query. No stdin is read. Invalid nested Graph fields or timestamps produce explicit incomplete-section errors; missing optional values are not evidence of inactivity.

Remote paths reject dot segments, controls and encoded slash or backslash within a segment before requests.

By Zero Width Lab (zerowidthlab.com)

License: MIT (read it).

MITMIT License

Copyright (c) 2026 Zero Width Lab

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Back to the listing