A governed control plane for software composition analysis, recon, evidence, and reporting. Deterministic where it counts, bounded where it helps, provable end to end.
Synapse turns a fragmented, manual security process into a controlled, auditable workflow: software composition analysis, recon, evidence capture, findings, and reporting. Scanning, matching, license classification, and reporting are pure, reproducible Go with nothing else in the path. Where automated analysis is offered it stays strictly bounded: a proposal is only ever proposed, a typed Go state machine validates and executes, and a human approves anything intrusive.
Built as clean-architecture Go with a strict dependency rule. Every capability sits behind a port, so tools, storage, and providers are swappable.
Fifteen-plus ecosystems (npm, PyPI, Maven, Gradle, Go, Cargo, RubyGems, Composer, NuGet, Hex, Dart and more) with owned per-ecosystem lockfile parsers and a pluggable producer.
A live advisory API and an offline database, cross-correlated and de-duplicated, plus an owned advisory store that ingests OSV, GHSA and CSAF feeds for detection independence.
Findings are ordered by exploitability (known-exploited catalog, then exploit-prediction score, then CVSS), never by raw CVSS alone.
Declared-license resolution, SPDX expression parsing (AND, OR, WITH), a curated category and risk model, and coordinate recovery for shaded or metadata-less JARs.
A deterministic call-graph engine decides whether a vulnerable symbol is actually reachable from application code, so a finding on unused code can be de-prioritized.
Every artifact is hash-chained. A broken chain blocks the report. Audit and evidence logs are append-only and can be anchored with an RFC-3161 timestamp.
Heavy tools are shelled out via argv arrays, never a shell string, inside a Linux sandbox with egress scoping. Scope and the authorization window are enforced before any tool runs.
Per-action role-based access control and tenant isolation flow through a single authorization chokepoint. Secrets stay server-side in a credential vault.
CycloneDX and SPDX with PURL, SARIF, OpenVEX and CSAF, plus KEV and EPSS. Import a client SBOM as the scan inventory, export the results in the format they expect.
An optional analysis layer proposes reachability, critique, threat and write-up drafts. Every claim goes through propose, verify, confirm, gated by a distinct verifier or a human. No model ever sits in the report path.
Every screen below is the current build. Tables virtualize past fifty rows, and loading, empty and error states are handled throughout.
Engagements overview: every scan is gated by a scope and an authorization window, enforced server-side.
Token login with no anonymous access, and a first-run Acceptable Use Policy gate the operator must accept.


Define an authorized scope and window, then work the engagement: inventory, findings, evidence, and reports in one place.


Vulnerabilities ranked by real risk, promoted into findings you can triage as a table or a board.



The full component inventory, license posture with SPDX categories, and the resolved dependency graph.



The bounded agent proposes, a human approves. Evidence is hash-chained, and every action lands in an append-only audit log.



Role-based team management and per-engagement settings.


The API, SCA, findings and reports run on any OS for development. The hardened sandbox, live recon and egress scoping need a Linux host.
Pinned in go.mod. Builds cgo-free, so the container image is distroless.
For the web dashboard. Use pnpm, not npm or yarn.
Syft is required for any scan. Grype is optional and adds the offline database. make tools installs both, pinned and checksum-verified.
For durable persistence and evidence artifacts. A blank DSN runs an in-memory dev store.
The easiest way to run the full stack, and the simplest path to a complete run on any OS.
bubblewrap, seccomp, cgroups and network namespaces. Without them, sandboxed execution fails closed rather than running unsandboxed.
Pick the path that fits: run the full stack with Docker, or build and run it natively.
Grab the source and change into it.
make install pulls Go modules and web deps. make tools installs Syft and Grype into ./bin.
SYNAPSE_API_TOKEN is mandatory. The server refuses to start without it. There is no anonymous access.
make dev starts the API on :8080 and the dashboard on :5173. Open the dashboard, paste the token, accept the AUP.
# Postgres, object store, API (syft + grype bundled), dashboard docker compose -f deploy/docker-compose.full.yml up --build # then open open http://localhost:5173
make install make tools export PATH="$PWD/bin:$PATH" export SYNAPSE_API_TOKEN="$(openssl rand -hex 32)" # blank DB DSN runs an in-memory dev store make dev
Migrations are embedded in the binary and applied automatically at startup. There is no separate migrate step. A blank SYNAPSE_DB_DSN runs fully in memory, so nothing is persisted.
Synapse reads the process environment directly. Copy .env.example and adjust. Empty means unset, so the built-in default applies. Booleans accept 1/0/true/false, durations use Go syntax (30s, 10m, 1h).
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_API_TOKEN | (none) | Bootstrap-admin bearer token. The API exits if empty. Generate with openssl rand -hex 32. |
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_HTTP_ADDR | :8080 | Listen address. |
SYNAPSE_ENV | development | Non-prod values: development, dev, local, test, ci. Any other value is treated as production and turns on the strict, fail-closed gates. |
SYNAPSE_LOG_LEVEL | info | Log verbosity. |
SYNAPSE_AUP_VERSION | 1.0 | Acceptable Use Policy version the operator must accept on first run. |
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_DB_DSN | (in-memory) | PostgreSQL connection URL. Empty runs an in-memory dev store, so nothing is durable. |
SYNAPSE_BLOB_ENDPOINT | (in-memory) | S3 or MinIO endpoint as host:port. Empty runs an in-memory blob store. Pairs with SYNAPSE_BLOB_ACCESS_KEY, SYNAPSE_BLOB_SECRET_KEY, SYNAPSE_BLOB_BUCKET. |
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_VAULT_MASTER_KEY | (ephemeral) | AES-256 credential-vault master key. Empty uses an ephemeral dev key, so stored secrets do not survive a restart. Never logged. |
SYNAPSE_EVIDENCE_SIGNING_SEED | (ephemeral) | ed25519 seed attesting evidence and audit chain heads. Never logged. |
SYNAPSE_TSA_URL | (none) | RFC-3161 timestamp authority for external anchoring. Empty leaves the chain signed but not anchored, still tamper-evident. |
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_SBOM_PRODUCER | syft | syft (pinned binary, full coverage, dep-graph edges) or ownsbom (detection-independent owned parsers, components only). |
SYNAPSE_GRYPE_DB_DIR | (online) | Pin Grype's vuln database to a pre-synced directory for offline, reproducible scans. |
SYNAPSE_FINDING_MIN_SEVERITY | high | Lowest severity promoted to a finding: critical, high, medium, low, info. |
SYNAPSE_SCAN_TIMEOUT | 10m | Per-scan timeout. 0 disables. |
SYNAPSE_OWNED_ADVISORY | false | Match the SBOM against the owned advisory store, alongside the live and offline sources. Populate it first with synapse-cli sync-advisories. |
SYNAPSE_JARHASH_ONLINE_ENABLED | false | Recover the coordinate of a shaded or metadata-less JAR by its SHA-1, so its vulnerabilities are attributed. |
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_SANDBOX_ENABLED | false | Run tool execution inside the bubblewrap sandbox. If set but bubblewrap is missing, startup fails closed and never runs unsandboxed. |
SYNAPSE_TOOL_HASHES | (TOFU) | Authoritative sha256 pins. The sandbox refuses a binary whose hash does not match. |
SYNAPSE_RECON_VIA_WORKER | false | Route recon through the durable queue to synapse-worker. Requires PostgreSQL. |
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_AGENT_ENABLED | false | Turn on the agent orchestrator. |
SYNAPSE_LLM_BASE_URL | (none) | OpenAI-compatible Chat Completions endpoint. Pairs with SYNAPSE_LLM_API_KEY (never logged) and SYNAPSE_LLM_MODEL (required when the agent is enabled). |
SYNAPSE_AGENT_APPROVAL_MODE | manual | Human-in-the-loop approval: manual (a human approves every action), filter, or auto. |
SYNAPSE_AGENT_MAX_STEPS | 16 | Per-run bound on agent steps. See also token budget and max duration. |
| Variable | Default | What it does |
|---|---|---|
SYNAPSE_JUDGMENTS_ENABLED | false | Judgment lifecycle routes (verify, accept, list). Prerequisite for the analyzers below. |
SYNAPSE_SAST_ENABLED | false | Pattern SAST in the scan pipeline: weak crypto, hardcoded secrets, insecure config. |
SYNAPSE_REACHABILITY_ENABLED | false | Call-graph reachability proof. A deterministic proof overrides an LLM opinion. |
SYNAPSE_CROSSCHECK_ENABLED | false | Detection-source disagreement judgments, human-reviewed. |
SYNAPSE_WRITEUP_DRAFTS_ENABLED | false | Agent proposes finding write-up prose. A distinct human signs off. |
This is the working set. The full reference, including connection-pool sizing, recon bounds, MCP server variables and feed overrides, lives in .env.example with an inline note on every option.
synapse-cli runs the same pipeline as the server. It creates an ephemeral, scope-checked engagement, so scope enforcement is exercised, not bypassed. Nothing is persisted.
# exit non-zero on any high-or-critical vuln ./bin/synapse-cli scan . --fail-on high # licenses only ./bin/synapse-cli scan . --mode licenses # scan a container image, offline ./bin/synapse-cli scan alpine:3.19 --image --offline
- name: SCA scan run: | make tools make build ./bin/synapse-cli scan . --fail-on high
Exit code is 0 when no finding meets the threshold, non-zero otherwise. Wire it straight into a pipeline step.
All external I/O (database, tools, storage, sandbox) goes through ports, which are interfaces in the usecase layer. The composition root wires them in main, with no business logic.
| Binary | Role |
|---|---|
synapse-api | HTTP API server, the primary service. |
synapse-cli | Run an SCA scan from the command line, CI-friendly. |
synapse-worker | Durable job runner for recon and background jobs, lease-based. |
synapse-callgraph | Sandboxed call-graph builder for reachability analysis. |
synapse-mcp | Read-only, propose-only integration server. Never executes. |
| Layer | May import |
|---|---|
internal/domain | Only domain and the standard library. |
internal/usecase | domain and the ports it defines. |
internal/adapter | usecase and domain. |
internal/infrastructure | Implements the ports (DB, tools, storage). |
internal/platform | Cross-cutting helpers (config, ids, logging). |
Synapse started as a small team effort. The engineers who shaped the platform and the designer behind its brand identity.