Analyze
Security check
What Brunel's security check looks for in a repository, dependency vulnerabilities from OSV, committed secrets, Dockerfile, Compose, CI and infrastructure-as-code risks, and how findings are reported.
Before you design production, know what could hurt you in production. The security check runs with every analysis, reads the same files as the detectors, and executes nothing.
Coverage by plan
| Check | Free | Pro and above |
|---|---|---|
| Committed secrets | Yes | Yes |
| Dockerfile and Compose | Yes | Yes |
| Known vulnerable dependencies (OSV) | — | Yes |
| CI workflows (GitHub Actions) | — | Yes |
| Existing Terraform and Kubernetes | — | Yes |
Finding format
Every finding has a severity (critical, high, medium, low), a title, the file and line it comes from, an explanation and a fix. Excerpts of secrets are masked (the first four characters, then dots) before anything is stored.
Committed secrets
Brunel looks for values that are secrets by their shape, not by guessing: AWS access keys, private keys, GitHub tokens, Stripe live secret keys, AI provider API keys, Slack tokens and webhook URLs, SendGrid keys, Google API keys, passwords inside connection strings, and filled .env files that were committed. Values found under docs/, examples/, fixtures/, tests or in Markdown files are reported one severity lower, since they are often placeholders.
Dependencies
Brunel reads exact versions from lockfiles and pinned manifests (package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock, poetry.lock, uv.lock, Pipfile.lock, go.mod, Cargo.lock, Gemfile.lock, composer.lock) and queries the public OSV database (https://osv.dev). Each vulnerable package is one finding with its versions, the advisories and the fixed version when there is one. Without a lockfile, versions are ranges and Brunel says so instead of guessing.
Dockerfiles and Compose
- Base image not pinned to a version or digest.
- The container runs as root (no
USER). - A secret baked into the image through
ENVorARG. ADDof a remote URL, or a remote script piped into a shell during the build.- World-writable permissions (
chmod 777), SSH port exposed. - In Compose: privileged containers, host network, the Docker socket mounted, database ports published on every interface, hard-coded passwords.
CI workflows
pull_request_targetworkflows, especially those that check out the pull request's code.- Untrusted input (issue titles, branch names…) interpolated directly into a shell step.
- Token permissions not declared, or write access to everything.
- Third-party actions pinned by tag instead of commit SHA.
- A step that prints a secret.
Existing infrastructure code
- Security groups open to the whole internet (all ports, or sensitive ones).
- Storage buckets readable by anyone.
- Databases reachable from the internet, storage encryption disabled.
- Passwords written in Terraform code, databases deleted without a final snapshot.
How findings feed the design
Findings are not only a report: the design takes them into account (for example a managed secrets store when secrets were committed), pull request reviews flag new ones, and reliability certificates use them as criteria.