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/8The 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>andapi.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 toapi.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 reachapi.dpndncy.<ours>on TCP 443. Browsers reachdpndncy.<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 |