Skip to main content

Reusable security audit tool for any repository

Project description

ShipGuard

Reusable security audit tool for any repository. Scans shell scripts, Python, JavaScript/TypeScript, GitHub Actions workflows, and configuration files for 48 vulnerability patterns across all 7 layers of a unified security pipeline.

Install

From PyPI

python -m pip install shipguard

Recommended: Using pipx (CLI tool)

pipx install git+https://github.com/celstnblacc/shipguard.git

This installs ShipGuard in an isolated environment with global command access.

From source (development)

git clone https://github.com/celstnblacc/shipguard.git
cd shipguard
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

In a project (virtual environment)

python3 -m venv .venv && source .venv/bin/activate && pip install "git+https://github.com/celstnblacc/shipguard.git"

Install from GitHub (correct URL syntax)

pip install "git+https://github.com/celstnblacc/shipguard.git"

You can pin to a branch/tag/commit:

pip install "git+https://github.com/celstnblacc/shipguard.git@main"
pip install "git+https://github.com/celstnblacc/shipguard.git@efbd130"

After install:

shipguard --version
shipguard scan .

Verify you are using the expected binary:

which shipguard
shipguard scan --help

If you open a new shell later:

source .venv/bin/activate && shipguard --version

Quick Start

# Scan current directory
shipguard scan .

# Scan another repository by absolute path
shipguard scan /path/to/target-repo

# Scan with JSON output (for CI pipelines)
shipguard scan . --format json

# Scan another repository and save JSON report
shipguard scan /path/to/target-repo --format json --output /tmp/target-repo-shipguard.json

# Optional: enable Rust-accelerated secrets scanning
shipguard scan . --rust-secrets

# Only show critical and high findings
shipguard scan . --severity high

# Only show high+ findings for another repository
shipguard scan /path/to/target-repo --severity high

# Generate markdown report (for PR comments)
shipguard scan . --format markdown --output report.md

# List all 48 rules with descriptions
shipguard list-rules

# Include only selected rules
shipguard scan . --include-rules PY-003,SEC-001

# Exclude noisy rules for a run
shipguard scan . --exclude-rules JS-008,PY-009

# Create a config file
shipguard init

# Create a config file in another repository
shipguard init /path/to/target-repo

Sample Terminal Output

ShipGuard Scan Results
──────────────────────────────────────────────────────
  Files scanned : 42      Rules applied : 48
  Findings      : 3       Files skipped : 0
  Duration      : 0.21s
──────────────────────────────────────────────────────

 CRITICAL  src/deploy.sh:14
           Rule  : SHELL-001  eval-injection
           CWE   : CWE-94
           Code  : eval $(get_user_input)
           Fix   : Avoid eval; use arrays or direct execution instead

 HIGH      scripts/build.py:37
           Rule  : SHELL-009  shell-true-subprocess
           CWE   : CWE-78
           Code  :     result = subprocess.run(cmd, shell=True)
           Fix   : Use shell=False with a list of arguments instead

 MEDIUM    .gitignore:1
           Rule  : SC-004  missing-gitignore-secret-entries
           CWE   : CWE-312
           Fix   : Add the following to .gitignore: *.key, *.pem, *.p12
──────────────────────────────────────────────────────
Exit code 1 (findings detected)

Development Staging Bootstrap (Maintainers Only)

Note: This section is for ShipGuard maintainers running the full go-live pipeline. Regular users do not need Docker or staging to use ShipGuard.

Use the helper script to create a local staging target for go-live/infra-probe verification:

# Start local staging and wait for health
./scripts/go_live_staging.sh up

# Show status
./scripts/go_live_staging.sh status

# Tear down cleanly
./scripts/go_live_staging.sh down

This workflow uses docker-compose.staging.yml and .env.staging (auto-copied from .env.staging.example if missing).

Release Rollback Runbook

Rollback trigger criteria:

  • New critical or high finding in post-release scan
  • PyPI installation failure for latest tag
  • CLI regression in critical path (shipguard scan, shipguard list-rules)

Rollback steps:

  1. Stop promotion and notify the on-call release owner.
  2. Repoint users to the previous stable release tag in release notes.
  3. Cut a patch release from main with the fix and rerun:
    • pytest tests -q
    • shipguard scan . --format terminal
  4. Publish patched tag using .github/workflows/release.yml.

Ownership:

  • Primary: repository maintainers listed in SECURITY.md
  • Escalation: GitHub issue with release-blocker label and incident summary

7-Layer Security Pipeline

ShipGuard implements a unified security model across all 7 layers of the software development lifecycle:

Layer Focus ShipGuard Rules External Tools
L1: Dependencies Vulnerable packages pip-audit, npm audit, osv-scanner
L2: Secrets Credential exposure SEC-001–010 (10) gitleaks, detect-secrets
L3: SAST Code vulnerabilities 34 rules ShellCheck, Bandit, ESLint
L4: AI Reasoning Semantic analysis Claude, GPT-4, human architects
L5: DAST Runtime vulnerabilities OWASP ZAP, Burp Suite
L6: Supply Chain Build integrity SC-001–004 (4) Sigstore, Cosign
L7: Observability Production monitoring SIEM, Datadog, PagerDuty

See docs/PIPELINE.md for complete framework details.


Rules (48 total)

Category Layer Count IDs Examples
Shell L3 9 SHELL-001–009 eval injection, unquoted vars, bash -c interpolation
Python L3 9 PY-001–009 zip slip, yaml.load, eval/exec, SQL injection
JavaScript L3 8 JS-001–008 eval, path traversal, prototype pollution, XSS
GitHub Actions L3 5 GHA-001–005 workflow injection, unpinned actions, secrets in logs
Config L3 3 CFG-001–003 auto-approve, committed .env, permissive CORS
Secrets L2 10 SEC-001–010 Cloud/API tokens and other hardcoded secret patterns
Supply Chain L6 4 SC-001–004 Docker :latest, unpinned deps, npm lockfiles, missing .gitignore entries

Run shipguard list-rules or shipguard list-rules --format json for full details.


Quick Start: Complete Security Pipeline

Run the full 7-layer pipeline locally:

# Install optional dependencies
pip install pip-audit bandit shellcheck-py

# Run all layers (1, 2, 3, 6 local; others require additional setup)
make security

# Run strict blocking gate (fails on high+ findings)
make security-strict

# Or run individual layers
make security-l1   # Dependencies
make security-l2   # Secrets
make security-l3   # SAST
make security-l6   # Supply Chain

# For CI/CD, use GitHub Actions workflow
# See .github/workflows/security.yml

Configuration

Create .shipguard.yml in your project root (or run shipguard init):

# Minimum severity to report: critical, high, medium, low
severity_threshold: medium

# Glob patterns for paths to exclude
exclude_paths:
  - "vendor/**"
  - "node_modules/**"
  - "**/fixtures/**"

# Rule IDs to disable
disable_rules:
  - SHELL-008

# Additional directories containing custom rule modules
custom_rules_dirs: []

CLI flags override config file values.

Optional Rust Acceleration (Secrets)

ShipGuard can offload SEC-001, SEC-002, and SEC-003 scanning to a Rust binary while keeping the rest of the scanner in Python.

Build the optional binary:

cd rust/shipguard-secrets
cargo build --release

Then either:

export SHIPGUARD_RUST_SECRETS_BIN="$PWD/target/release/shipguard-secrets"
shipguard scan . --rust-secrets

Or place shipguard-secrets in your PATH.

Inline Suppression

Suppress a finding on a specific line:

eval(expr)  # shipguard:ignore PY-003

Or on the line above:

# shipguard:ignore PY-003
eval(expr)

Multiple rules can be suppressed:

eval $cmd  # shipguard:ignore SHELL-001, SHELL-002

Output Formats

  • terminal (default) — Rich color-coded table with severity highlighting and fix hints
  • json — Machine-readable {"findings": [...], "summary": {...}} for CI integration
  • markdown — Report grouped by severity level, suitable for PR comments

CI Integration

Pre-commit Hook

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/celstnblacc/shipguard
    rev: main
    hooks:
      - id: shipguard

GitHub Action

- uses: celstnblacc/shipguard@main
  with:
    severity: medium
    format: terminal

Generic CI

pip install shipguard
shipguard scan . --severity high --format json
# Exit code 1 if findings exist, 0 if clean

Release Runbook (PyPI Trusted Publishing)

Use this checklist for each release:

  1. Prepare version + changelog
  • Update package version and append the release notes in CHANGELOG.md.
  1. Confirm GitHub workflow + environment
  • Workflow file: .github/workflows/publish.yml
  • Required workflow name: publish.yml
  • Required job environment: pypi
  • Workflow publishes on tag pushes matching v*.
  1. Configure PyPI trusted publisher (one-time or when repo changes)
  • URL: https://pypi.org/manage/project/shipguard/settings/publishing/
  • Owner: newblacc
  • Repository: shipguard
  • Workflow: publish.yml
  • Environment: pypi
  1. Create and push release tag
git tag vX.Y.Z
git push origin vX.Y.Z
  1. If publish failed before OIDC setup
  • Open GitHub Actions and re-run the failed publish.yml run for the same tag after trusted publisher configuration is saved.
  1. Post-publish smoke test
python -m pip install -U shipguard
shipguard --version
shipguard scan . --severity high
  1. Verify release
  • Confirm the new version is visible on PyPI and installable in a clean environment.

Exit Codes

Code Meaning
0 No findings at or above the severity threshold
1 One or more findings detected

Suppression Comments

Both # and // comment styles are supported:

# Python / Shell
eval(expr)  # shipguard:ignore PY-003
// JavaScript
eval(code);  // shipguard:ignore JS-001
# Shell
eval $cmd  # shipguard:ignore SHELL-001

Suppress multiple rules:

eval $cmd  # shipguard:ignore SHELL-001, SHELL-002

About This Project

ShipGuard implements a 7-layer unified security framework integrated into a single SAST tool. It was developed to package 48 security vulnerability patterns discovered during real-world audits of the spec-kit and superpowers projects.

ShipGuard provides:

  • Layer 3 (SAST): 34 rules across command injection, path traversal, code injection, and configuration issues
  • Layer 2 (Secrets): 10 rules detecting cloud/API credentials and token patterns
  • Layer 6 (Supply Chain): 4 rules checking Docker image pinning, dependency pinning, and .gitignore secret baselines
  • Integration: GitHub Actions workflow, pre-commit hooks, local Makefile targets

See docs/7_LAYER_SECURITY_MODEL.md for the complete security framework.

The rules focus on:

  • Command injection: eval, exec, bash -c, sed, printf with unquoted variables
  • Path traversal: Unvalidated path.join(), symlink following
  • Code/data injection: YAML unsafe load, pickle, SQL string formatting
  • Secrets: AWS/GCP keys, GitHub tokens, hardcoded credentials
  • Supply chain: Docker :latest tags, unpinned dependencies, npm lockfile verification
  • Configuration: Committed .env files, overly permissive CORS, auto-approve settings

Troubleshooting

"Module not found" errors

If you get import errors, ensure you're in the correct environment:

# For pipx installations
pipx list  # Should show shipguard

# For venv installations
source .venv/bin/activate
which shipguard  # Should show venv path

Pre-commit hook not running

Ensure .pre-commit-hooks.yaml is in the correct location and hooks are configured:

pre-commit install
pre-commit run --all-files  # Test manually

Development

To contribute or modify rules:

git clone https://github.com/celstnblacc/shipguard.git
cd shipguard
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Test the CLI
shipguard scan tests/fixtures/

New rules should be added to src/shipguard/rules/ with the @register decorator:

from shipguard.models import Finding, Severity
from shipguard.rules import register

@register(
    id="RULE-001",
    name="rule-description",
    severity=Severity.HIGH,
    description="What this rule detects",
    extensions=[".py"],
    cwe_id="CWE-123"
)
def rule_001_check(file_path, content, config=None):
    findings = []
    # Detection logic here
    return findings

License

Apache License 2.0 — see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

shipguard-0.3.2.tar.gz (141.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

shipguard-0.3.2-py3-none-any.whl (50.8 kB view details)

Uploaded Python 3

File details

Details for the file shipguard-0.3.2.tar.gz.

File metadata

  • Download URL: shipguard-0.3.2.tar.gz
  • Upload date:
  • Size: 141.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for shipguard-0.3.2.tar.gz
Algorithm Hash digest
SHA256 6b166e991fa1d67fd8508d1886de1e1bcb4cc99bd25cf6c3c94bb4f635895332
MD5 b060491debabe7a5091655b1bf97ae44
BLAKE2b-256 27f58a2107cd12a674fe172ff3c19c6a6688121347128529eb318672749be0f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for shipguard-0.3.2.tar.gz:

Publisher: publish.yml on celstnblacc/shipguard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file shipguard-0.3.2-py3-none-any.whl.

File metadata

  • Download URL: shipguard-0.3.2-py3-none-any.whl
  • Upload date:
  • Size: 50.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for shipguard-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 545696af4b76004fa1d1ad16531033027bc1e478583ac0a06305591eef16942d
MD5 2b16d568d3c67618fbf6a6b7152d8dbd
BLAKE2b-256 70d22b42b8e382750785cb8daefaa9340f375bb4ec2402ff51fabb981bd3cf32

See more details on using hashes here.

Provenance

The following attestation bundles were made for shipguard-0.3.2-py3-none-any.whl:

Publisher: publish.yml on celstnblacc/shipguard

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page