Broly

module
v0.1.116 Latest Latest
Warning

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

Go to latest
Published: Apr 8, 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 · 20 ecosystems --ai-sca-reachability checks if the vuln is actually called · --package-intelligence detects hallucinated/non-existent dependencies
SAST Together AI · Qwen/Qwen3-Coder-Next-FP8 + regex pre-filter Slice-aware multi-file analysis · source-to-sink data flow · 17 deterministic patterns · priority 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
License File-based detection · 13 license types Policy engine: allowed_licenses / denied_licenses in .broly.yaml
SBOM osv-scalibr · 20 ecosystems broly sbom generates CycloneDX 1.5 or SPDX 2.3 with PURLs

Install

Go install:

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

Pre-built binaries (Linux/macOS) — download from Releases.

From source (full Hyperscan support for secrets engine):

brew install vectorscan   # macOS
make build

SAST and AI features require a Together AI 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 --package-intelligence                 # detect hallucinated/non-existent packages
broly scan --ai-triage                            # verdict (TP/FP) + fix suggestion per finding
broly scan --ai-triage --explain                  # + one-sentence attack scenario per finding

# Container scanning
broly scan --container alpine:3.19                # pull and scan a registry image
broly scan --container ./image.tar                # scan from a local 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

# SBOM
broly sbom                                        # CycloneDX 1.5 to stdout
broly sbom -f spdx -o sbom.json                   # SPDX 2.3 to file

# Config and suppression
broly scan --config .broly.yaml                   # project config; also activates license policy
broly scan --baseline .broly-baseline.yaml        # suppress known FPs / require specific findings
broly scan --incremental                          # skip unchanged files

Scanner Output

Demo videos coming soon.

Each scanner outputs an aligned table in the terminal. Supports JSON (-f json), SARIF (-f sarif), and table (default).

AI Triage

--ai-triage adds a verdict, confidence score, and fix suggestion to every finding. --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

CI Integration

GitHub App — install once on your org, scans every PR automatically. No per-repo setup needed.

Reusable workflow — drop one line into any repo's existing CI:

jobs:
  security:
    uses: Shasheen8/Broly/.github/workflows/broly-scan.yml@main
    secrets:
      together_api_key: ${{ secrets.TOGETHER_API_KEY }}

Supports min_severity, scanners, and ai_triage inputs. Posts findings as a PR comment and uploads SARIF to the GitHub Security tab.

GitHub App

Install once on your org, scans every PR automatically. No per-repo workflow setup. Only findings in changed files are reported — no historic noise.

Check a box in the PR comment to mark a finding as a false positive. Broly commits the fingerprint to .broly-baseline.yaml and the finding never surfaces again. Suppressions accumulate over time — each repo builds its own false positive memory.

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

Multi-stage Dockerfile at cmd/broly-app/Dockerfile. Uses Chainguard hardened images — non-root, no shell, minimal attack surface.

docker build -f cmd/broly-app/Dockerfile -t broly-app .

docker run -p 8080:8080 \
  -e APP_ID=123456 \
  -e PRIVATE_KEY_PATH=/secrets/app.pem \
  -e WEBHOOK_SECRET=your_secret \
  -e TOGETHER_API_KEY=your_key \
  -v /path/to/app.pem:/secrets/app.pem:ro \
  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

# License policy (findings only emitted when configured)
allowed_licenses:
  - MIT
  - Apache-2.0
  - BSD-2-Clause
  - BSD-3-Clause
  - ISC
denied_licenses:
  - GPL-3.0
  - AGPL-3.0
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

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.
license
Package license detects software licenses and checks them against a policy.
Package license detects software licenses and checks them against a policy.
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