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.

7 stars

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

$curl -o ~/.claude/skills/permissions-auditor/SKILL.md --create-dirs "https://raw.githubusercontent.com/heldernoid/agentic-build-templates/main/projects/security-privacy/permissions-auditor/skills/permissions-auditor/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/permissions-auditor/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How permissions-auditor Compares

Feature / Agentpermissions-auditorStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/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

7
from heldernoid/agentic-build-templates

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

7
from heldernoid/agentic-build-templates

## Overview

Skill: Status Page

7
from heldernoid/agentic-build-templates

## Overview

Skill: unit-conversion

7
from heldernoid/agentic-build-templates

## Overview

Skill: recipe-scaler

7
from heldernoid/agentic-build-templates

## Overview

reading-list

7
from heldernoid/agentic-build-templates

Operate the reading-list API to save, manage, tag, search, and export articles.

email-digest

7
from heldernoid/agentic-build-templates

Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.

websocket-realtime

7
from heldernoid/agentic-build-templates

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

7
from heldernoid/agentic-build-templates

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

7
from heldernoid/agentic-build-templates

## Overview

Skill: csv-import

7
from heldernoid/agentic-build-templates

## Overview

Skill: Syntax Highlighting

7
from heldernoid/agentic-build-templates

## Purpose