mirror of
https://github.com/git-pkgs/proxy.git
synced 2026-09-15 23:32:04 -04:00
* Add Homebrew JSON API and bottle proxy support * Fix Homebrew HEAD offline fallback and non-sha256 OCI manifest handling Route Homebrew API HEAD requests through ProxyCached so a warm cache answers without an upstream call and stale entries are served when the upstream is unreachable. HEAD still reaches upstream as HEAD when metadata caching is disabled. Limit OCI manifest digest verification to sha256 references and Docker-Content-Digest headers so other digest algorithms are proxied instead of rejected, and log the failing expected value. * Reconcile with #280 and #301 after rebase Compute real manifest digests in #280's fixture upstreams so the new verification accepts them, and add headerETag / headerLastModified to * Send fixed Accept for Homebrew API and match If-None-Match properly The Homebrew API cache key does not include Accept, so replaying the client header could serve one representation under another; the API does not negotiate anyway. Compare If-None-Match with weak comparison, list splitting and "*" per RFC 7232 instead of string equality, and apply the same helper to the metadata and swift responders. * Reconcile with #298 and #304 after rebase Move the configureScanning doc comment back to its function after the auto-merge stacked it on mountProtocolHandlers, and drop the second ETag/Last-Modified set in writeMetadataCachedResponse now that the pre-304 set covers both response paths.
325 lines
11 KiB
YAML
325 lines
11 KiB
YAML
# Proxy server configuration
|
|
# Copy to config.yaml and modify as needed
|
|
|
|
# Server listen address
|
|
listen: ":8080"
|
|
|
|
# Public URL where package endpoints are reachable.
|
|
# Used for rewriting package metadata URLs and shown in install guide snippets
|
|
# so users know what to point their package manager at.
|
|
base_url: "http://localhost:8080"
|
|
|
|
# Timeout for individual upstream HTTP requests made by protocol handlers
|
|
# (metadata fetches, pass-through file requests). Uses Go duration syntax.
|
|
# Set to "0" to disable the timeout. Default: "30s".
|
|
# http_timeout: "30s"
|
|
|
|
# Public URL where the web UI is reached. Defaults to base_url when unset.
|
|
# Set this separately when the UI is served on a different hostname than the
|
|
# package endpoints — for example, the UI on a public domain behind auth while
|
|
# build machines hit a Docker network alias for the package endpoints.
|
|
# ui_base_url: "https://proxy.example.com/ui"
|
|
|
|
# Artifact storage configuration
|
|
storage:
|
|
# Storage backend URL
|
|
# Supported schemes:
|
|
# - file:///path/to/dir - Local filesystem (default)
|
|
# - s3://bucket-name - Amazon S3
|
|
# - s3://bucket?endpoint=http://localhost:9000 - S3-compatible (MinIO)
|
|
# - gs://bucket-name - Google Cloud Storage
|
|
# - azblob://container-name - Azure Blob Storage
|
|
#
|
|
# For S3, configure credentials via environment variables:
|
|
# AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
|
|
#
|
|
# For GCS, authentication uses Application Default Credentials. On GKE with
|
|
# Workload Identity, bind the Kubernetes service account to a Google service
|
|
# account that has roles/storage.objectAdmin on the bucket. No extra config
|
|
# is needed in this file. For local development, run:
|
|
# gcloud auth application-default login
|
|
# If direct_serve is enabled, the service account also needs
|
|
# roles/iam.serviceAccountTokenCreator on itself so the IAM Credentials
|
|
# signBlob API can sign URLs without a private key.
|
|
url: ""
|
|
|
|
# Local filesystem path (used when url is empty)
|
|
# Deprecated: Use url with file:// scheme instead
|
|
path: "./cache/artifacts"
|
|
|
|
# Maximum cache size (e.g., "10GB", "500MB")
|
|
# When exceeded, least recently used artifacts are evicted
|
|
# Empty or "0" means unlimited
|
|
max_size: ""
|
|
|
|
# Redirect cached artifact downloads to presigned storage URLs (HTTP 302)
|
|
# instead of streaming through the proxy. Only effective for S3, GCS, and Azure.
|
|
# Leave disabled if clients reach the proxy through an authenticating gateway,
|
|
# since presigned URLs bypass it.
|
|
direct_serve: false
|
|
|
|
# How long presigned URLs remain valid (e.g. "5m", "1h"). Default: "15m".
|
|
direct_serve_ttl: "15m"
|
|
|
|
# Public base URL to substitute into presigned URLs. Set this when the
|
|
# proxy reaches storage at an internal address (127.0.0.1, a Docker
|
|
# service name) but clients must use a public hostname. Only scheme and
|
|
# host are used; the signed path and query are preserved. For S3/MinIO
|
|
# the reverse proxy at this address must forward requests with the
|
|
# internal Host header or the SigV4 signature will not validate.
|
|
# direct_serve_base_url: "https://minio.example.com"
|
|
|
|
# Database configuration
|
|
database:
|
|
# Database driver: "sqlite" (default) or "postgres"
|
|
driver: "sqlite"
|
|
|
|
# SQLite database file path (used when driver is "sqlite")
|
|
path: "./cache/proxy.db"
|
|
|
|
# PostgreSQL connection URL (used when driver is "postgres")
|
|
# Example: "postgres://user:password@localhost:5432/proxy?sslmode=disable"
|
|
url: ""
|
|
|
|
# Logging configuration
|
|
log:
|
|
# Minimum log level: "debug", "info", "warn", "error"
|
|
level: "info"
|
|
|
|
# Log format: "text" or "json"
|
|
format: "text"
|
|
|
|
# JSONL access log. Leave path empty to disable it.
|
|
access_log:
|
|
path: ""
|
|
|
|
# Upstream URLs for built-in routes and authentication
|
|
upstream:
|
|
# Hosts allowed to resolve to private, ULA, or CGNAT addresses
|
|
allow_private_hosts: []
|
|
|
|
# Permit upstream requests and redirects to loopback addresses
|
|
allow_loopback: false
|
|
|
|
# npm registry URL
|
|
npm: "https://registry.npmjs.org"
|
|
# Always request full npm packuments so served metadata carries publish
|
|
# times ("time" map) even when cooldown is disabled. Needed by clients that
|
|
# gate on publish age, e.g. Yarn's npmMinimalAgeGate. Default: false.
|
|
# npm_full_metadata: true
|
|
|
|
# Cargo sparse index URL
|
|
cargo: "https://index.crates.io"
|
|
|
|
# Cargo crate download URL
|
|
cargo_download: "https://static.crates.io/crates"
|
|
|
|
# RubyGems registry URL
|
|
gem: "https://rubygems.org"
|
|
|
|
# Go module proxy URL
|
|
go: "https://proxy.golang.org"
|
|
|
|
# Hex repository URL
|
|
hex: "https://repo.hex.pm"
|
|
|
|
# Hex API URL used for package timestamps
|
|
hex_api: "https://hex.pm"
|
|
|
|
# pub registry URL
|
|
pub: "https://pub.dev"
|
|
|
|
# PyPI index and API URL
|
|
pypi: "https://pypi.org"
|
|
|
|
# PyPI package download URL
|
|
pypi_download: "https://files.pythonhosted.org"
|
|
|
|
# Maven repository URL (used by /maven endpoint)
|
|
maven: "https://repo1.maven.org/maven2"
|
|
|
|
# Gradle Plugin Portal Maven URL (fallback for plugin marker artifacts)
|
|
gradle_plugin_portal: "https://plugins.gradle.org/m2"
|
|
|
|
# NuGet API URL
|
|
nuget: "https://api.nuget.org"
|
|
|
|
# NuGet search API URL
|
|
nuget_search: "https://azuresearch-usnc.nuget.org"
|
|
|
|
# Packagist API URL
|
|
composer: "https://packagist.org"
|
|
|
|
# Packagist repository URL
|
|
composer_repository: "https://repo.packagist.org"
|
|
|
|
# Conan registry URL
|
|
conan: "https://center.conan.io"
|
|
|
|
# Conda channel base URL
|
|
conda: "https://conda.anaconda.org"
|
|
|
|
# CRAN mirror URL
|
|
cran: "https://cloud.r-project.org"
|
|
|
|
# Julia package server URL
|
|
julia: "https://pkg.julialang.org"
|
|
|
|
# Swift Package Registry URL (used by /swift endpoint)
|
|
swift: "https://tuist.dev/api/registry/swift"
|
|
|
|
# Default OCI registry URL for unprefixed /v2 requests
|
|
oci_default: "https://registry-1.docker.io"
|
|
|
|
# Debian/APT repository URL (used by /debian endpoint)
|
|
debian: "http://deb.debian.org/debian"
|
|
|
|
# RPM repository URL (used by /rpm endpoint)
|
|
rpm: "https://dl.fedoraproject.org/pub/fedora/linux"
|
|
|
|
# Homebrew JSON API URL (used by /homebrew endpoint)
|
|
homebrew_api: "https://formulae.brew.sh/api"
|
|
|
|
# Homebrew artifact registry URL (used for /v2/homebrew/core requests)
|
|
homebrew_artifact: "https://ghcr.io"
|
|
|
|
# Named HTTP Helm chart repositories (used by /helm/{name}/)
|
|
# helm:
|
|
# bitnami: "https://charts.bitnami.com/bitnami"
|
|
|
|
# Named OCI registries. Use the upstream/{name}/ repository prefix, e.g.
|
|
# oci://proxy.example.com/upstream/ghcr/owner/chart.
|
|
# oci:
|
|
# ghcr: "https://ghcr.io"
|
|
|
|
# Named Alpine APK repositories (used by /apk/{name}/).
|
|
# Defaults to {"alpine": "https://dl-cdn.alpinelinux.org/alpine"} when empty;
|
|
# configuring any entry replaces that default.
|
|
# apk:
|
|
# alpine: "https://dl-cdn.alpinelinux.org/alpine"
|
|
# private: "https://apk.example.com"
|
|
|
|
# Named generic HTTP upstreams (used by /generic/{name}/). The remaining
|
|
# request path and query are appended to the upstream URL. GitHub release
|
|
# assets ({owner}/{repo}/releases/download/{tag}/{asset}) are cached
|
|
# immutably; other paths use the metadata cache with stale-on-error.
|
|
# generic:
|
|
# github: "https://github.com"
|
|
# github-api: "https://api.github.com"
|
|
|
|
# Authentication for upstream registries
|
|
# Keys are absolute URL scopes. Scheme, host, effective port, and path
|
|
# segment boundaries must match; the longest matching scope wins.
|
|
# Values can reference environment variables using ${VAR_NAME} syntax.
|
|
#
|
|
# Supported auth types:
|
|
# - bearer: Authorization header with Bearer token
|
|
# - basic: Authorization header with Basic auth (username:password)
|
|
# - header: Custom header name and value
|
|
# - ecr: AWS ECR auto-refreshing token via the AWS SDK credential chain
|
|
auth:
|
|
# Example: npm with bearer token
|
|
# "https://registry.npmjs.org":
|
|
# type: bearer
|
|
# token: "${NPM_TOKEN}"
|
|
|
|
# Example: GitHub npm registry
|
|
# "https://npm.pkg.github.com":
|
|
# type: bearer
|
|
# token: "${GITHUB_TOKEN}"
|
|
|
|
# Example: PyPI with basic auth
|
|
# "https://pypi.org":
|
|
# type: basic
|
|
# username: "__token__"
|
|
# password: "${PYPI_TOKEN}"
|
|
|
|
# Example: Custom header for private registry
|
|
# "https://maven.mycompany.com":
|
|
# type: header
|
|
# header_name: "X-Auth-Token"
|
|
# header_value: "${MAVEN_TOKEN}"
|
|
|
|
# Example: private AWS ECR registry (12h tokens auto-refreshed via
|
|
# ecr:GetAuthorizationToken; credentials come from the AWS SDK default
|
|
# chain, so IRSA / instance profiles / AWS_* env vars all work; the region
|
|
# is inferred from the private ECR hostname)
|
|
# "https://123456789012.dkr.ecr.eu-west-1.amazonaws.com":
|
|
# type: ecr
|
|
|
|
# Gradle HttpBuildCache configuration
|
|
gradle:
|
|
build_cache:
|
|
# Set to true to disable PUT uploads (read-only cache mode)
|
|
read_only: false
|
|
|
|
# Maximum accepted Gradle cache upload body size
|
|
# Required and must be > 0
|
|
max_upload_size: "100MB"
|
|
|
|
# Evict entries older than this age (set to "0" to disable age-based eviction)
|
|
max_age: "168h"
|
|
|
|
# Cap total Gradle cache size; oldest entries are deleted first
|
|
# ("0" disables size-based eviction)
|
|
# max_size: "20GB"
|
|
|
|
# How often eviction runs when max_age or max_size is set
|
|
sweep_interval: "10m"
|
|
|
|
# Health endpoint configuration.
|
|
health:
|
|
# Minimum time between storage backend probes.
|
|
# The /health endpoint runs a write/read/verify/delete round-trip
|
|
# against the configured storage backend and caches the result for
|
|
# this interval. Set to "0" to probe on every request.
|
|
# Default: "30s".
|
|
storage_probe_interval: "30s"
|
|
|
|
# Version cooldown configuration
|
|
# Hides package versions published too recently, giving the community time
|
|
# to spot malicious releases before they're pulled into projects.
|
|
# Supported durations: "7d" (days), "48h" (hours), "30m" (minutes), "0" (disabled)
|
|
cooldown:
|
|
# Global default cooldown for all ecosystems
|
|
# default: "3d"
|
|
|
|
# Per-ecosystem overrides
|
|
# ecosystems:
|
|
# npm: "7d"
|
|
# cargo: "0"
|
|
|
|
# Per-package overrides (keyed by PURL). Keys are normalized, so npm scopes
|
|
# may use either @scope or the canonical %40scope form.
|
|
# packages:
|
|
# "pkg:npm/lodash": "0"
|
|
# "pkg:npm/@babel/core": "14d"
|
|
|
|
# Pre-cache artifact scanning. When enabled, every artifact is staged into
|
|
# storage and scanned by the configured scanners before it is committed to
|
|
# the cache and served to clients. Scanners never receive artifact bytes
|
|
# directly — each notify call includes a short-lived signed URL that the
|
|
# scanner fetches itself, so the proxy stays agnostic to trivy/ClamAV/Wiz/
|
|
# any custom service. Scanners run concurrently; the first "block" verdict
|
|
# wins and cancels the rest.
|
|
# scanning:
|
|
# enabled: true
|
|
# fail_open: false
|
|
# timeout: 30s
|
|
#
|
|
# # Authenticates pull requests to the internal scan-fetch route.
|
|
# # Required whenever enabled is true. Supports ${VAR_NAME} expansion.
|
|
# signing_key: ${PROXY_SCANNING_SIGNING_KEY}
|
|
#
|
|
# # Address scanners use to reach this proxy to pull staged artifacts.
|
|
# # Defaults to base_url.
|
|
# # fetch_base_url: http://proxy.internal:8080
|
|
#
|
|
# scanners:
|
|
# - name: clamav
|
|
# url: http://clamav-adapter:8080/scan
|
|
# mode: block
|
|
# - name: trivy
|
|
# url: http://trivy-adapter:8081/scan
|
|
# mode: monitor
|
|
# ecosystems: [npm, pypi]
|