The rule it started with
One line of YAML puts your database on the internet.
Docker writes firewall rules directly when it maps a port, so this goes around UFW no matter how carefully you configured it. Checkov, Trivy, Snyk and Semgrep all parse the file happily.
ports: - "5432:5432" # binds 0.0.0.0 - "127.0.0.1:5432:5432" # host only
BLOCKED — 1 CRITICAL/HIGH finding(s): ──────────────────────────────────────────────── [CRITICAL] VGL-D001 — Port 5432 bound to 0.0.0.0 — Docker bypasses UFW; service is publicly reachable from the internet at docker-compose.yml:5 → - "5432:5432" fix: Change to "127.0.0.1:5432:5432" (or 0.0.0.0 only for nginx 80/443 which are intentionally public). $ echo $? 2
How it works
Wire it in once. It runs on every write after that.
No configuration file to author, no rules to enable. Critical and high findings stop the change and hand back the rule, the location and the fix.
1 · Install
pip install valca — stdlib-only, so nothing else is installed
alongside it.
2 · Hook it up
valca init --global registers Valca with Claude Code for every
project on the machine.
3 · Keep working
Your assistant gets the finding and the fix immediately, while the change is still in front of it.
Coverage
116 rules across 27 categories.
Each one exists because something shipped that shouldn't have. The newest families cover the surface that only appears once an agent is doing the typing.
Integrations
Wherever the code is being written.
Claude Code
A hook on every write, so it runs whether the model thinks to ask or not. A scanner the assistant can skip is a scanner the assistant will skip.
VS Code, Cursor, Windsurf
Scans on save and reports inline, where you are already looking.
Any CI
Exit codes drive the gate; SARIF output feeds code-scanning annotations. No plugin required.
MCP
Agents can call the scanner themselves. Read-only, and it never returns the matched line — a credential it finds doesn't travel into a model's context.
Licensing
Free in production. Honest about the terms.
Business Source License 1.1. Use it commercially at no cost. The one restriction is offering Valca itself as a hosted service competing with its paid tier. Every release converts to MIT four years after it ships.
BUSL is not an OSI-approved open source licence, and calling it one would be dishonest. The source is public and auditable, which is the property that matters for a tool you let near your codebase.
Zero runtime dependencies
Valca is stdlib-only Python 3.11+. It adds no supply chain of its own — which matters, because several of its own rules exist to catch exactly that problem in other people's projects.