Skip to main content

GhostAudit

English · 中文 · 日本語 · 한국어 · Русский · Deutsch

PyPI Python License: PolyForm Shield 1.0.0

Tamper-evident filesystem auditing for multi-project workspaces. Hashes every file with SHA-256, tracks changes across runs, generates a per-project AUDIT.md, and seals findings in a Merkle tree. Optional encrypted evidence capsules for SOC 2, HIPAA, and AI-provenance workflows.

Stdlib-only core. No pip dependencies unless you enable encrypted capsules.

Quick Start

pip install ghostaudit

# Run a full audit (inventory + index + diff)
ghostaudit --mode full --workspace /path/to/workspace

# Run the daily pipeline (hash → compare → audit or sleep)
ghostaudit --mode daily --workspace /path/to/workspace

# Just update project audits
ghostaudit --mode update_audits --workspace /path/to/workspace

# Preview audit changes without writing
python -m workspace_audit.update_audits --workspace /path/to/workspace --dry-run

Tools

Tool Purpose
run_audit.py Orchestrator — runs any mode via --mode flag
daily_audit.py Daily runner — hash, compare, full audit or sleep
hash_manifest.py SHA-256 hashes every file, compares to previous manifest
generate_inventory.py Scans workspace, classifies items, detects secrets
build_index.py Generates consolidated AUDIT_INDEX.md from all data
diff_audits.py Compares current vs previous snapshots, tracks changes
update_audits.py Auto-generates and versions per-project AUDIT.md files

Modes

run_audit.py --mode <mode>
Mode What it does
full inventory → index → diff
daily hash → compare → if changes: full + update_audits + daily report; if no changes: sleep
inventory_only Just scan filesystem metadata
index_only Regenerate AUDIT_INDEX.md from existing data
diff_only Compare current to previous snapshot
hash_only Hash files and compare to previous manifest
update_audits Generate/update per-project AUDIT.md files

Pipeline Flow

daily_audit.py
  ├── hash_manifest.py      → audit/manifests/{timestamp}.json
  │     └── compare          → audit/manifests/latest_result.json
  │
  ├── [if changes detected]
  │     ├── generate_inventory.py  → audit/inventory.json
  │     ├── build_index.py         → administration/AUDIT_INDEX.md
  │     ├── diff_audits.py         → audit/history/diffs/{timestamp}.json
  │     ├── update_audits.py       → {project}/AUDIT.md (versioned)
  │     └── daily report           → audit/daily/{date}.md
  │
  └── [if no changes]
        └── log "no_changes"       → audit/daily/daily_log.jsonl

Configuration

Create audit.config.json in your workspace root (optional — all settings have defaults):

{
  "owner": "auto",
  "composite_projects": ["my-monorepo"],
  "force_audit_subdirs": ["legacy-api", "worker"],
  "skip_dirs": [
    "node_modules", ".git", "target", ".next", "dist", "__pycache__",
    ".pytest_cache", "venv", ".venv", "vendor", ".mypy_cache"
  ],
  "admin_dir": "administration",
  "audit_dir": "audit",
  "version_audits": true,
  "generate_sub_audits": true
}
Setting Default Description
owner "auto" Owner name in AUDIT.md. "auto" reads from git config user.name
composite_projects [] Projects that should always be treated as composite (per-subdir audits)
force_audit_subdirs [] Subdirectory names to audit even if they don't have build configs
skip_dirs (see above) Directories to skip when scanning
admin_dir "administration" Where to write AUDIT_INDEX.md
audit_dir "audit" Where to write inventory, manifests, and history
version_audits true Archive old AUDIT.md before overwriting
generate_sub_audits true Generate per-component audits for composite projects

Composite Projects

Projects with 2+ subdirectories containing build configs (package.json, Cargo.toml, etc.) are automatically detected as composite. For each composite project:

  1. Each sub-component gets its own {component}/AUDIT.md
  2. The parent gets a summary AUDIT.md with a component table
  3. Add directories to force_audit_subdirs in config if they lack standard build configs

Versioning

When version_audits is true (default), the old AUDIT.md is archived to {project}/audits/AUDIT-{date}.md before being overwritten. Same-day re-runs are detected and don't create duplicate archives.

Scheduling (Windows)

@echo off
cd /d C:\path\to\workspace
python tools\audit\daily_audit.py --workspace C:\path\to\workspace >> audit\daily\scheduler.log 2>&1
schtasks /create /tn "WorkspaceAudit" /tr "C:\path\to\schedule_daily.bat" /sc daily /st 04:00 /f

Scheduling (Linux/macOS)

# crontab -e
0 4 * * * cd /path/to/workspace && python tools/audit/daily_audit.py >> audit/daily/scheduler.log 2>&1

Output Structure

workspace/
├── audit/
│   ├── inventory.json              # Current inventory
│   ├── inventory_summary.json      # Rollup stats
│   ├── findings.json               # Tracked findings
│   ├── manifests/                  # Hash manifests
│   │   ├── {timestamp}.json
│   │   └── latest_result.json      # Last comparison result
│   ├── history/
│   │   ├── inventory/              # Historical snapshots
│   │   ├── findings/
│   │   └── diffs/                  # Change reports
│   └── daily/
│       ├── {date}.md               # Daily reports
│       ├── daily_log.jsonl         # Run log
│       └── scheduler.log           # Cron/scheduler output
├── administration/
│   └── AUDIT_INDEX.md              # Consolidated index
├── project-a/
│   ├── AUDIT.md                    # Auto-generated audit
│   └── audits/
│       └── AUDIT-2026-03-22.md     # Versioned archive
└── audit.config.json               # Configuration (optional)

GitHub Action

Use GhostAudit as a GitHub Action to get findings as GitHub Code Scanning alerts in pull requests and the repository Security tab.

Basic usage

- uses: adam-scott-thomas/ghostaudit@v1
  with:
    profiles: 'security'
    fail-on: 'CRITICAL'
    upload-sarif: 'true'

Full workflow example

name: Workspace Audit

on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]
  schedule:
    - cron: '0 4 * * *'

permissions:
  security-events: write
  contents: read

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Run Workspace Audit
        id: audit
        uses: adam-scott-thomas/ghostaudit@v1
        with:
          profiles: 'security,soc2'
          fail-on: 'CRITICAL'
          upload-sarif: 'true'

      - name: Print summary
        run: |
          echo "Findings: ${{ steps.audit.outputs.findings-count }}"
          echo "Critical: ${{ steps.audit.outputs.critical-count }}"
          echo "High:     ${{ steps.audit.outputs.high-count }}"

Inputs

Input Default Description
profiles security Comma-separated audit profiles (security, feature, soc2, quality)
project (all) Specific project to audit
format sarif Output format (sarif, json, csv, markdown)
fail-on never Fail if findings at this severity or above (CRITICAL, HIGH, MEDIUM, LOW, never)
upload-sarif true Upload SARIF to GitHub Code Scanning
python-version 3.12 Python version to use

Outputs

Output Description
findings-count Total number of findings
critical-count Number of CRITICAL findings
high-count Number of HIGH findings
sarif-file Path to SARIF output file
report-file Path to report output file

SARIF integration

When upload-sarif is true (the default), findings are uploaded to GitHub Code Scanning via the github/codeql-action/upload-sarif action. This requires the security-events: write permission. Findings appear in the repository's Security tab and as annotations on pull requests.

Requirements

  • Python 3.10+
  • Git (for owner detection and git status checks)
  • No pip dependencies for the core — stdlib only
  • cryptography>=42.0 only if you enable encrypted evidence capsules (pip install ghostaudit[capsule])

License

GhostAudit is licensed under the PolyForm Shield License 1.0.0. This is a source-available commercial-restrictive license. You may use, modify, and redistribute GhostAudit for any purpose, including internal enterprise use, except to build a product or service that competes with GhostAudit or with a product GhostLogic LLC provides using GhostAudit. See LICENSE for the full terms.

Copyright GhostLogic LLC.

Release files for ghostaudit 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ghostaudit 1.2.0
File Size Uploaded
ghostaudit-1.2.0.tar.gz 115.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ghostaudit 1.2.0
File Interpreter ABI Platform
ghostaudit-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 246.4 kB

Release files / ghostaudit-1.2.0.tar.gz

Download URL ghostaudit-1.2.0.tar.gz
Size 115.1 kB
Tags Source
SHA-256 checksum
How to use checksums
fe13034131e1721afdc8da481e441ede88f6f54d72301eb33eae21b364eb99c6
BLAKE2b-256 checksum
How to use checksums
5cbc886e5a3e9375bc0b975381dc2c9fe97a6bee892de8c204437a5f8c928f34
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release files / ghostaudit-1.2.0-py3-none-any.whl

Download URL ghostaudit-1.2.0-py3-none-any.whl
Size 131.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a4a901eef651f3bfedccf5cdd948d1b402ef42689c097bf1759c294f336d0528
BLAKE2b-256 checksum
How to use checksums
35e7b85268c0681e4c2b226bb07a5f0540500b89f185618f3bfbbab35e5b9cd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.10

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page