dpndncY

Ports and networking

This page is for the people who run your network: what dpndncY needs opened, what it connects to, and why. Everything here was checked against a running installation.

#The short version

  • dpndncY needs two web addresses and one outbound path to the internet (or none, if air-gapped).
  • The two addresses are served on port 443 (HTTPS) by a reverse proxy. Nothing else is exposed.
  • One address is for people (the console). The other is for machines (the CLI, CI pipelines and agents).
  • Source code is uploaded by your pipelines to your own server. It does not leave your network.

#Inbound: what to open

Port Protocol From Purpose
443 TCP Your users, your CI runners HTTPS to both addresses. The only port anyone uses day to day
443 UDP Same Optional: HTTP/3. Safe to leave closed
80 TCP Anywhere that must reach the certificate authority Issues and renews certificates, and redirects to HTTPS. Not needed if you bring your own certificates
22 TCP Your administrators SSH to the machine. Your own policy, nothing to do with dpndncY

That is the complete list. In particular, never publish ports 3000 or 3001 to the network: they are the application's own internal ports and speak plain HTTP.

#The two addresses

Choose two DNS names that point at the machine (or at your load balancer or ingress):

Console API
Example dpndncy.example.com api.dpndncy.example.com
Used by People, in a browser The dpndncy CLI, CI pipelines (GitHub Actions, GitLab, Jenkins, Azure DevOps, Bitbucket), runtime agents
Behind it Application port 3000 Application port 3001
Sign-in Username and password, two-step verification, single sign-on An API token (a bearer token)
Public paths The sign-in page /health, /releases and the sign-in endpoints. Everything else needs a token

Why two? The web console serves the browser and does not pass other clients' requests through to the API. A deployment that publishes only the console works for people but pipelines and agents cannot reach it. Publishing the API on its own name is also what lets you restrict it separately, for example to your runners' address ranges.

   People ──── HTTPS 443 ───►  dpndncy.example.com  ──┐
                                                       ├─► reverse proxy ─┬─► console   :3000
   CLI · CI · agents ─ HTTPS 443 ─► api.dpndncy.example.com ─┘            └─► API       :3001
                                                                              │
                                                                    one data volume (database)

#Inside the machine (never exposed)

Port What Reachable from
3000 Console The reverse proxy only
3001 API The reverse proxy, and the console on the same machine
2019 Reverse proxy administration Inside the container network only

With Docker Compose these stay on a private container network. With Kubernetes they are Service ports reachable only through the Ingress.

#Outbound: what dpndncY connects to

Scanning needs vulnerability data and package information, so the machine makes outbound HTTPS (port 443) connections. Only package names and versions are sent. Your source code is never sent. If your network blocks the internet, use the offline mode and none of this applies (Running dpndncY without internet access (air-gapped)).

Destination Why Needed
api.osv.dev Vulnerability lookup by package and version Yes, unless air-gapped
services.nvd.nist.gov NVD details and CVSS scores Recommended
api.github.com GitHub security advisories; scanning GitHub repositories Recommended
www.cisa.gov The list of vulnerabilities known to be exploited Recommended
epss.empiricalsecurity.com Exploit probability scores Optional
The registries your projects use: registry.npmjs.org, pypi.org, repo1.maven.org and repo.maven.apache.org, proxy.golang.org, crates.io, rubygems.org, api.nuget.org, repo.packagist.org Licences and package metadata For the ecosystems you scan
license.dpndncy.com Online licence activation and renewal Only if you activate online. A licence file can be imported instead
acme-v02.api.letsencrypt.org Certificates, when the reverse proxy uses Let's Encrypt Not needed with your own certificates
Your mail server, identity provider, Jira, Slack and similar Only if you configure those integrations Optional
ghcr.io Pulling the container image Only when you pull from the registry. Not needed if you load the image from a file

The product sends no telemetry. A daily licence check-in (licence id and totals only) is off unless you turn it on, and is always off in air-gapped mode.

#If your network uses a proxy

Set the usual proxy variables on the container and dpndncY will use them:

HTTPS_PROXY=http://proxy.corp.example:3128
HTTP_PROXY=http://proxy.corp.example:3128
NO_PROXY=.corp.example,10.0.0.0/8

The container starts with proxy support switched on when it sees these, and automatically keeps traffic to itself (127.0.0.1, localhost) out of the proxy. Allow the destinations in the table above on the proxy. If the proxy re-signs TLS traffic, the machine must trust its certificate authority. For Docker Compose put the variables in .env; for Kubernetes use extraEnv in the Helm values.

#Certificates

You have Do this
Public DNS names and ports 80 and 443 reachable Automatic Let's Encrypt certificates. This is the default
Private DNS names, no public access Use the internal certificate authority (--internal-tls) and distribute its root certificate to browsers and CI runners once, or bring your own certificate
A certificate from your corporate authority Mount it into the proxy (Docker) or reference it in the Ingress (Kubernetes)

CI runners must trust whichever authority signs the API certificate. The CLI is a Node program, so NODE_EXTRA_CA_CERTS=/path/to/ca.pem points it at an extra certificate bundle.

#Load balancers and proxies in front

If a load balancer, WAF or ingress sits in front, set these:

Setting Value Why
Idle and read timeout 600 seconds on the API name Scans and uploads run for minutes
Maximum request body At least 256 MB on the API name Source archives are uploaded
Forwarded headers Pass X-Forwarded-For and X-Forwarded-Proto The application records the real client address and applies per-client rate limits
Buffering Off for uploads, if your device offers it Large uploads stream
Health check GET /health on the API name, expecting HTTP 200 Reports {"status":"ok",...}

#A note to send your network team

We are installing dpndncY, a software security scanner, on one server. Please publish two HTTPS names, dpndncy.<ours> and api.dpndncy.<ours>, both pointing at it, on TCP 443 (and TCP 80 if we use Let's Encrypt). Do not publish any other port. Allow the server to make outbound HTTPS to api.osv.dev, services.nvd.nist.gov, api.github.com, www.cisa.gov, and the package registries listed in the installation guide, or provide a proxy. Allow our CI runners to reach api.dpndncy.<ours> on TCP 443. Browsers reach dpndncy.<ours>.

#Checking it

From a laptop and from a CI runner:

curl -sS https://api.dpndncy.example.com/health          # {"status":"ok","version":"2.9.0",...}
curl -sSI https://dpndncy.example.com/login | head -1    # HTTP/2 200
curl -sS -o /dev/null -w "%{http_code}\n" https://api.dpndncy.example.com/api/scan-jobs    # 401: reachable, needs a token

#Mistakes we see

Mistake Result
Publishing only the console name People can sign in, pipelines cannot reach the API. The CLI gets a 404
Putting the CLI's --server at the console name Same
Blocking port 80 while using Let's Encrypt Certificates are not issued or renewed
One name for both Not supported. Use two
Exposing 3000 or 3001 directly Plain HTTP, no certificates. Always put the proxy in front
A short proxy timeout Uploads and scans are cut off after a minute or so
Browsing to a different name than the one configured Sign-in fails with "request could not be verified". Use exactly the console address you configured