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

CheckFreePro and above
Committed secretsYesYes
Dockerfile and ComposeYesYes
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 ENV or ARG.
  • ADD of 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_target workflows, 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.

Security check · Brunel Docs