Proxy Configuration (Restricted / No Internet Access)¶
Repod is fully usable with zero internet access — nothing it does requires outbound connectivity by default. But a handful of optional features reach out to public sources, and if your server sits behind a restricted egress (a security team that only allows specific domains, or a fully air-gapped site), you need to know exactly what to allow — and how to route it through a proxy.
This page lists every outbound dependency, explains how to route them through a corporate proxy, and gives a worked example using Squid with a domain-allowlist, which is the pattern most regulated environments already use for controlled egress.
What actually needs internet access¶
Nothing in the core upload → scan → publish → serve pipeline requires internet access. Everything below is either optional or only triggered by a specific action.
| Dependency | Triggered by | Can run fully offline? |
|---|---|---|
| ClamAV signature updates | Automatic (freshclam daemon) |
Yes — works with whatever signatures are already cached; only updates need connectivity |
| Grype vulnerability database | Automatic, periodic | Yes — same as above, CVE matching uses the last successfully downloaded database |
| EPSS scores / CISA KEV catalog | Every CVE scan | Yes — 24h local cache; a package that was already scanned once keeps working offline |
| Upstream security sync (Debian/Ubuntu/RPM security advisories) | Scheduled sync job (disabled by default) | N/A — this feature is inherently about fetching external advisories |
| "Import from internet" (upstream package mirrors, Maven Central, PyPI, npmjs.org, Docker Hub) | Explicit user action ("Import" tab) | N/A — only used if you choose to import from a public source |
| Upstream cache (pull-through proxy for apt/dnf clients) | Client requests to /upstream/... |
N/A — see Upstream cache, a separate air-gap-oriented feature |
| License usage reporting | Opt-in only (settings["license_reporting"]["enabled"]) |
Yes — license validation is 100% offline; reporting is purely informational |
| LDAP / OIDC / SMTP / webhook notifications | Whatever you configure | Depends entirely on where your IdP/SMTP relay/webhook endpoint lives (often internal) |
If your policy is "no internet, full stop", the pipeline still runs — CVE and antivirus scanning use whatever data was cached during your last connected window (or an air-gapped cache seeded from a relay host), and you simply never use the "Import from internet" tab.
Routing outbound calls through a proxy¶
Most of the table above goes over plain HTTP(S) from the backend container,
using clients that respect the standard proxy environment variables. Set
these in backend.env:
HTTP_PROXY=http://proxy.internal.example.com:3128
HTTPS_PROXY=http://proxy.internal.example.com:3128
NO_PROXY=localhost,127.0.0.1,db,depot-apt,depot-rpm,YOUR_INTERNAL_LDAP_HOST
This covers: the CVE/EPSS/KEV enrichment calls, the "Import from internet" feature (upstream mirrors, Maven Central, PyPI, npmjs.org, Docker Hub search), and Grype's own database updates — all of them use HTTP clients that honor these variables automatically, no extra configuration needed.
ClamAV's freshclam is the one exception
freshclam does not read HTTP_PROXY/HTTPS_PROXY — it only understands
its own config directives. If you need ClamAV updates to go through an
explicit (non-transparent) proxy, mount a freshclam.conf override:
services:
backend:
volumes:
- ./freshclam.conf:/etc/clamav/freshclam.conf:ro
If your proxy is deployed in transparent/intercepting mode at the
network level (see below), this override isn't needed — freshclam
doesn't know it's being proxied either way.
Worked example: Squid with a domain allowlist¶
Rather than a general-purpose "allow everything" proxy, most regulated
environments want an explicit allowlist — only the domains Repod actually
needs, nothing else. Squid's dstdomain ACL is the standard tool for this.
1. Allowlist file¶
# Security feeds
api.first.org
www.cisa.gov
# ClamAV / Grype update infrastructure — consult their own docs for the
# current full list, these CDN domains do change over time
database.clamav.net
.cvdupdate.clamav.net
grype.anchore.io
toolbox-data.anchore.io
# OS package mirrors — only the ones matching the distributions you serve
archive.ubuntu.com
security.ubuntu.com
deb.debian.org
security.debian.org
dl-cdn.alpinelinux.org
repo.almalinux.org
dl.rockylinux.org
mirror.stream.centos.org
download.opensuse.org
# Build-tool ecosystems — only if you use "Import from internet" for these
repo1.maven.org
search.maven.org
pypi.org
registry.npmjs.org
hub.docker.com
registry-1.docker.io
production.cloudflare.docker.com
2. squid.conf¶
http_port 3128
acl allowed_domains dstdomain "/etc/squid/allowed_domains.txt"
acl repod_net src 172.20.0.0/16 # adjust to your Docker network / server subnet
http_access allow repod_net allowed_domains
http_access deny all
# Standard hardening
via off
forwarded_for delete
request_header_access X-Forwarded-For deny all
3. Run it (standalone, or as a compose overlay)¶
services:
squid:
image: ubuntu/squid:latest
container_name: repod-squid
ports:
- "127.0.0.1:3128:3128" # bind to loopback; only the Repod host should reach it
volumes:
- ./squid/squid.conf:/etc/squid/squid.conf:ro
- ./squid/allowed_domains.txt:/etc/squid/allowed_domains.txt:ro
restart: unless-stopped
Then point backend.env at it:
(If squid runs on the same Docker network as backend, use the service name
as the hostname; otherwise use the host's proxy port.)
4. Verify¶
# From inside the backend container:
docker exec backend-api curl -sI https://api.first.org
# Should succeed (allowlisted)
docker exec backend-api curl -sI https://example.com
# Should be denied by Squid (not on the allowlist)
Watch docker logs repod-squid (or Squid's access.log) while triggering a
CVE scan or an "Import from internet" — any legitimately needed domain that
gets denied will show up there as TCP_DENIED, letting you extend the
allowlist deliberately rather than guessing upfront.
Fully air-gapped (no proxy at all)¶
If the server truly has no outbound path — not even through a proxy — see Upstream cache for seeding package mirrors via removable media through a relay host, and rely on the local EPSS/KEV/Grype/ClamAV caches for CVE and antivirus data (refreshed manually during a maintenance window with connectivity, if one ever exists — otherwise the pipeline keeps using whatever was cached at deployment time).