Hides package versions published too recently from metadata responses, giving the community time to spot malicious releases. Configurable per-ecosystem and per-package with duration overrides. Supported for npm, PyPI, pub.dev, and Composer.
6.4 KiB
Configuration
The proxy can be configured via command line flags, environment variables, or a configuration file. Command line flags take precedence over environment variables, which take precedence over the configuration file.
Configuration File
Create a YAML or JSON file and pass it with -config:
proxy serve -config config.yaml
See config.example.yaml in the repository root for a complete example.
Server Settings
| Config | Environment | Flag | Default | Description |
|---|---|---|---|---|
listen |
PROXY_LISTEN |
-listen |
:8080 |
Address to listen on |
base_url |
PROXY_BASE_URL |
-base-url |
http://localhost:8080 |
Public URL for the proxy |
Storage
The proxy stores cached artifacts using gocloud.dev/blob, supporting local filesystem and S3-compatible storage.
Local Filesystem
storage:
url: "file:///var/cache/proxy"
Or using the legacy path option:
storage:
path: "./cache/artifacts"
| Config | Environment | Flag | Description |
|---|---|---|---|
storage.url |
PROXY_STORAGE_URL |
-storage-url |
Storage URL (file:// or s3://) |
storage.path |
PROXY_STORAGE_PATH |
-storage-path |
Local path (deprecated, use url) |
storage.max_size |
PROXY_STORAGE_MAX_SIZE |
- | Max cache size (e.g., "10GB") |
Amazon S3
storage:
url: "s3://my-bucket"
Configure credentials via environment variables:
export AWS_ACCESS_KEY_ID=your-key
export AWS_SECRET_ACCESS_KEY=your-secret
export AWS_REGION=us-east-1
S3-Compatible (MinIO, etc.)
storage:
url: "s3://my-bucket?endpoint=http://localhost:9000&disableSSL=true&s3ForcePathStyle=true"
Database
The proxy supports SQLite (default) and PostgreSQL for storing package metadata.
SQLite
database:
driver: "sqlite"
path: "./cache/proxy.db"
| Config | Environment | Flag | Description |
|---|---|---|---|
database.driver |
PROXY_DATABASE_DRIVER |
-database-driver |
sqlite or postgres |
database.path |
PROXY_DATABASE_PATH |
-database-path |
SQLite file path |
PostgreSQL
database:
driver: "postgres"
url: "postgres://user:password@localhost:5432/proxy?sslmode=disable"
| Config | Environment | Flag | Description |
|---|---|---|---|
database.url |
PROXY_DATABASE_URL |
-database-url |
PostgreSQL connection URL |
Logging
log:
level: "info"
format: "text"
| Config | Environment | Flag | Values |
|---|---|---|---|
log.level |
PROXY_LOG_LEVEL |
-log-level |
debug, info, warn, error |
log.format |
PROXY_LOG_FORMAT |
-log-format |
text, json |
Upstream Registries
Override default upstream registry URLs:
upstream:
npm: "https://registry.npmjs.org"
cargo: "https://index.crates.io"
cargo_download: "https://static.crates.io/crates"
Authentication
Configure authentication for private upstream registries. Auth is matched by URL prefix, and credentials can reference environment variables using ${VAR_NAME} syntax.
Bearer Token
Used by npm, GitHub Package Registry, and many other registries:
upstream:
auth:
"https://registry.npmjs.org":
type: bearer
token: "${NPM_TOKEN}"
"https://npm.pkg.github.com":
type: bearer
token: "${GITHUB_TOKEN}"
Basic Authentication
Used by PyPI, Artifactory, and others:
upstream:
auth:
"https://pypi.org":
type: basic
username: "__token__"
password: "${PYPI_TOKEN}"
"https://artifactory.mycompany.com":
type: basic
username: "deploy"
password: "${ARTIFACTORY_PASSWORD}"
Custom Header
For registries that use non-standard authentication headers:
upstream:
auth:
"https://maven.mycompany.com":
type: header
header_name: "X-Auth-Token"
header_value: "${MAVEN_TOKEN}"
URL Matching
Auth configs are matched by URL prefix. The longest matching prefix wins, so you can configure different credentials for different paths:
upstream:
auth:
# All requests to this registry
"https://registry.mycompany.com":
type: bearer
token: "${REGISTRY_TOKEN}"
# Override for a specific scope
"https://registry.mycompany.com/@private":
type: bearer
token: "${PRIVATE_TOKEN}"
Cooldown
The cooldown feature hides package versions published too recently, giving the community time to spot malicious releases before they reach your projects. When a version is within its cooldown period, it's stripped from metadata responses so package managers won't install it.
cooldown:
default: "3d"
ecosystems:
npm: "7d"
cargo: "0"
packages:
"pkg:npm/lodash": "0"
"pkg:npm/@babel/core": "14d"
| Config | Environment | Description |
|---|---|---|
cooldown.default |
PROXY_COOLDOWN_DEFAULT |
Global default cooldown |
cooldown.ecosystems |
- | Per-ecosystem overrides |
cooldown.packages |
- | Per-package overrides (keyed by PURL) |
Durations support days (7d), hours (48h), and minutes (30m). Set to 0 to disable.
Resolution order: package override, then ecosystem override, then global default. This lets you set a conservative default while exempting trusted packages.
Currently supported for npm, PyPI, pub.dev, and Composer. These ecosystems include publish timestamps in their metadata. Other ecosystems (Go, Cargo, RubyGems) would require extra API calls and are not yet supported.
Docker
SQLite with Local Storage
docker compose up
PostgreSQL with Local Storage
docker compose --profile postgres up
PostgreSQL with S3 (MinIO)
docker compose --profile s3 up
Example Configurations
Minimal (defaults)
listen: ":8080"
Production with PostgreSQL and S3
listen: ":8080"
base_url: "https://proxy.example.com"
storage:
url: "s3://my-cache-bucket"
max_size: "100GB"
database:
driver: "postgres"
url: "postgres://proxy:secret@db.example.com:5432/proxy?sslmode=require"
log:
level: "info"
format: "json"
Private npm Registry
listen: ":8080"
base_url: "http://localhost:8080"
upstream:
npm: "https://npm.pkg.github.com"
auth:
npm:
type: bearer
token: "${GITHUB_TOKEN}"