Broly

module
v0.1.90 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 2, 2026 License: MIT

README

Broly

Broly

A berserker code security scanner.

Secrets · SCA · SAST · Containers in a single binary. AI-powered. No rule files. No rule engine.

Go License Release Together AI


What It Does

Scanner Engine AI Layer
Secrets Titus · 487 rules · Hyperscan --ai-filter-secrets eliminates false positives
SCA osv-scalibr + osv.dev · 19 ecosystems --ai-sca-reachability checks if the vuln is actually called
SAST Together AI · Qwen/Qwen3-Coder-Next-FP8 Source-to-sink data flow · CVSS scoring
Dockerfile AI-powered · Dockerfile, Containerfile, Compose Privilege escalation, secret exposure, dangerous mounts
Container go-containerregistry + osv.dev · Alpine, Debian, Ubuntu, RHEL OS package CVEs with layer attribution

Install

go install github.com/Shasheen8/Broly/cmd/broly@latest

Pre-built Linux binaries on Releases. macOS: build from source with brew install vectorscan && make build for Hyperscan support.

SAST and AI features are powered by Together AI and require an API key:

export TOGETHER_API_KEY=your_key_here

Usage

broly scan                                         # all scanners, current directory
broly scan /path/to/project                        # specific path


# individual scanners
broly scan --secrets                               # secrets only
broly scan --sca                                   # SCA only
broly scan --sast                                  # SAST only (requires TOGETHER_API_KEY)


# AI enhancements
broly scan --ai-filter-secrets                     # filter secrets false positives with AI
broly scan --ai-sca-reachability                   # check if vulnerable deps are actually called
broly scan --ai-triage                             # verdict (TP/FP) + fix suggestion per finding
broly scan --ai-triage --explain                   # + concise attack-scenario sentence per finding


# container scanning
broly scan --container alpine:3.19                 # scan a container image for vulnerabilities
broly scan --container ./image.tar                 # scan from tarball


# output
broly scan -f json                                 # JSON output
broly scan -f sarif -o results.sarif               # SARIF 2.1.0 for GitHub Code Scanning
broly scan --min-severity high                     # only high and critical


# config
broly scan --config .broly.yaml                    # load project config file
broly scan --baseline .broly-baseline.yaml         # suppress known FPs / require specific findings
broly scan --incremental                           # skip unchanged files (uses .broly-cache.json)

Scanner Output

SAST

Each file is sent to the LLM with a structured security prompt. The model traces data flow from source to sink, infers CVSS scores, and finds what static rules miss.

  ▸ SAST (4 findings)

  SEVERITY     ISSUE                            FILE                      DESCRIPTION
  ──────────────────────────────────────────────────────────────────────────────────────────────────
  CRITICAL     SQL injection via unsanitize..   api/handlers.py:10        User input flows directly ..
  CRITICAL     OS command injection via uns..   api/handlers.py:15        OS command injection via u..
  HIGH         Path traversal in read_file      api/handlers.py:20        Path traversal in read_fil..
  HIGH         Insecure deserialization via..   api/handlers.py:25        Insecure deserialization v..
Dockerfile and Compose

Auto-detected during normal scans. Specialized prompts cover privilege escalation, hardcoded secrets, dangerous mounts, unpinned base images, and more.

  ▸ DOCKERFILE (4 findings)

  SEVERITY     ISSUE                            FILE                                DESCRIPTION
  ──────────────────────────────────────────────────────────────────────────────────────────────────
  CRITICAL     Hardcoded secrets in ENV/ARG     Dockerfile:3                        Secrets visible in image hi..
  CRITICAL     Docker socket mounted            docker-compose.yml:14               Full control over Docker da..
  HIGH         curl piped to bash               Dockerfile:10                       Compromised script runs as ..
  MEDIUM       Running as root (no USER)        Dockerfile:1                        Increases blast radius of a..
Secrets

487 rules. --ai-filter-secrets reads surrounding code context and eliminates placeholders and test values:

  ▸ SECRETS (3 findings)

  SEVERITY     RULE                             FILE                      REDACTED
  ──────────────────────────────────────────────────────────────────────────────────
  HIGH         AWS API Key                      config/example.py:6       AKIA****MPLE
  HIGH         AWS API Credentials              config/example.py:6       AKIA****KEY"
  HIGH         GitHub Personal Access Token     config/example.py:9       ghp_****8B4a
SCA

19 ecosystems, 50+ lockfile formats. --ai-sca-reachability checks if the vulnerable function is actually called:

  ▸ SCA (3 findings)

  SEVERITY     VULN ID                PACKAGE            VERSION        FIXED            ECOSYSTEM
  ──────────────────────────────────────────────────────────────────────────────────────────────────
  MEDIUM       GHSA-9hjg-9r4m-mvj7    requests           2.31.0         no patch         PyPI
  MEDIUM       GHSA-496j-2rq6-j6cc    grpcio             1.54.0         no patch         PyPI
  MEDIUM       GHSA-cfgp-2977-2fmm    grpcio             1.54.0         no patch         PyPI
Container

--container pulls an image, extracts OS packages, and matches against OSV. Each finding shows which layer introduced it:

  ▸ CONTAINER (5 findings)

  SEVERITY     VULN ID                PACKAGE            VERSION        FIXED            ECOSYSTEM          LAYER
  ────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  MEDIUM       ALPINE-CVE-2023-42..   busybox            1.36.1-r2      no patch         Alpine:v3.18       #1
  MEDIUM       ALPINE-CVE-2025-26..   musl               1.2.4-r1       no patch         Alpine:v3.18       #1
AI Triage

--ai-triage labels each finding TRUE/FALSE positive with a confidence score and a fix. For container/SCA findings with no patch, it suggests mitigations. --explain adds a one-sentence attack scenario:

  CRITICAL     SQL injection via unsanitize..   api/handlers.py:10        User input flows directly ..
  🔺 TRUE_POSITIVE [HIGH]  User input flows directly into raw SQL query without parameterization
      An attacker sends id=1 OR 1=1 to dump the entire users table.
    fix:
      query = "SELECT * FROM users WHERE id = %s"
      cursor.execute(query, (user_id,))

  HIGH         Path traversal in read_file      api/handlers.py:20        Path traversal in read_fil..
  🟢 FALSE_POSITIVE [HIGH]  File path is validated against an allowlist before use

Developer Feedback Loop

Check a box in the PR comment to mark a finding as a false positive. Broly verifies write access, commits the fingerprint to .broly-baseline.yaml, and the finding never surfaces again.

- [ ] 🔴 CRITICAL · SQL injection in get_user() · api/handlers.py:7

Suppressions accumulate over time; each repo builds its own false positive memory.


GitHub App

Install once, scans every PR automatically. No per-repo workflow setup.

The app clones the repo at the PR head, runs Broly with AI triage, and posts findings as a check run + PR comment. Only findings in changed files are reported — no historic noise.

# run the app server locally
APP_ID=123456 PRIVATE_KEY_PATH=./app.pem WEBHOOK_SECRET=your_secret go run ./cmd/broly-app

Configuration

Config file

[!TIP] .broly.yaml is loaded automatically from the repo root. CLI flags always override it.

min_severity: low
exclude_paths:
  - vendor
  - .git
workers: 8
Baseline

[!NOTE] suppress silences known false positives. require asserts specific findings must be detected every scan; missing entries cause a non-zero exit.

suppress:
  - fingerprint: "abc123..."
    reason: "test fixture"

require:
  - rule_id: "SQL-INJECTION"
    file: "api/handlers.py"
    reason: "SQL injection in user lookup - must be detected"
Inline suppression
query = "SELECT * FROM users WHERE id = " + user_id  # broly:ignore
query = f"SELECT * FROM users WHERE id = {user_id}"  # broly:ignore SQL-INJECTION

Acknowledgments

Project Role
Titus Secrets engine: 487 rules, Hyperscan + Go regex
osv-scalibr Lockfile extraction across 50+ formats
osv.dev Vulnerability database by Google
go-containerregistry Container image pulling and layer inspection
go-github + ghinstallation GitHub App authentication and API
Together AI AI inference for SAST, triage, and reachability

License

MIT. See LICENSE for the full text.

Directories

Path Synopsis
cmd
broly command
broly-app command
broly-app is a GitHub App webhook server that scans PRs and pushes with Broly.
broly-app is a GitHub App webhook server that scans PRs and pushes with Broly.
pkg
ai
Package ai provides a shared Together.ai client for all Broly scanners.
Package ai provides a shared Together.ai client for all Broly scanners.
cache
Package cache provides a file-hash cache for incremental scanning.
Package cache provides a file-hash cache for incremental scanning.
container
Package container scans container images for OS and language package vulnerabilities.
Package container scans container images for OS and language package vulnerabilities.
sast
Package sast provides AI-powered static application security testing.
Package sast provides AI-powered static application security testing.
sbom
Package sbom generates Software Bill of Materials in CycloneDX and SPDX formats.
Package sbom generates Software Bill of Materials in CycloneDX and SPDX formats.
sca
Package sca adapts osv-scalibr + osv.dev to Broly's core.Scanner interface.
Package sca adapts osv-scalibr + osv.dev to Broly's core.Scanner interface.
secrets
Package secrets adapts Titus's engine to Broly's core.Scanner interface.
Package secrets adapts Titus's engine to Broly's core.Scanner interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL