Stand Up Socket Firewall For The First Time
Stand up the Socket Registry Firewall in about 15 minutes and start blocking malicious packages at install time.
Socket Firewall (Registry Mode) is a container that sits between your package managers and the registries they pull from. Every package download is checked against Socket before it reaches the machine. A blocked package returns HTTP 403, so the install fails with a reason and a request ID.
This page gets one firewall running. The child pages cover what to do with it:
| Goal | Page |
|---|---|
| Block known-bad packages | Flat block |
| Hold brand-new releases for a few days | Cooldown |
| Decide what gets blocked | Policy config |
| Keep verdicts across restarts and instances | Redis cache |
| Hide blocked versions so installs pick a safe one | Metadata filtering (needs Redis) |
| Point developers and CI at the firewall | Deployments |
| Send decisions to a SIEM | Data |
PlaceholdersExamples use
sfw.example.comas the firewall hostname. Replace it everywhere with your own.
Prerequisites
- Docker with Docker Compose
- A Socket API key with the
packages:listandentitlements:listscopes (Dashboard → Settings → API Tokens) - Outbound HTTPS from the firewall host to
api.socket.devand to the public registries
1. Create the project
mkdir -p ~/socket-fw/ssl && cd ~/socket-fw
cat > .env <<'ENV'
SOCKET_SECURITY_API_TOKEN=your_api_key_here
SOCKET_FAIL_OPEN=true
# Log clean allows too, not just blocks and warnings (see Data)
SOCKET_IGNORE_LOG_LEVEL=warn
ENV
Use the right variable nameThe firewall container reads
SOCKET_SECURITY_API_TOKEN. This is not the same variable the Socket CLI or CI integrations use.
2. Generate a certificate
The container expects fullchain.pem and privkey.pem in ssl/. For a POC a self-signed certificate is fine.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/privkey.pem \
-out ssl/fullchain.pem \
-subj "/CN=sfw.example.com" \
-addext "subjectAltName=DNS:sfw.example.com"
chmod 644 ssl/fullchain.pem ssl/privkey.pem3. Write socket.yml
socket.ymlOne route per ecosystem you need. This example covers npm and PyPI.
socket:
api_url: https://api.socket.dev
fail_open: true # allow if the Socket API is unreachable; set false for strict posture
ports:
http: 8080
https: 8443
cache:
ttl: 600 # verdict cache, seconds
path_routing:
enabled: true
domain: sfw.example.com
rewrite_scheme: https
routes:
- path: /npm
upstream: https://registry.npmjs.org
registry: npm
- path: /pypi
upstream: https://pypi.org
registry: pypi4. Write docker-compose.yml
docker-compose.ymlPublishing the HTTPS port on 443 means clients never need a port in their URLs.
services:
socket-firewall:
image: socketdev/socket-registry-firewall:latest
container_name: socket-registry-firewall
ports:
- "443:8443"
env_file: .env
environment:
- CONFIG_FILE=/app/socket.yml
volumes:
- ./socket.yml:/app/socket.yml:ro
- ./ssl:/etc/nginx/ssl:rw
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-fk", "https://localhost:8443/health"]
interval: 30s
timeout: 10s
retries: 3
Why 443The firewall rewrites package download URLs to
path_routing.domainand drops any non-standard port. If clients reach it on:8443, metadata loads but downloads go to port 443 and fail (404 or connection refused, depending on what listens there). Publishing on 443 avoids this. If you must use another port, setpath_routing.use_incoming_domain: trueso rewritten URLs keep the host and port the client used.
5. Start it
# Local testing only. In production, create a DNS record for sfw.example.com.
sudo sh -c 'printf "127.0.0.1 sfw.example.com\n" >> /etc/hosts'
docker compose up -d
# TLS isn't ready for the first few seconds, so retry
for i in $(seq 1 30); do curl -sk https://sfw.example.com/health && break; sleep 2; done
docker compose ps # (healthy) can take about 45 sVerify
docker compose logs socket-firewall | grep "Resolved org slug from API"docker compose psshowsUp (healthy).- The health check returns
SocketFirewall/<version> - Health OK(some builds return JSON with"status":"healthy"). - The log line above is present. This is the check that proves the firewall can reach Socket and get verdicts.
Healthy is not the same as working
/healthreports OK even when the firewall can't reach the Socket API or has no routes loaded. Always confirm with the log line above and a real block test (Flat block).
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| 404 on every request | The request's Host header is not path_routing.domain | Reach the firewall by sfw.example.com, not by IP or localhost |
| Metadata works, downloads fail | Clients connect on a non-443 port and the rewritten URL drops it | Publish on 443, or set path_routing.use_incoming_domain: true |
| Healthy, but nothing is checked | Socket API unreachable. With fail_open: true the firewall starts anyway and allows everything | Check logs for Firewall access validation failed at startup, and allow outbound HTTPS to api.socket.dev |
| Nothing ever blocks | Wrong or missing API token | docker compose exec socket-firewall env | grep SOCKET_SECURITY_API_TOKEN |
Next
Flat block proves it blocks.
Reference
Updated 1 day ago