SpectreHub Docs

← spectrehub.dev

Quick Reference

brew install ppiankov/tap/spectrehub     # install
spectrehub activate sh_live_...          # activate license
spectrehub run                           # scan (local only)
spectrehub run --store                   # scan + store locally + upload if licensed
spectrehub run --format json -o out.json # JSON output
spectrehub diff                          # what changed since last run
spectrehub diff --fail-new               # exit 1 if new issues (CI gate)
spectrehub export --format csv -o e.csv  # compliance evidence
spectrehub export --format sarif         # GitHub Advanced Security

Security & Data Model

What SpectreHub touches, what it doesn't, and when data leaves your machine.

Guarantees

Assumptions

What gets uploaded (with --store + license)

Resource identifiers are infrastructure names like s3://bucket-name, kafka:topic-name, vault:secret/path, db.table_name. These are names, not contents. If your naming convention encodes sensitive information in resource names, be aware those names will be uploaded.

What never gets uploaded

Getting Started

Install, activate, scan, review.

1. Install SpectreHub

brew install ppiankov/tap/spectrehub

Or from source:

go install github.com/ppiankov/spectrehub/cmd/spectrehub@latest

2. Install audit tools

Install the tools for the infrastructure you want to audit. Each is a standalone binary:

brew install ppiankov/tap/vaultspectre    # HashiCorp Vault
brew install ppiankov/tap/s3spectre       # AWS S3
brew install ppiankov/tap/awsspectre      # AWS resource waste (EC2, EBS, RDS, ALB, NAT GW)
brew install ppiankov/tap/iamspectre      # AWS & GCP IAM audit
brew install ppiankov/tap/gcsspectre     # GCP Cloud Storage
brew install ppiankov/tap/gcpspectre     # GCP Compute, Disks, SQL, IPs
brew install ppiankov/tap/kafkaspectre    # Apache Kafka
brew install ppiankov/tap/pgspectre       # PostgreSQL

Each tool requires its own environment variables to connect to infrastructure. See the tool configuration table below.

3. Check your setup

spectrehub doctor

Doctor validates everything end-to-end: config file, license key, API connectivity, repo identifier, installed tools, and storage. Fix any issues it reports before running your first scan.

4. Run your first scan

spectrehub run

No SpectreHub config file is required for a first run. SpectreHub discovers installed tool binaries in your PATH, checks which have their target environment variables set, and runs them.

$ spectrehub run
Discovered 4 tool(s), 4 runnable

  vaultspectre   ✓ ready
  pgspectre      ✓ ready
  kafkaspectre   ✓ ready
  clickspectre   ✓ ready

Total Issues: 40
Health Score: GOOD (91%)

Recommendations:
  1. [CRITICAL] Fix 8 missing Vault secrets
  2. [HIGH] Clean up 7 unused Kafka topics
  3. [MEDIUM] Review 18 stale ClickHouse tables

5. Activate your license (paid tiers)

After purchasing a Team or Organization plan, you receive a license key by email. Activate it:

spectrehub activate sh_live_your_key_here

This validates the key against the SpectreHub API and writes it to your config file. The default write path is ~/.spectrehub.yaml (or $XDG_CONFIG_HOME/spectrehub/spectrehub.yaml if XDG is set). Override with --config /path/to/file.yaml.

For CI, set the key as an environment variable instead:

export SPECTREHUB_LICENSE_KEY=sh_live_your_key_here

6. Store and upload reports

After activation, use --store to save reports locally and upload to the API. The --repo flag is required for upload:

spectrehub run --store --repo my-org/my-repo
spectrehub run without --store never uploads anything, even with a license key. Upload requires both a valid license and --store. Without a license key, --store still stores locally but performs no upload.

Other output options:

spectrehub run --format json -o report.json   # JSON to file
spectrehub run --store --repo my-org/my-repo   # tag report with repo name
spectrehub diff                                 # compare last two runs

Configuration

Config file or environment variables. Both optional for local usage.

Config file

SpectreHub looks for config in this order:

Override with --config /path/to/spectrehub.yaml.

Sample config:

# ~/.spectrehub.yaml

# Directory to store reports locally
storage_dir: .spectre

# Fail if issues exceed this count (0 = disabled)
fail_threshold: 50

# Output format: text, json, or both
format: text

# Number of runs to keep for trend analysis
last_runs: 7

# Repository identifier (required for upload)
# Also settable via --repo flag or SPECTREHUB_REPO env var
repo: my-org/my-repo

# License key (paid features)
# Also settable via SPECTREHUB_LICENSE_KEY env var
license_key: sh_live_your_key_here

# API URL (change only for testing)
# api_url: https://api.spectrehub.dev

SpectreHub environment variables

All config values can be set via environment variables with the SPECTREHUB_ prefix:

VariableDescription
SPECTREHUB_LICENSE_KEYLicense key for API access
SPECTREHUB_REPORepository identifier (required for upload)
SPECTREHUB_STORAGE_DIRLocal report storage directory
SPECTREHUB_FAIL_THRESHOLDIssue count threshold for CI failure
SPECTREHUB_FORMATOutput format (text/json/both)

Tool environment variables

Each audit tool reads its own environment variables to connect to infrastructure. SpectreHub checks whether these exist to determine which tools can run. It reads presence only, never values.

ToolRequired env vars
vaultspectreVAULT_ADDR, VAULT_TOKEN
s3spectreAWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
kafkaspectreKAFKA_BROKERS
clickspectreCLICKHOUSE_DSN
pgspectrePGSPECTRE_DSN or DATABASE_URL
mongospectreMONGO_URI
awsspectreAWS_PROFILE, AWS_REGION, or AWS_ACCESS_KEY_ID
iamspectreAWS_PROFILE or GOOGLE_APPLICATION_CREDENTIALS
gcsspectreGOOGLE_APPLICATION_CREDENTIALS, GOOGLE_CLOUD_PROJECT, or CLOUDSDK_CORE_PROJECT
gcpspectreGOOGLE_APPLICATION_CREDENTIALS or CLOUDSDK_CORE_PROJECT

Health Score

Deterministic arithmetic. No ML, no heuristics.

Health score is the percentage of audited resources with zero issues:

affected   = count(unique resources with at least one issue)
score      = (total_resources - affected) / total_resources * 100
score      = clamp(score, 0, 100)

total_resources is the count of distinct resources across all tools (Vault references, S3 buckets, Kafka topics, database tables, etc.). affected is the count of unique resources that have at least one finding — a resource with 5 issues counts the same as a resource with 1. The result is clamped to 0–100.

Example: 100 resources, 7 have issues → score = (100 - 7) / 100 * 100 = 93.0 → GOOD
ScoreHealth level
95–100excellent
85–94good
70–84warning
50–69critical
0–49severe

Run spectrehub explain-score to see the full calculation step by step after a stored run:

$ spectrehub explain-score
Health Score Breakdown
======================

1. Resources per tool:
   pgspectre        42 resources, 3 issues, 3 affected
   s3spectre        18 resources, 2 issues, 2 affected
   vaultspectre     40 resources, 2 issues, 2 affected
                    100 resources total

2. Affected resources: 7 distinct

3. Formula:
   score = (total - affected) / total * 100
   score = (100 - 7) / 100 * 100 = 93.0

4. Thresholds:
     ≥ 95%  excellent
   → ≥ 85%  good
     ≥ 70%  warning
     ≥ 50%  critical
     ≥ 0%   severe

Result: GOOD (93.0%)

Also available as JSON (spectrehub explain-score --format json) for scripting. Per-tool resource counts are under summary.score_percent, summary.health_score, and summary.total_issues in the report output.

Interactive TUI

Browse audit results interactively in your terminal.

When spectrehub summarize runs in a TTY, it automatically launches an interactive TUI built with bubbletea. You can also force it with --tui:

spectrehub summarize           # auto-TUI when in a terminal
spectrehub summarize --tui     # force TUI
spectrehub summarize -f json   # bypass TUI, output JSON

The TUI displays:

Keyboard shortcuts:

The TUI requires stored runs. Run spectrehub run --store first. Pipe or redirect disables auto-TUI: spectrehub summarize | less outputs plain text.

CI/CD Integration

GitHub Action or any CI runner.

GitHub Action

- name: SpectreHub Audit
  uses: ppiankov/spectrehub-action@v1
  with:
    threshold: 50
  env:
    SPECTREHUB_LICENSE_KEY: ${{ secrets.SPECTREHUB_LICENSE_KEY }}
    VAULT_ADDR: ${{ secrets.VAULT_ADDR }}
    VAULT_TOKEN: ${{ secrets.VAULT_TOKEN }}

The action installs tools, discovers configured targets from repository secrets, runs audits, and posts results as a PR comment. Exit code 1 if issues exceed your threshold.

Any CI system

SpectreHub is a single binary with deterministic exit codes (see Exit Codes for per-command details):

# GitLab CI, CircleCI, Jenkins, etc.
spectrehub run --store --repo org/name --fail-threshold 50 --format json -o report.json
--store stores reports locally and uploads to the API if a valid license key is set. Without --store, nothing is uploaded, even in CI.

Health Alerts

Team and Organization tiers. Email when health degrades.

Health alerts trigger when the API detects a significant score drop between consecutive reports for the same repo. No configuration needed — alerts activate automatically once you have a license key and at least two stored runs for a repo.

Alert conditions

Who receives alerts

Alerts are sent to the email address associated with your license key (the email used at checkout). Recipients are not currently configurable per-repo.

Example alert

Subject: SpectreHub: health degraded for org/api

Score: 91 → 72
New issues: 14

Run spectrehub run to see full details.
Alerts only trigger on report submission. SpectreHub does not poll or schedule — it evaluates health each time spectrehub run --store executes and uploads.

PR Drift Delta

Team and Organization tiers. Catch regressions before merge.

The spectrehub diff command compares two audit runs and shows exactly what changed: new issues introduced and old issues resolved.

Basic usage

# Compare the two most recent stored runs
spectrehub diff

# Compare against a specific baseline file
spectrehub diff --baseline ./main-branch-report.json

# Fail CI if new issues were introduced
spectrehub diff --fail-new

Output

$ spectrehub diff
Drift Delta: 2 new, 1 resolved

New issues:
  [HIGH] kafkaspectre/unused_topic — events.dlq
  [MEDIUM] pgspectre/idle_role — readonly_user

Resolved:
  [HIGH] vaultspectre/missing_secret — config/db_password

Summary: +1 high, +1 medium, -1 high

CI gating

Use --fail-new in CI to block PRs that introduce new issues:

# In CI: run baseline scan on main, then diff on PR branch
spectrehub run --store --format json -o baseline.json
# (checkout PR branch, run again)
spectrehub diff --baseline baseline.json --fail-new

Exit code 1 if any new issues are found. JSON output available with --format json.

Compliance Exports

Organization tier. Evidence artifacts for SOC2, ISO 27001, and GitHub Security.

The spectrehub export command generates evidence artifacts from stored audit runs. These are supporting documents for compliance — not attestations or certifications. Your auditor determines how to use them.

Formats

FormatUse case
csvSpreadsheets, compliance tools, audit evidence binders
jsonProgrammatic consumption, custom dashboards
sarifGitHub Advanced Security, code scanning alerts

Usage

# Export last run as CSV
spectrehub export --format csv -o audit-evidence.csv

# Export last 30 runs as JSON
spectrehub export --format json --last 30 -o evidence.json

# SARIF for GitHub Advanced Security
spectrehub export --format sarif -o results.sarif --last 1

CSV columns

Each row is one issue from one run:

run_timestamp, tool, category, severity, resource, evidence, status, health_score, score_percent

SARIF integration

Upload SARIF to GitHub to surface SpectreHub findings in the Security tab:

# In GitHub Actions
- name: Export SARIF
  run: spectrehub export --format sarif -o results.sarif --last 1

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

Policy Enforcement

Organization tier. Define rules, fail CI on violations.

Create a .spectrehub-policy.yaml file in your repository root. SpectreHub evaluates it automatically during spectrehub run and exits with code 1 on violations.

Policy file

# .spectrehub-policy.yaml
version: "1"
rules:
  # Maximum total issues allowed
  max_issues: 100

  # Zero tolerance for critical findings
  max_critical: 0

  # Cap high-severity issues
  max_high: 10

  # Minimum health score (0-100)
  min_score: 70.0

  # Block specific issue categories
  forbid_categories:
    - missing_secret
    - public_access

  # Require these tools to be present in every run
  require_tools:
    - vaultspectre
    - s3spectre

Available rules

RuleDescription
max_issuesFail if total issues exceed this count
max_criticalFail if critical-severity issues exceed this count
max_highFail if high-severity issues exceed this count
min_scoreFail if health score drops below this percentage
forbid_categoriesFail if any listed issue category has findings
require_toolsFail if any listed tool is missing from the report

All rules are optional. Omit any rule to skip that check. The policy file is searched in the current directory and parent directories up to the filesystem root.

CI example

# .github/workflows/audit.yml
- name: SpectreHub Audit
  run: spectrehub run --store
  env:
    SPECTREHUB_LICENSE_KEY: ${{ secrets.SPECTREHUB_LICENSE_KEY }}
# Policy file in repo root is picked up automatically.
# Exit code 1 on any violation.

Billing & Subscription

Manage your plan, update payment, view invoices.

Plans

PlanReposFeatures
FreeUnlimited (local)CLI scans, local reports, CI threshold gate
Team ($49/mo)5API reporting, audit history, health alerts, drift delta
Organization ($149/mo)UnlimitedEverything in Team + policy enforcement, compliance exports

Managing your subscription

After purchasing, visit your welcome page on spectrehub.dev and click "Manage subscription" to access the Stripe billing portal. From there you can:

License lifecycle

Your license stays active as long as your Stripe subscription is active. If you cancel, the license is deactivated at the end of your billing period. If payment fails, Stripe retries automatically — the license remains active during retries. Local CLI usage always works regardless of license status.

Repo limits

The --repo flag (or repo in config) is required for upload. The API rejects reports without a repo identifier because trends, policy, alerts, and repo-limit enforcement all depend on it.

The Team plan tracks up to 5 unique repositories. Once 5 distinct repos have submitted reports, new repos are rejected until you upgrade. Existing repos continue to work. Organization plan has no repo limit.

Exit Codes

Deterministic per-command exit codes for scripting and CI.

Command0123
runOKThreshold / policy failInvalid inputRuntime error
diffNo new issuesNew issues (--fail-new)Invalid inputRuntime error
activateActivatedInvalid key / API errorConfig write error
exportSuccessInvalid inputRuntime error
collectOKThreshold / policy failInvalid inputRuntime error
doctorAll checks passRuntime error
statusOKRuntime error
explain-scoreOKNo stored runs
summarizeOKNo stored runs

Without --fail-new, diff always exits 0 (drift is informational). export exits 0 even if the export is empty (no stored runs).

Troubleshooting

Common problems and how to fix them.

"Discovered 0 tool(s), 0 runnable"

SpectreHub found no audit tool binaries in your PATH. Check that at least one tool is installed:

which vaultspectre s3spectre kafkaspectre pgspectre clickspectre mongospectre awsspectre iamspectre gcsspectre gcpspectre

If tools are installed but outside your PATH, add their directory to PATH before running SpectreHub.

"Tool X: not runnable" or "missing env vars"

The tool binary was found but its required environment variables are not set. See the tool configuration table for which variables each tool needs. SpectreHub checks presence only — if the variable exists but has a wrong value, the tool will be marked runnable but may fail during execution.

"Tool X: failed" in results

The tool started but exited with an error. Common causes: wrong credentials, target unreachable, timeout. Run the tool directly to see the full error:

# Run a single tool directly to see its error output
vaultspectre audit --format json

# Run SpectreHub with verbose output
spectrehub run --verbose

"repo is required" on upload

The API requires a repo identifier for every report. Add --repo org/name to your command or set repo in your config file.

spectrehub run --store --repo my-org/my-repo

Running a single tool

To audit only one tool without running all discovered tools:

spectrehub run --tool vaultspectre

Where are local reports stored?

By default in .spectre/ under the current directory (or the storage_dir value in config). Each run creates a timestamped JSON file. To delete stored reports, remove the files from that directory:

ls .spectre/
rm -i .spectre/report-2026-01-15T10:30:00.json   # confirm before deleting

What SpectreHub is NOT

Boundaries prevent misunderstanding.