From Contender at Black Hat MEA 2025
Lattice is the new version of the Contender project from the Betterscan line—the contender-class security scanning work presented at Black Hat Middle East & Africa 2025 in Saudi Arabia (Riyadh).
The mission is the same: high-signal, multi-engine analysis of real codebases. This generation adds graph-native engines (Joern and Fraunhofer CPG), a Go runner with unified findings and deduplication, multi-provider VCS (including GitHub App), and a self-hosted web platform with dual frontends.
Core-limited worker pool built in Go for concurrent engine execution. Lattice orchestrates OpenGrep, Trivy, Bandit, Brakeman, Gostaticcheck, Joern, and Fraunhofer CPG.
Overlay security analysis with AI context using OpenAI-compatible endpoints to explain impact and write customized fixes directly in your reports.
No more juggling tool-specific logs. Normalizes all findings into a clean, unified schema supporting JSON, SARIF, and static HTML with smart deduplication.
Connect GitHub App (install + permissions), or PATs for GitLab, Bitbucket, and generic HTTPS git. One clone path with short-lived credentials at scan time.
Web “Scan Now” enqueues jobs on Redis. Workers clone (public or authenticated), run lattice, and write findings back to Postgres.
Next.js (:3000) and zero-build jQuery (:8081) share the same API—dashboard, projects, integrations, and scans. Playwright e2e covers click-through flows.
Joern for rules. Fraunhofer CPG for yours.
Lattice runs two code-property-graph style engines. They solve different jobs and work well together—findings can still share a file:line and collapse under smart deduplication (longest message wins). The name Lattice is the graph: nodes, edges, and structure you can query.
Excellent existing rules
Prefer Joern when you want a mature, battle-tested query / rule pack for known vulnerability patterns (querydb and community queries). This is the default path for deep, out-of-the-box graph findings.
New rules & project enforcement
Prefer Fraunhofer CPG for writing new semantic checks and enforcing project- or org-specific policies on a multi-language graph—not as a replacement for Joern’s large default query set.
That split matches how Fraunhofer presents the library: a language-independent analysis platform
((CPG docs)
with extensible frontends, passes, and analyses, plus compliance-oriented tooling such as
Codyze
for checking software against defined security goals—rather than shipping Joern-scale canned rule volume. Lattice’s cpg plugin starts with a small built-in suite (e.g. NPE / OOB) and is meant to grow with your rules.
Why a graph at all?
Standard SAST often stops at shallow regex grepping or isolated AST parsing. A code property graph unifies structure, control flow, and data flow so checks can reason about how values move—not only keyword hits.
Self-hosted Lattice web
Prefer a dashboard over the terminal? The web stack (still under lattice-web/ in the repo) is a full platform: Gin API, Postgres, Redis queue, scan worker, and two interchangeable frontends—all local via Docker Compose.
Modern UI on :3000 — dashboard, projects, findings, scans, Integrations.
Zero-build Bootstrap UI on :8081 — same API, same JWT auth.
What you can do in the UI
- ✦ Integrations: install a GitHub App (or use mock mode for local/dev), or save a PAT for GitLab / Bitbucket / GitHub / any git host.
- ✦ Projects: pick a repo from a connection or paste a URL; trigger Scan Now.
- ✦ Queued scans: API enqueues to Redis; worker clones with installation token or PAT when needed, runs lattice, stores findings.
- ✦ Dashboard & findings: trends, severity counts, false-positive workflow.
-
✦
Playwright e2e: register → login → projects → GitHub mock under
lattice-web/e2e/.
Private clone model
Secrets are encrypted at rest. At enqueue time the API mints credentials (e.g. GitHub installation token, or stored PAT). The worker rewrites
https://user:pass@host/… and never logs the password. Same path for every provider.
Provider cheat sheet
- GitHub App →
x-access-token+ install token - GitLab →
oauth2+ PAT - Bitbucket →
x-token-auth - Generic → host + token
Docs: README (VCS table, env vars), .env.example (GITHUB_APP_*, GITHUB_APP_MOCK=1, VCS_SECRET_KEY).
# Full stack (API, worker, both UIs)
cd lattice-web
docker compose up -d
# Next.js · jQuery · API
http://localhost:3000
http://localhost:8081
http://localhost:8080
GitHub App first. Every host supported.
Modern GitHub uses an App install with repository permissions—not only OAuth “login as user.” Lattice implements that flow (install URL → callback → list repos → scan with installation token), and uses the same credential plumbing for GitLab, Bitbucket, and generic HTTPS remotes via personal or project access tokens.
| Provider | Connect how | Clone auth |
|---|---|---|
| GitHub App | Integrations → Install (or mock) | x-access-token + install token |
| GitHub PAT | Token form | x-access-token |
| GitLab | PAT + host (SaaS or self-hosted) | oauth2 |
| Bitbucket | Access token / app password | x-token-auth |
| Generic git | Host + token | git (configurable) |
Usage Examples
# Run parallel scan with 8 jobs
./lattice --code-dir ./src --strategy parallel --jobs 8
# Full report with LLM enrichment
./lattice \
--code-dir ./project \
--llm-enrich \
--llm-model gpt-4.1-mini \
--sarif-out results.sarif \
--html-out results.html
Strategies & Tools
- ✓ Sequential: Predictable, step-by-step scanner execution.
- ✓ Parallel: High-speed concurrent execution using a Go worker pool.
-
✓
Auto-Install: Automatically download and configure missing local tooling dependencies using the
--install-missingflag. - ✓ Joern: Excellent existing graph rules for known vuln patterns.
- ✓ Fraunhofer CPG: New / project-specific rules and policy enforcement on the CPG library.
-
✓
Dedup: Strict or
file-linescope; longest message kept when tools agree.
Deployment Ready
Ready-to-use templates for cloud-scale automated scanning:
Built with Security in Mind
Lattice isolates every scan worker in its own hardware-enforced microVM (Qubes OS / KVM), so untrusted code that attempts a container escape is confined to a single ephemeral VM rather than shared host resources.
This is defense in depth: an independent isolation layer that protects you even when the host kernel or Docker runtime is not fully patched.