Reusable security audit tool for any repository
Project description
ShipGuard: The AI-Native Security Sentinel
ShipGuard is an intelligent security sentinel designed to protect your repository from vulnerabilities through semantic analysis and AI reasoning. It moves beyond simple pattern matching by using Tree-sitter to understand the "intent" of your code, virtually eliminating false positives. With its built-in Layer 4 AI Triage, it automatically determines if a vulnerability is reachable or just dead code. The integrated Auto-Remediation engine can autonomously generate and apply secure code patches to fix findings on the fly. As an MCP-native tool, it serves as a security sense-organ for AI agents like Claude and Cursor, providing a high-performance Rust core for instantaneous workspace audits.
๐ The Sentinel Experience
๐บ Demo
Run shipguard scan --ai-triage to see the Sentinel reason about your code in real-time. Watch as it dismisses safely handled patterns and focuses only on exploitable risks.
๐ง Wizard (Getting Started)
To initialize the Sentinel in your project, simply run:
shipguard init
This wizard will guide you through setting up your .shipguard.yml and configuring AI triage for your specific tech stack.
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 /golive//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
criticalorhighfinding in post-release scan - PyPI installation failure for latest tag
- CLI regression in critical path (
shipguard scan,shipguard list-rules)
Rollback steps:
- Stop promotion and notify the on-call release owner.
- Repoint users to the previous stable release tag in release notes.
- Cut a patch release from
mainwith the fix and rerun:pytest tests -qshipguard scan . --format terminal
- Publish patched tag using
.github/workflows/release.yml.
Ownership:
- Primary: repository maintainers listed in
SECURITY.md - Escalation: GitHub issue with
release-blockerlabel 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:
- Prepare version + changelog
- Update package version and append the release notes in
CHANGELOG.md.
- 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*.
- 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
- Create and push release tag
git tag vX.Y.Z
git push origin vX.Y.Z
- If publish failed before OIDC setup
- Open GitHub Actions and re-run the failed
publish.ymlrun for the same tag after trusted publisher configuration is saved.
- Post-publish smoke test
python -m pip install -U shipguard
shipguard --version
shipguard scan . --severity high
- 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
.gitignoresecret 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file shipguard-0.4.0.tar.gz.
File metadata
- Download URL: shipguard-0.4.0.tar.gz
- Upload date:
- Size: 160.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6de408ab5229df272f2e50b92ea269085ca8c905fb66abd8b52d4effe02933d5
|
|
| MD5 |
1ceb136b574e017e2574ef44e4f2f17c
|
|
| BLAKE2b-256 |
6bd71490e0c29ef960c6b272c85ba93a82457c612f647d660f7ac6ea60def9a2
|
Provenance
The following attestation bundles were made for shipguard-0.4.0.tar.gz:
Publisher:
publish.yml on celstnblacc/shipguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shipguard-0.4.0.tar.gz -
Subject digest:
6de408ab5229df272f2e50b92ea269085ca8c905fb66abd8b52d4effe02933d5 - Sigstore transparency entry: 1412745787
- Sigstore integration time:
-
Permalink:
celstnblacc/shipguard@46f3f252699536c71ffd95d7144ec2233ae6bf39 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/celstnblacc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@46f3f252699536c71ffd95d7144ec2233ae6bf39 -
Trigger Event:
push
-
Statement type:
File details
Details for the file shipguard-0.4.0-py3-none-any.whl.
File metadata
- Download URL: shipguard-0.4.0-py3-none-any.whl
- Upload date:
- Size: 60.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
467d3a7ee6489f7f64ed0c412de5f20fc8f4fec0ecbd3ed9889ef1aae1401ff7
|
|
| MD5 |
57d8222f5b846b46e7074a752cf56249
|
|
| BLAKE2b-256 |
3cd3671067b229e709d9153ae3ceaf590693396a0ea3def8f27816e69c6525ab
|
Provenance
The following attestation bundles were made for shipguard-0.4.0-py3-none-any.whl:
Publisher:
publish.yml on celstnblacc/shipguard
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
shipguard-0.4.0-py3-none-any.whl -
Subject digest:
467d3a7ee6489f7f64ed0c412de5f20fc8f4fec0ecbd3ed9889ef1aae1401ff7 - Sigstore transparency entry: 1412745856
- Sigstore integration time:
-
Permalink:
celstnblacc/shipguard@46f3f252699536c71ffd95d7144ec2233ae6bf39 -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/celstnblacc
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@46f3f252699536c71ffd95d7144ec2233ae6bf39 -
Trigger Event:
push
-
Statement type: