permissions-auditor
A CLI tool and web UI for auditing Unix file system permissions. Scans a directory tree, applies configurable rules, and reports findings by severity. Outputs results as a formatted table, JSON snapshot, or SARIF 2.1.0 report for GitHub Advanced Security.
Best use case
permissions-auditor is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
A CLI tool and web UI for auditing Unix file system permissions. Scans a directory tree, applies configurable rules, and reports findings by severity. Outputs results as a formatted table, JSON snapshot, or SARIF 2.1.0 report for GitHub Advanced Security.
Teams using permissions-auditor should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/permissions-auditor/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How permissions-auditor Compares
| Feature / Agent | permissions-auditor | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
A CLI tool and web UI for auditing Unix file system permissions. Scans a directory tree, applies configurable rules, and reports findings by severity. Outputs results as a formatted table, JSON snapshot, or SARIF 2.1.0 report for GitHub Advanced Security.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# permissions-auditor
A CLI tool and web UI for auditing Unix file system permissions. Scans a directory tree, applies configurable rules, and reports findings by severity. Outputs results as a formatted table, JSON snapshot, or SARIF 2.1.0 report for GitHub Advanced Security.
## Installation
```bash
npm install -g permissions-auditor
# or
pnpm add -g permissions-auditor
```
## Commands
### scan
Scan a directory for permission issues.
```bash
permissions-auditor scan <path> [options]
```
Options:
| Flag | Default | Description |
|------|---------|-------------|
| `--severity <level>` | `low` | Minimum severity to report: `info`, `low`, `medium`, `high`, `critical` |
| `--output <format>` | `table` | Output format: `table`, `json`, `sarif` |
| `--sarif-out <file>` | `results.sarif` | Path for SARIF output file |
| `--save [file]` | auto | Save JSON snapshot; default name is `scan-<date>.json` |
| `--ci` | false | Exit 1 if any finding meets or exceeds `--severity` threshold |
| `--no-color` | false | Disable ANSI color codes in output |
| `--follow-symlinks` | false | Follow symbolic links during traversal |
| `--ignore <glob>` | see config | Additional ignore glob (repeatable) |
Examples:
```bash
# Basic scan, show all findings at medium and above
permissions-auditor scan /var/www/html --severity medium
# Save a snapshot and open web UI
permissions-auditor scan . --save && permissions-auditor serve
# CI: fail on critical or high findings, emit SARIF for GitHub
permissions-auditor scan . --severity high --ci --output sarif --sarif-out results.sarif
```
### compare
Compare two JSON snapshots and show drift (new, fixed, unchanged findings).
```bash
permissions-auditor compare <baseline.json> <current.json> [options]
```
Options:
| Flag | Default | Description |
|------|---------|-------------|
| `--output <format>` | `table` | Output format: `table`, `json` |
Example:
```bash
permissions-auditor compare scan-2026-03-13.json scan-2026-03-20.json
```
Output sections:
- **NEW** - findings present in current but not baseline
- **FIXED** - findings present in baseline but not current
- **UNCHANGED** - findings present in both
### serve
Launch the web UI, optionally loading a specific snapshot.
```bash
permissions-auditor serve [snapshot.json] [options]
```
Options:
| Flag | Default | Description |
|------|---------|-------------|
| `--port <n>` | `3900` | Port to listen on |
| `--host <addr>` | `127.0.0.1` | Bind address |
Example:
```bash
# Serve the most recent scan
permissions-auditor serve
# Serve a specific snapshot
permissions-auditor serve scan-2026-03-20.json --port 4000
```
## Severity levels
| Level | Code | Exit code in CI | Description |
|-------|------|-----------------|-------------|
| Critical | C | triggers exit 1 | World-writable credential files, SUID root binaries |
| High | H | triggers exit 1 | World-writable directories, group-writable scripts |
| Medium | M | no | Group-writable sensitive files, SGID binaries |
| Low | L | no | Owner mismatches, unusual configurations |
| Info | I | no | Informational notes (group-readable logs, etc.) |
## Rules
| Rule ID | Condition | Default severity |
|---------|-----------|-----------------|
| `world-writable-file` | Mode has other-write bit (0o002) set | Critical |
| `world-writable-dir` | Mode has other-write bit set AND sticky bit (0o1000) not set | High |
| `suid-binary` | Executable with SUID bit (0o4000) set | High |
| `sgid-binary` | Executable with SGID bit (0o2000) set | Medium |
| `group-writable-sensitive` | Group-write bit set AND path matches sensitive pattern | Medium |
| `owner-mismatch` | File owner does not match expected application user | Low |
| `no-read-owner` | Owner cannot read their own file | Info |
| `executable-in-config` | Executable bit set on a config-directory file | Info |
Sensitive path patterns for `group-writable-sensitive`: files under `config/`, `secrets/`, `certs/`, `keys/`, `scripts/`, `cron/`, `tmp/` or files matching `*.env`, `*.pem`, `*.key`, `*.json`, `*.yml`, `*.yaml`, `*.conf`, `*.sh`.
## Output formats
### table (default)
```
permissions-auditor scan . --severity medium
```
Prints a color-coded summary table to stdout with severity, path, rule, mode, owner, and fix advice. Critical and high findings are listed in full. Medium and below show a count only unless `--severity medium` or lower is set.
### json
```bash
permissions-auditor scan . --output json
```
Emits a JSON object conforming to the `ScanResult` interface:
```json
{
"id": "uuid",
"rootPath": "/abs/path",
"startedAt": "ISO8601",
"completedAt": "ISO8601",
"scannedCount": 3412,
"summary": { "critical": 2, "high": 5, "medium": 8, "low": 3, "info": 12, "total": 30 },
"findings": [
{
"id": "uuid",
"path": "/abs/path/file",
"ruleId": "world-writable-file",
"severity": "critical",
"message": "File is world-writable (mode 0666)...",
"mode": 438,
"uid": 1000,
"gid": 1000,
"owner": "user",
"group": "user",
"size": 512,
"fixAdvice": "chmod 600 /abs/path/file"
}
]
}
```
Note: `mode` is the decimal integer value of the Unix mode bits. Convert to octal with `mode.toString(8).padStart(4, '0')`.
### sarif
```bash
permissions-auditor scan . --output sarif --sarif-out results.sarif
```
Emits a SARIF 2.1.0 document. Each finding becomes a `result` with:
- `ruleId` matching the rule ID
- `level` mapped from severity (`critical/high` -> `error`, `medium` -> `warning`, `low/info` -> `note`)
- `locations[0].physicalLocation.artifactLocation.uri` as a path relative to `rootPath`
- `properties.mode`, `properties.modeOctal`, `properties.owner`, `properties.fixAdvice`
Upload to GitHub Advanced Security:
```yaml
# .github/workflows/security.yml
- name: Audit file permissions
run: |
npx permissions-auditor scan . --severity high --ci \
--output sarif --sarif-out results.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: results.sarif
```
## Configuration file
Settings are stored in `~/.config/permissions-auditor/config.json` and can be overridden per-project with `.permaudit/config.json`:
```json
{
"severity": "low",
"followSymlinks": false,
"autoSave": true,
"maxSnapshots": 30,
"defaultOutput": "table",
"color": true,
"showInfo": false,
"ignore": [
"node_modules/**",
".git/**",
".venv/**",
"vendor/**",
"dist/**",
"build/**"
],
"rules": {
"owner-mismatch": { "enabled": true, "expectedOwner": "www-data" },
"no-read-owner": { "enabled": false }
}
}
```
## Web UI pages
| Route | Description |
|-------|-------------|
| `/` | Dashboard with scan info bar, stat cards, top findings table |
| `/findings` | Full findings table with search, severity filter, rule filter |
| `/findings/:id` | Single finding detail with permission breakdown and fix recommendations |
| `/compare` | Side-by-side snapshot diff with new/fixed/unchanged breakdown |
| `/history` | Scan history list with severity bar charts per scan |
| `/settings` | Scan rules, ignore patterns, output preferences |
## Exit codes
| Code | Meaning |
|------|---------|
| `0` | Scan completed; no findings at or above the `--severity` threshold (in `--ci` mode), or CI mode not set |
| `1` | CI mode: one or more findings at or above threshold |
| `2` | Scan error (path not found, permission denied on root, etc.) |
## Snapshot files
Snapshots are stored in `.permaudit/` relative to the scanned path (or the current working directory). File names follow the pattern `scan-<YYYY-MM-DD>T<HH-MM-SS>.json`. The directory and naming can be overridden with `--save <path>`.
The web UI automatically loads the most recent snapshot in `.permaudit/` when launched without an explicit path argument.
## Environment variables
| Variable | Default | Description |
|----------|---------|-------------|
| `PERMAUDIT_CONFIG` | `~/.config/permissions-auditor/config.json` | Path to global config file |
| `NO_COLOR` | unset | Disable ANSI colors when set to any value |
| `PERMAUDIT_PORT` | `3900` | Default port for `serve` command |Related Skills
file-permissions
Reference guide for Unix file permission bits, octal notation, symbolic notation, and security-relevant permission combinations used by the permissions-auditor rules engine.
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.
Skill: personal-finance
## Overview
Skill: csv-import
## Overview
Skill: Syntax Highlighting
## Purpose