One signing root. Three operational layers.
Where each component runs, what flows between them, and what signed evidence looks like end-to-end.
The three layers
Every dpndncY capability sits in exactly one of three layers: Scan, Block, or Sign. They share the same signal stack (CISA KEV + EPSS + ExploitDB + reachability + attack-path + license obligations) and the same RSA signing keypair. What changes between layers is where the decision lives.
Scan
SCA (30+ ecosystems), native SAST (400+ rules, 24 languages), IaC (Terraform / CloudFormation / Kubernetes), high-precision secrets, container image (OCI tarball + 9 in-image ecosystems), attack-path graph, JS/TS reachability, AI-risk attribution. Runs on the dpndncY server. Findings emerge in a unified view, with SARIF 2.1.0 / CycloneDX 1.5 / SPDX export.
Block
Two enforcement components: the Dependency Firewall (package-manager admission control, configured via .npmrc / pip.conf / settings.xml / env vars) and the eBPF Runtime Agent (Linux daemon on CI runners attaching to four kernel hooks). The firewall runs as part of the server; the runtime agent runs on the runner itself.
Sign
Every decision the server or the agent makes is wrapped in a DSSE envelope over a SLSA in-toto v1 Statement and signed with the per-tenant RSA keypair. The standalone dpndncy-verify binary checks signatures offline with one public key.
Components
| Component | Runs on | Language |
|---|---|---|
| Server (web UI + API) | Container / VM / metal — your infra | Node.js 20 + Express 5 |
| Database | Embedded in the server, or external | SQLite (default) · PostgreSQL 16 (production / HA) |
| Scan engine | Same host as server | Python 3.12 (per-ecosystem scanners) |
| Dependency Firewall | Same host as server (registry-proxy mode) | Node.js |
| eBPF Runtime Agent | CI runner host | Go + libbpf CO-RE |
| dpndncy-verify | Anywhere with a public key | Static Go binary |
| VS Code extension | Developer workstation | TypeScript |
| CLI | Anywhere | Node.js |
Storage & state
All persistent state lives in one place — there is no external service dependency unless you add one. By default the server runs on an embedded SQLite database under the data volume (/data), which also holds scan artifacts, the signing-key archive, and attestation history. For production and high-availability deployments, point DATABASE_URL at an external PostgreSQL 16 instance (the Helm chart and the on-prem compose overlay ship a bundled Postgres option). The application speaks one SQL dialect and an adapter translates to whichever backend is configured, so migrations and behaviour are identical on both.
Data flow — what gets signed
Three primary signed events flow through the system:
https://dpndncy.io/scan/v1 // emitted per scan
https://dpndncy.io/firewall/v1 // emitted per allow / block / bypass
https://dpndncy.io/agent/runtime-trace/v1 // emitted per CI job by the eBPF agentEach event carries the decision, every signal that produced it (with source URLs and timestamps), the policy version applied, and (for runtime traces) the SHA-256 of the full event-log NDJSON bound into the signature.
/data/keys/archive/.What never leaves your infrastructure
By default, nothing. dpndncY has no telemetry, no remote callbacks, no remote licence check. Advisory data (OSV, NVD, GHSA, CISA KEV, EPSS, ExploitDB) is pulled from public sources; in air-gapped mode it’s loaded from offline bundles.