README
¶
foxguard
Fast local security guard for changed files, built-in rules, and Semgrep-compatible YAML.
foxguard.dev | crates.io | npm
Fast local security guard for JS/TS, Python, and Go.
What foxguard is
foxguard is a Rust security guard built for the edit-save-commit loop. It runs locally, scans quickly, emits terminal/JSON/SARIF output, includes a first-class secrets mode, and can load Semgrep-compatible YAML rules with --rules.
The point of the product is not "our opinionated rules vs everyone else's". The point is fast security feedback in a form teams can actually drop into existing workflows.
Use it:
- on a repo before commit
- in scripts and CI
- with the built-in rules
- with your own Semgrep-style or OpenGrep-style rules
Install
cargo install foxguard
npx foxguard .
Usage
foxguard .
foxguard --severity high .
foxguard --format json .
foxguard --format sarif .
foxguard secrets .
foxguard --rules ./rules .
foxguard --changed .
foxguard secrets --changed .
foxguard baseline --output .foxguard/baseline.json
foxguard init
foxguard secrets --exclude-path fixtures --ignore-rule secret/github-token .
foxguard --config .foxguard.yml .
src/app.js
12:5 CRITICAL js/express-no-hardcoded-session-secret (CWE-798)
Hardcoded session secret -- use environment variables
45:3 HIGH js/express-direct-response-write (CWE-79)
res.send() called with user input -- risk of reflected XSS
WARNING 2 issues found: 1 critical, 1 high, 0 medium, 0 low
Why foxguard
- Fast enough to run locally without becoming background noise
- Single binary, no JVM, no Python runtime, no network calls
- First-class secrets scan for common leaked credentials and key material
- Semgrep-compatible rule loading via
--rules - Built-in security coverage out of the box
- SARIF output for code scanning and CI systems
foxguard is best thought of as a fast security engine you can slot into your workflow, not as a closed rules product.
Repo config
foxguard can auto-discover ./.foxguard.yml, ./.foxguard.yaml, ./foxguard.yml, or ./foxguard.yaml from the scan path upward. You can also point at an explicit file with --config.
Relative paths inside the config are resolved from the config file location.
Example:
scan:
baseline: .foxguard/baseline.json
rules: ./semgrep-rules
secrets:
baseline: .foxguard/secrets-baseline.json
exclude_paths:
- fixtures
- testdata
ignore_rules:
- secret/github-token
CLI flags still win over config values.
Local guard workflow
Install foxguard as a repo-local guard:
foxguard init
That installs a pre-commit hook and writes a starter .foxguard.yml when one does not already exist. By default, the generated config points at .foxguard/baseline.json and .foxguard/secrets-baseline.json, so the hook can stay on the clean --config ... --changed path.
Useful commands:
foxguard --changed .foxguard secrets --changed .foxguard --config .foxguard.yml .foxguard baseline --output .foxguard/baseline.jsonfoxguard --baseline .foxguard/baseline.json .
Secrets mode
Use the built-in secrets scanner when you want fast local checks for obvious leaked credentials and key material:
foxguard secrets .
foxguard secrets --changed .
foxguard secrets --write-baseline .foxguard/secrets-baseline.json .
foxguard secrets --baseline .foxguard/secrets-baseline.json .
foxguard secrets --exclude-path fixtures --exclude-path-file .foxguard/secrets.ignore .
foxguard secrets --ignore-rule secret/github-token .
Current patterns include AWS access keys and secret access keys, GitHub, GitLab, npm, Slack, and Stripe tokens plus private key headers.
Secrets findings are redacted in output, secrets baselines store suppression fingerprints rather than raw secret values, and binary files are skipped.
Use --exclude-path for repo-relative file or directory prefixes, --exclude-path-file for a newline-delimited ignore list, and --ignore-rule when a specific secret pattern is intentionally present in test fixtures or examples.
The same defaults can live in foxguard.yml or .foxguard.yml for local hooks and CI runs.
Bring your own rules
foxguard can load Semgrep-compatible YAML rules from a file or directory:
foxguard --rules ./semgrep-rules .
By default, foxguard runs its built-in rules. Use --rules to add external rules on top. Use --no-builtins --rules ... when you want an external-rules-only compatibility run.
foxguard currently supports a useful Semgrep-compatible subset for local rule loading. That makes it a good fit for teams already using Semgrep or OpenGrep-style rules, without claiming full drop-in compatibility.
That subset now includes regex clauses such as pattern-regex and pattern-not-regex in addition to the AST-style operators listed in COMPATIBILITY.md.
It also supports rule-level path scoping with paths.include and paths.exclude.
It now also supports metavariable-regex for regex-constraining bound metavariables inside patterns.
It also supports pattern-not-inside for excluding matches that appear inside known-safe wrapper contexts.
See COMPATIBILITY.md for the supported subset and the intended built-ins-first workflow.
Built-in coverage
foxguard currently ships with 59 built-in code rules across 3 languages:
| Language | Rules | Frameworks |
|---|---|---|
| JavaScript/TypeScript | 25 | Express, outbound request checks, JWT flows |
| Python | 26 | Flask, Django, outbound request checks |
| Go | 8 | Gin, net/http request flows, TLS transport checks |
Examples of included checks:
- Hardcoded secrets and placeholder credentials
- SQL injection via string interpolation
- Command injection via exec/spawn
- XSS via unsafe response or DOM writes
- Weak crypto such as MD5 and SHA1
- SSRF via dynamic outbound requests and common client variants
- Path traversal across file and response-file operations
- Unsafe deserialization
- Auth, session, and framework misconfigurations
Framework-oriented highlights:
- Express and Node apps: session secret handling, cookie flags, direct response writes, JWT hardcoding, JWT
nonealgorithm, JWT expiry bypass, and JWT decode-without-verify - Flask and Django apps: hardcoded secret keys, debug mode, session cookie flags, CSRF cookie flags,
@csrf_exempt, Flask-WTF CSRF enforcement,ALLOWED_HOSTS, and HTTPS redirect settings - Gin and net/http services: trusted proxy config, request timeouts, outbound request misuse, and TLS verification bypass
GitHub Action
- uses: peaktwilight/foxguard/action@v1
with:
path: .
severity: medium
Performance
The benchmark suite supports two modes:
default: foxguard built-ins vs Semgrep/OpenGrepautocompat: the same Semgrep-compatible YAML rules across foxguard, Semgrep, and OpenGrep
Built-ins are the default product path. compat exists to answer the narrower same-rules question fairly.
Benchmark outputs are written locally as benchmarks/results-default.md and benchmarks/results-compat.md. Rust + tree-sitter + rayon. See benchmarks/README.md for methodology, commands, and notes about missing competitor binaries.
For the homepage-style visual comparison, use default mode. For compatibility checks, use compat.
License
MIT