Documentation
¶
Overview ¶
Package config provides configuration loading and validation for the proxy server.
Configuration can be provided via:
- Command line flags (highest priority)
- Environment variables (PROXY_ prefix)
- Configuration file (YAML or JSON)
Storage Configuration:
The proxy supports multiple storage backends via gocloud.dev/blob:
Local filesystem (default):
storage: url: "file:///var/cache/proxy"
Amazon S3:
storage: url: "s3://bucket-name"
S3-compatible (MinIO, etc.):
storage: url: "s3://bucket?endpoint=http://localhost:9000"
Google Cloud Storage:
storage: url: "gs://bucket-name"
For S3, configure credentials via AWS environment variables:
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION
For GCS, authentication uses Application Default Credentials. This supports GKE Workload Identity, attached service accounts on GCE and Cloud Run, and local credentials created by `gcloud auth application-default login`. When direct_serve is enabled without a private key, the GCS backend uses the IAM Credentials signBlob API. The service account must hold roles/iam.serviceAccountTokenCreator on itself.
Database Configuration:
The proxy supports two database backends:
SQLite (default):
database: driver: "sqlite" path: "/var/lib/proxy/cache.db"
PostgreSQL:
database: driver: "postgres" url: "postgres://user:password@localhost:5432/proxy?sslmode=disable"
See config.example.yaml in the repository root for a complete example.
Index ¶
- Constants
- func CompileGenericArtifactPattern(pattern string) (*regexp.Regexp, error)
- func GenericPathAllowed(patterns []string, p string) bool
- func HasDotSegment(p string) bool
- func ParseSize(s string) (int64, error)
- type AccessLogConfig
- type AuthConfig
- type Config
- func (c *Config) EnvWarnings() []string
- func (c *Config) LoadFromEnv()
- func (c *Config) ParseArtifactMaxSize() int64
- func (c *Config) ParseArtifactTimeout() time.Duration
- func (c *Config) ParseDirectServeTTL() time.Duration
- func (c *Config) ParseGradleBuildCacheMaxAge() time.Duration
- func (c *Config) ParseGradleBuildCacheMaxSize() int64
- func (c *Config) ParseGradleBuildCacheMaxUploadSize() int64
- func (c *Config) ParseGradleBuildCacheSweepInterval() time.Duration
- func (c *Config) ParseHTTPTimeout() time.Duration
- func (c *Config) ParseHitFlushInterval() time.Duration
- func (c *Config) ParseMaxSize() int64
- func (c *Config) ParseMetadataMaxSize() int64
- func (c *Config) ParseMetadataRewriteCacheSize() int64
- func (c *Config) ParseMetadataTTL() time.Duration
- func (c *Config) ParseRetentionSweepInterval() time.Duration
- func (c *Config) ParseWriteTimeout() time.Duration
- func (c *Config) RetentionRules(reg *retention.Registry) (retention.Rules, error)
- func (c *Config) Validate() error
- type CooldownConfig
- type DatabaseConfig
- type DenylistConfig
- type GitConfig
- type GitUpstream
- type GradleBuildCacheConfig
- type GradleConfig
- type HealthConfig
- type HostedConfig
- type LogConfig
- type MirrorConfig
- type MirrorSchedule
- type RetentionConfig
- type ScannerConfig
- type ScanningConfig
- type StorageConfig
- type UpstreamConfig
Constants ¶
const DefaultSwiftUpstream = "https://tuist.dev/api/registry/swift"
DefaultSwiftUpstream is the Swift Package Registry used when none is configured.
const HostedGenericRepository = "hosted"
HostedGenericRepository is the /generic/{name}/ path that serves files pushed through /api/hosted/generic. While hosted packages are enabled, no upstream.generic entry may use it.
Variables ¶
This section is empty.
Functions ¶
func CompileGenericArtifactPattern ¶ added in v0.10.0
CompileGenericArtifactPattern compiles an upstream.generic_artifacts pattern so that it only matches a whole path, and checks it has the `version` and `file` groups.
func GenericPathAllowed ¶ added in v0.11.0
GenericPathAllowed reports whether p, a request path after /generic/{name}/, matches one of an upstream's upstream.generic_paths patterns. No patterns allow every path. With patterns, a path holding a character the upstream could read as the end of the path or as a different path ('%', '?', '#' or a backslash) is refused, so the path that matched is the one the upstream sees.
func HasDotSegment ¶ added in v0.11.0
HasDotSegment reports whether the URL path p, or p decoded once more, has a '.' or '..' segment. Backslashes count as separators, and ";params" are ignored, since some upstream servers (Tomcat, Jetty) treat them that way.
Types ¶
type AccessLogConfig ¶ added in v0.8.0
type AccessLogConfig struct {
// Path is the file to append activity records to. Empty disables the access log.
Path string `json:"path" yaml:"path"`
}
AccessLogConfig configures the JSONL activity log.
type AuthConfig ¶
type AuthConfig struct {
// Type is the authentication type: "bearer", "basic", "header", or "ecr".
Type string `json:"type" yaml:"type"`
// Token is used for bearer authentication.
// Can reference environment variables with ${VAR_NAME} syntax.
Token string `json:"token" yaml:"token"`
// Username is used for basic authentication.
Username string `json:"username" yaml:"username"`
// Password is used for basic authentication.
// Can reference environment variables with ${VAR_NAME} syntax.
Password string `json:"password" yaml:"password"`
// HeaderName is the custom header name (for type "header").
HeaderName string `json:"header_name" yaml:"header_name"`
// HeaderValue is the custom header value (for type "header").
// Can reference environment variables with ${VAR_NAME} syntax.
HeaderValue string `json:"header_value" yaml:"header_value"`
// Region is the AWS region for ECR authentication (for type "ecr").
// If empty, the region is inferred from private ECR registry URLs before
// falling back to the AWS SDK default region chain.
Region string `json:"region" yaml:"region"`
}
AuthConfig configures authentication for an upstream registry.
func (*AuthConfig) Header ¶
func (a *AuthConfig) Header() (name, value string)
Header returns the HTTP header name and value for this auth config. Returns empty strings if the config is invalid or incomplete.
type Config ¶
type Config struct {
// Listen is the address to listen on (e.g., ":8080", "127.0.0.1:8080").
Listen string `json:"listen" yaml:"listen"`
// BaseURL is the public URL where package endpoints are reachable.
// Used for rewriting package metadata URLs and shown to humans on the
// install guide so they know what to point their package manager at.
// Example: "https://proxy.example.com" or "http://localhost:8080"
BaseURL string `json:"base_url" yaml:"base_url"`
// UIBaseURL is the public URL where the web UI is reachable. Defaults to
// BaseURL 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.
// Example: "https://proxy.example.com/ui"
UIBaseURL string `json:"ui_base_url" yaml:"ui_base_url"`
// TrustForwardedFor attributes requests to the leftmost X-Forwarded-For
// entry instead of the TCP peer address, in the structured log, the access
// log and the request-source table on /ui/analytics.
//
// Enable this only when the proxy sits behind a load balancer or ingress
// that sets the header, because any client can send it: behind one it is
// the only way to see past the hop, in front of one it lets a caller choose
// what address it is attributed to.
TrustForwardedFor bool `json:"trust_forwarded_for" yaml:"trust_forwarded_for"`
// UIRequestSources shows the request-source table on /ui/analytics, which
// reports caller addresses, the tool each ran and how much each pulled.
//
// Off by default. The proxy has no authentication of its own, so until this
// is enabled /ui exposes what is cached rather than who called.
UIRequestSources bool `json:"ui_request_sources" yaml:"ui_request_sources"`
// UIFailureDetails lists the latest failures behind each failure counter on
// /ui/analytics: the package, its upstream URL or storage path, and the
// error. URLs are shown without credentials or query strings.
//
// Off by default, for the same reason as UIRequestSources: package names and
// upstream hosts say what the proxy's users depend on.
UIFailureDetails bool `json:"ui_failure_details" yaml:"ui_failure_details"`
// Storage configures artifact storage.
Storage StorageConfig `json:"storage" yaml:"storage"`
// Database configures the cache database.
Database DatabaseConfig `json:"database" yaml:"database"`
// Log configures logging.
Log LogConfig `json:"log" yaml:"log"`
// AccessLog configures the JSONL activity log.
AccessLog AccessLogConfig `json:"access_log" yaml:"access_log"`
// Upstream configures upstream registry URLs (optional overrides).
Upstream UpstreamConfig `json:"upstream" yaml:"upstream"`
// Cooldown configures version age filtering to mitigate supply chain attacks.
Cooldown CooldownConfig `json:"cooldown" yaml:"cooldown"`
// Denylist blocks explicitly configured package versions.
Denylist DenylistConfig `json:"denylist" yaml:"denylist"`
// Scanning configures pre-cache artifact scanning (trivy, ClamAV, Wiz,
// or a custom service) to mitigate supply chain attacks.
Scanning ScanningConfig `json:"scanning" yaml:"scanning"`
// CacheMetadata enables caching of upstream metadata responses for offline fallback.
// When enabled, metadata is stored in the database and storage backend.
// The mirror command always enables this regardless of this setting.
CacheMetadata bool `json:"cache_metadata" yaml:"cache_metadata"`
// MetadataTTL is how long cached metadata is considered fresh before
// revalidating with upstream. Uses Go duration syntax (e.g. "5m", "1h").
// Default: "5m". Set to "0" to always revalidate.
MetadataTTL string `json:"metadata_ttl" yaml:"metadata_ttl"`
// MetadataMaxSize is the maximum size of an upstream metadata response
// the proxy will buffer (e.g. "100MB", "250MB"). Responses over this
// size return ErrMetadataTooLarge. Default: "100MB".
MetadataMaxSize string `json:"metadata_max_size" yaml:"metadata_max_size"`
// ArtifactMaxSize is the largest upstream artifact the proxy will fetch
// (e.g. "2GB"). Larger artifacts are refused and not cached. Default: ""
// (unlimited). "0" is also unlimited.
ArtifactMaxSize string `json:"artifact_max_size" yaml:"artifact_max_size"`
// MetadataRewriteCacheSize is how much rewritten npm and Composer
// metadata to keep in memory, so a document is rewritten once rather than
// on every request (e.g. "256MB", "1GB"). Default: "256MB". Set to "0" to
// rewrite on every request.
MetadataRewriteCacheSize string `json:"metadata_rewrite_cache_size" yaml:"metadata_rewrite_cache_size"`
// HTTPTimeout is the timeout for individual upstream HTTP requests made
// by protocol handlers (metadata fetches, pass-through file requests).
// Uses Go duration syntax (e.g. "30s", "2m"). Default: "30s".
// Set to "0" to disable the timeout entirely. Independently of this
// setting, the shared transport gives up on an upstream that has not sent
// response headers within 60 seconds.
HTTPTimeout string `json:"http_timeout" yaml:"http_timeout"`
// WriteTimeout bounds response writes, including time spent downloading and
// scanning before the response starts. Default: "5m"; "0" disables it.
WriteTimeout string `json:"write_timeout" yaml:"write_timeout"`
// ArtifactTimeout bounds each upstream artifact download while serving
// requests, excluding scanning. Default: "5m"; "0" disables it.
// The mirror command keeps its unlimited artifact download timeout.
ArtifactTimeout string `json:"artifact_timeout" yaml:"artifact_timeout"`
// MirrorAPI enables the /api/mirror endpoints for starting mirror jobs via HTTP.
// Disabled by default to prevent unauthenticated users from triggering downloads.
MirrorAPI bool `json:"mirror_api" yaml:"mirror_api"`
// Mirror configures scheduled mirroring.
Mirror MirrorConfig `json:"mirror" yaml:"mirror"`
// CacheDelete enables DELETE /api/cache for removing cached artifacts, and
// the delete buttons on the UI's version page. It has no authentication of
// its own, so restrict /api/cache and /ui at the ingress when enabling it.
CacheDelete bool `json:"cache_delete" yaml:"cache_delete"`
// Hosted configures pushing packages to the proxy (/api/hosted).
Hosted HostedConfig `json:"hosted" yaml:"hosted"`
// Gradle configures Gradle HttpBuildCache behavior.
Gradle GradleConfig `json:"gradle" yaml:"gradle"`
// Health configures the /health endpoint behavior.
Health HealthConfig `json:"health" yaml:"health"`
// Git configures the Git repository cache served at /git/{name}/.
Git GitConfig `json:"git" yaml:"git"`
// contains filtered or unexported fields
}
Config holds all configuration for the proxy server.
func (*Config) EnvWarnings ¶ added in v0.10.0
EnvWarnings returns the environment values LoadFromEnv ignored.
func (*Config) LoadFromEnv ¶
func (c *Config) LoadFromEnv()
LoadFromEnv applies environment variable overrides to a Config. Environment variables use the PROXY_ prefix:
- PROXY_LISTEN
- PROXY_BASE_URL
- PROXY_UI_URL
- PROXY_STORAGE_PATH
- PROXY_STORAGE_MAX_SIZE
- PROXY_DATABASE_PATH
- PROXY_LOG_LEVEL
- PROXY_LOG_FORMAT
- PROXY_ACCESS_LOG_PATH
- PROXY_TRUST_FORWARDED_FOR
- PROXY_UI_REQUEST_SOURCES
- PROXY_UPSTREAM_SWIFT
- PROXY_HEALTH_STORAGE_PROBE_INTERVAL
func (*Config) ParseArtifactMaxSize ¶ added in v0.10.0
ParseArtifactMaxSize returns the artifact size limit in bytes, or 0 for no limit.
func (*Config) ParseArtifactTimeout ¶ added in v0.10.0
ParseArtifactTimeout returns the upstream artifact download timeout for serving requests, defaulting to 5m. An explicit zero disables the timeout.
func (*Config) ParseDirectServeTTL ¶
ParseDirectServeTTL returns the presigned URL expiry duration. Returns 15 minutes if unset.
func (*Config) ParseGradleBuildCacheMaxAge ¶ added in v0.4.0
ParseGradleBuildCacheMaxAge returns age-based eviction threshold. Returns 0 when disabled or invalid.
func (*Config) ParseGradleBuildCacheMaxSize ¶ added in v0.4.0
ParseGradleBuildCacheMaxSize returns total-size cap in bytes. Returns 0 when disabled or invalid.
func (*Config) ParseGradleBuildCacheMaxUploadSize ¶ added in v0.4.0
ParseGradleBuildCacheMaxUploadSize returns the max accepted PUT body size. Defaults to 100MB if unset or invalid.
func (*Config) ParseGradleBuildCacheSweepInterval ¶ added in v0.4.0
ParseGradleBuildCacheSweepInterval returns eviction sweep cadence. Defaults to 10m if unset or invalid.
func (*Config) ParseHTTPTimeout ¶ added in v0.6.0
ParseHTTPTimeout returns the upstream HTTP client timeout. Returns 30s if unset, 0 (no timeout) if explicitly set to "0".
func (*Config) ParseHitFlushInterval ¶ added in v0.9.1
ParseHitFlushInterval returns how often batched cache hits are written. Returns 1 second if unset or invalid, 0 if explicitly disabled.
func (*Config) ParseMaxSize ¶
ParseMaxSize returns the maximum cache size in bytes. Returns 0 if unset or explicitly disabled (meaning unlimited).
func (*Config) ParseMetadataMaxSize ¶ added in v0.5.0
ParseMetadataMaxSize returns the maximum metadata response size in bytes. Returns 100MB if unset or invalid.
func (*Config) ParseMetadataRewriteCacheSize ¶ added in v0.9.1
ParseMetadataRewriteCacheSize returns how many bytes of rewritten metadata to keep in memory. Returns 256MB if unset or invalid, 0 if disabled.
func (*Config) ParseMetadataTTL ¶
ParseMetadataTTL returns the metadata TTL duration. Returns 5 minutes if unset, 0 if explicitly disabled.
func (*Config) ParseRetentionSweepInterval ¶ added in v0.10.0
ParseRetentionSweepInterval returns how often the retention sweep runs.
func (*Config) ParseWriteTimeout ¶ added in v0.10.0
ParseWriteTimeout returns the response write timeout, defaulting to 5m. An explicit zero disables the timeout.
func (*Config) RetentionRules ¶ added in v0.10.0
RetentionRules validates storage.retention against the ecosystems registered with reg and resolves it. An ecosystem or package that reg does not support is an error, so a rule is never silently ignored.
type CooldownConfig ¶
type CooldownConfig struct {
// Default is the global default cooldown (e.g., "3d", "48h", "0" to disable).
Default string `json:"default" yaml:"default"`
// Ecosystems overrides the default for specific ecosystems.
Ecosystems map[string]string `json:"ecosystems" yaml:"ecosystems"`
// Packages overrides the cooldown for specific packages (keyed by PURL).
// Valid PURL keys are normalized to canonical form before use.
Packages map[string]string `json:"packages" yaml:"packages"`
// PackagePatterns overrides the cooldown for packages whose PURLs match a glob.
// Exact package overrides take precedence over matching patterns.
PackagePatterns map[string]string `json:"package_patterns" yaml:"package_patterns"`
}
CooldownConfig configures version cooldown periods. Versions published more recently than the cooldown are hidden from metadata responses.
func (*CooldownConfig) NormalizedPackages ¶ added in v0.6.0
func (c *CooldownConfig) NormalizedPackages() map[string]string
NormalizedPackages returns a copy of the package overrides with valid PURL keys in canonical form. An explicitly canonical key wins over an equivalent noncanonical key, and invalid keys are preserved unchanged.
func (*CooldownConfig) Shortest ¶ added in v0.11.0
func (c *CooldownConfig) Shortest() time.Duration
Shortest returns the shortest cooldown configured anywhere, by default, ecosystem, package or package pattern, or 0 when none is. Unparsable durations are left out; Validate reports them.
type DatabaseConfig ¶
type DatabaseConfig struct {
// Driver is the database driver: "sqlite" or "postgres".
Driver string `json:"driver" yaml:"driver"`
// Path is the path to the SQLite database file.
Path string `json:"path" yaml:"path"`
// URL is the PostgreSQL connection string.
URL string `json:"url" yaml:"url"`
// HitFlushInterval is how often cache hit counts and last-access times
// are written, batched in one transaction. Uses Go duration syntax
// (e.g. "1s", "10s"). Default: "1s". Set to "0" to write each hit as it
// happens.
HitFlushInterval string `json:"hit_flush_interval" yaml:"hit_flush_interval"`
}
DatabaseConfig configures the cache database.
func (DatabaseConfig) String ¶ added in v0.5.1
func (d DatabaseConfig) String() string
String returns a human-readable description of the configured database suitable for logging. For postgres the password in the connection URL is redacted; if the URL cannot be parsed only the driver name is returned to avoid leaking credentials.
type DenylistConfig ¶ added in v0.9.0
type DenylistConfig struct {
Packages []string `json:"packages" yaml:"packages"`
}
DenylistConfig identifies exact package versions that must not be served.
type GitConfig ¶ added in v0.11.0
type GitConfig struct {
// CacheDir holds the cached bare repositories. It must be local disk
// used by this process only, which locks it. Default: ./cache/git.
CacheDir string `json:"cache_dir" yaml:"cache_dir"`
// MaxSize bounds the cache, counting fetches in progress; the least
// recently used repositories not in use are evicted to stay within it.
// Empty or "0" disables the limit.
MaxSize string `json:"max_size" yaml:"max_size"`
// MaxRepoSize is the most one repository may take; a clone or fetch that
// would pass it fails. "0" disables the limit. Default: 5GB. MaxSize
// caps it when set.
MaxRepoSize string `json:"max_repo_size" yaml:"max_repo_size"`
// RefreshWait is how long a request waits for the upstream's branches
// and tags to be checked before it is served the cached copy. A fetch of
// new commits the check finds is waited for in full. Default: 5s.
RefreshWait string `json:"refresh_wait" yaml:"refresh_wait"`
// StaleMaxAge is how long after the last successful upstream check a
// cached copy may still be served when the upstream fails or is slow.
// Default: 24h.
StaleMaxAge string `json:"stale_max_age" yaml:"stale_max_age"`
// contains filtered or unexported fields
}
GitConfig configures the Git repository cache behind /git/{name}/.
func (*GitConfig) MaxRepoSizeBytes ¶ added in v0.11.0
MaxRepoSizeBytes returns the parsed MaxRepoSize, 0 for no limit. Validate must run first.
func (*GitConfig) MaxSizeBytes ¶ added in v0.11.0
MaxSizeBytes returns the parsed MaxSize, 0 for no limit. Validate must run first.
func (*GitConfig) RefreshWaitDuration ¶ added in v0.11.0
RefreshWaitDuration returns the parsed RefreshWait. Validate must run first.
func (*GitConfig) StaleMaxAgeDuration ¶ added in v0.11.0
StaleMaxAgeDuration returns the parsed StaleMaxAge. Validate must run first.
type GitUpstream ¶ added in v0.11.0
type GitUpstream struct {
URL string `json:"url" yaml:"url"`
// Repos lists path.Match patterns for repository paths under URL, such
// as "mediawiki/*". A pattern ending in "/**" also matches every
// repository nested below its prefix: "mediawiki/**" matches
// mediawiki/skins/Vector. Empty allows every repository. Required when
// upstream.auth has credentials for the URL, since everyone who can
// reach the proxy can read what it serves.
Repos []string `json:"repos" yaml:"repos"`
}
GitUpstream is an upstream.git entry: a Git server's base URL and, optionally, the repositories under it that may be served. In YAML or JSON it is either the URL alone or an object with url and repos.
func (GitUpstream) AllowsRepo ¶ added in v0.11.0
func (g GitUpstream) AllowsRepo(repo string) bool
AllowsRepo reports whether repo, a path under URL, may be served.
func (*GitUpstream) UnmarshalJSON ¶ added in v0.11.0
func (g *GitUpstream) UnmarshalJSON(data []byte) error
UnmarshalJSON accepts a bare URL as well as the object form.
func (*GitUpstream) UnmarshalYAML ¶ added in v0.11.0
func (g *GitUpstream) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML accepts a bare URL as well as the object form.
type GradleBuildCacheConfig ¶ added in v0.4.0
type GradleBuildCacheConfig struct {
// ReadOnly disables PUT uploads and keeps cache reads (GET/HEAD) enabled.
// Default: true; set false on the instance that CI uploads to.
ReadOnly bool `json:"read_only" yaml:"read_only"`
// MaxUploadSize caps a single PUT body size (e.g., "100MB"). Must be > 0.
// Default: "100MB".
MaxUploadSize string `json:"max_upload_size" yaml:"max_upload_size"`
// MaxAge evicts entries older than this duration (e.g., "24h", "7d").
// Empty or "0" disables age-based eviction.
MaxAge string `json:"max_age" yaml:"max_age"`
// MaxSize evicts oldest entries until total Gradle cache size is <= MaxSize.
// Empty or "0" disables size-based eviction.
MaxSize string `json:"max_size" yaml:"max_size"`
// SweepInterval controls periodic eviction frequency.
// Default: "10m".
SweepInterval string `json:"sweep_interval" yaml:"sweep_interval"`
}
GradleBuildCacheConfig configures Gradle HttpBuildCache safeguards.
func (*GradleBuildCacheConfig) Validate ¶ added in v0.4.0
func (g *GradleBuildCacheConfig) Validate() error
Validate checks Gradle build cache settings, applying the default upload size if unset.
type GradleConfig ¶ added in v0.4.0
type GradleConfig struct {
// BuildCache configures the /gradle HttpBuildCache endpoint.
BuildCache GradleBuildCacheConfig `json:"build_cache" yaml:"build_cache"`
}
GradleConfig configures Gradle-specific features.
type HealthConfig ¶ added in v0.4.0
type HealthConfig struct {
// StorageProbeInterval is the minimum time between storage backend probes.
// Uses Go duration syntax (e.g. "30s", "1m"). Default: "30s".
// Set to "0" to probe on every /health request (useful for low-traffic deployments).
StorageProbeInterval string `json:"storage_probe_interval" yaml:"storage_probe_interval"`
}
HealthConfig configures the /health endpoint.
func (*HealthConfig) Validate ¶ added in v0.4.0
func (h *HealthConfig) Validate() error
Validate checks the /health configuration. An unset interval is allowed (the cache uses its default); explicit values must parse and be non-negative.
type HostedConfig ¶ added in v0.10.0
type HostedConfig struct {
// Enabled registers the /api/hosted endpoints. Off by default.
Enabled bool `json:"enabled" yaml:"enabled"`
// Token is the bearer token required to push and delete packages.
// Required when Enabled. Supports ${VAR_NAME} expansion like AuthConfig
// fields.
Token string `json:"token" yaml:"token"`
// MaxUploadSize caps a single pushed archive (e.g., "100MB"). Must be > 0.
// Default: "100MB".
MaxUploadSize string `json:"max_upload_size" yaml:"max_upload_size"`
// NPMScopes are npm scopes (e.g. "@acme") served only from pushed
// packages. The upstream registry is never asked about them, so a package
// published there under the same name can't be mixed in.
NPMScopes []string `json:"npm_scopes" yaml:"npm_scopes"`
// ComposerVendors are Composer vendors (e.g. "acme") served only from
// pushed packages, like NPMScopes.
ComposerVendors []string `json:"composer_vendors" yaml:"composer_vendors"`
// contains filtered or unexported fields
}
HostedConfig configures packages pushed to the proxy through the /api/hosted endpoints. Pushed versions are served in place of upstream versions with the same number, so writes always require a token.
func (*HostedConfig) MaxUploadBytes ¶ added in v0.10.0
func (h *HostedConfig) MaxUploadBytes() int64
MaxUploadBytes returns the parsed MaxUploadSize. Validate must run first.
func (*HostedConfig) TokenExpanded ¶ added in v0.10.0
func (h *HostedConfig) TokenExpanded() string
TokenExpanded returns Token with ${VAR_NAME} references expanded.
func (*HostedConfig) Validate ¶ added in v0.10.0
func (h *HostedConfig) Validate() error
Validate checks the hosted package settings, applying the default upload size if unset.
type LogConfig ¶
type LogConfig struct {
// Level is the minimum log level: "debug", "info", "warn", "error".
Level string `json:"level" yaml:"level"`
// Format is the log format: "text" or "json".
Format string `json:"format" yaml:"format"`
}
LogConfig configures logging.
type MirrorConfig ¶ added in v0.10.0
type MirrorConfig struct {
// Schedules re-mirror container image tags at a fixed interval, so a
// moved tag is picked up even when nobody pulls it.
Schedules []MirrorSchedule `json:"schedules" yaml:"schedules"`
}
MirrorConfig configures mirroring that the server runs on its own.
func (*MirrorConfig) Validate ¶ added in v0.10.0
func (m *MirrorConfig) Validate() error
Validate checks every schedule.
type MirrorSchedule ¶ added in v0.10.0
type MirrorSchedule struct {
// Images are pkg:docker or pkg:oci PURLs with a tag.
Images []string `json:"images" yaml:"images"`
// Interval is how often the images are mirrored, at least one minute
// (e.g. "6h").
Interval string `json:"interval" yaml:"interval"`
// Platforms limit which platforms of an image index are mirrored, as
// os/architecture[/variant]. Empty mirrors every platform.
Platforms []string `json:"platforms" yaml:"platforms"`
// contains filtered or unexported fields
}
MirrorSchedule is a set of image PURLs mirrored every Interval.
func (*MirrorSchedule) IntervalDuration ¶ added in v0.10.0
func (s *MirrorSchedule) IntervalDuration() time.Duration
IntervalDuration returns the parsed Interval. Validate must run first.
type RetentionConfig ¶ added in v0.10.0
type RetentionConfig struct {
// Default applies to every ecosystem that supports retention and has no
// rule of its own, except generic, which requires an explicit rule.
Default string `json:"default" yaml:"default"`
// Ecosystems overrides the default per ecosystem key (e.g. "npm", "oci").
// Configuring an ecosystem whose retention is not supported yet is an
// error.
Ecosystems map[string]string `json:"ecosystems" yaml:"ecosystems"`
// Packages overrides the ecosystem rule for single packages, keyed by
// package PURL.
Packages map[string]string `json:"packages" yaml:"packages"`
// SweepInterval is how often expired artifacts are looked for, at least
// one minute. Default: "10m".
SweepInterval string `json:"sweep_interval" yaml:"sweep_interval"`
}
RetentionConfig configures age-based eviction of cached artifacts. An artifact's age is the time since it was last served, or since it was fetched when it has not been served since. Durations accept a "d" suffix for days; "0" or empty means never evict by age.
type ScannerConfig ¶ added in v0.8.0
type ScannerConfig struct {
// Name identifies this scanner in logs and metrics.
Name string `json:"name" yaml:"name"`
// URL is the endpoint the proxy POSTs scan notifications to.
URL string `json:"url" yaml:"url"`
// Mode is "block" (default) or "monitor". A "block" scanner's verdict
// can prevent caching; a "monitor" scanner's findings are logged but
// never gate caching.
Mode string `json:"mode" yaml:"mode"`
// Ecosystems restricts this scanner to specific ecosystems (e.g.
// "npm", "pypi"). Empty means all ecosystems.
Ecosystems []string `json:"ecosystems" yaml:"ecosystems"`
// Headers are additional HTTP headers sent with every scan request
// (e.g. for authenticating to the scanner service). Values support
// ${VAR_NAME} expansion like AuthConfig fields.
Headers map[string]string `json:"headers" yaml:"headers"`
}
ScannerConfig configures a single external scanning service.
func (*ScannerConfig) HeadersExpanded ¶ added in v0.8.0
func (s *ScannerConfig) HeadersExpanded() map[string]string
HeadersExpanded returns Headers with ${VAR_NAME} references expanded in each value.
func (*ScannerConfig) Validate ¶ added in v0.8.0
func (s *ScannerConfig) Validate() error
Validate checks a single scanner's configuration, applying the default mode ("block") if unset.
type ScanningConfig ¶ added in v0.8.0
type ScanningConfig struct {
// Enabled turns on the scan gate. When false (default), artifacts are
// cached exactly as if scanning didn't exist.
Enabled bool `json:"enabled" yaml:"enabled"`
// FailOpen treats scanner errors and timeouts as an allow verdict
// instead of a block. Default is fail-closed, since the default
// posture for a security gate should block on infrastructure failure.
FailOpen bool `json:"fail_open" yaml:"fail_open"`
// Timeout bounds each scan call. Uses Go duration syntax (e.g. "30s").
// Default: "30s".
Timeout string `json:"timeout" yaml:"timeout"`
// SigningKey authenticates pull requests to the internal scan-fetch
// route used by every storage backend. Required whenever Enabled is
// true. Supports ${VAR_NAME} expansion like AuthConfig fields.
SigningKey string `json:"signing_key" yaml:"signing_key"`
// FetchBaseURL is the address scanners use to reach this proxy to pull
// staged artifacts. Defaults to BaseURL. Set this separately when
// scanners reach the proxy over an internal address different from the
// public-facing BaseURL (mirrors DirectServeBaseURL/UIBaseURL).
FetchBaseURL string `json:"fetch_base_url" yaml:"fetch_base_url"`
// Scanners is the list of external scanning services to call.
Scanners []ScannerConfig `json:"scanners" yaml:"scanners"`
}
ScanningConfig configures pre-cache artifact scanning (e.g. trivy, ClamAV, Wiz, or a custom service) to mitigate supply chain attacks. Unlike Cooldown, which only looks at a version's publish timestamp, scanning inspects the actual artifact bytes before they become servable from cache.
func (*ScanningConfig) SigningKeyExpanded ¶ added in v0.8.0
func (s *ScanningConfig) SigningKeyExpanded() string
SigningKeyExpanded returns SigningKey with ${VAR_NAME} references expanded.
func (*ScanningConfig) Validate ¶ added in v0.8.0
func (s *ScanningConfig) Validate() error
Validate checks the scanning configuration for errors, applying the default timeout if unset.
type StorageConfig ¶
type StorageConfig struct {
// URL is the 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 (Workload Identity supported)
// - azblob://container-name - Azure Blob Storage
// If empty, defaults to file:// with the Path value.
URL string `json:"url" yaml:"url"`
// Path is the directory where cached artifacts are stored.
// If URL is empty, this is used as file://{Path}.
//
// Deprecated: Use URL with file:// scheme instead.
Path string `json:"path" yaml:"path"`
// MaxSize is the maximum cache size (e.g., "10GB", "500MB").
// When exceeded, least recently used artifacts are evicted.
// Empty or "0" means unlimited.
MaxSize string `json:"max_size" yaml:"max_size"`
// DirectServe enables redirecting cached artifact downloads to presigned
// storage URLs (HTTP 302) instead of streaming bytes through the proxy.
// Only effective for backends that support URL signing (S3, GCS, Azure).
DirectServe bool `json:"direct_serve" yaml:"direct_serve"`
// DirectServeTTL is how long presigned URLs remain valid.
// Uses Go duration syntax (e.g. "5m", "1h"). Default: "15m".
DirectServeTTL string `json:"direct_serve_ttl" yaml:"direct_serve_ttl"`
// DirectServeBaseURL overrides the scheme and host of presigned URLs
// before returning them to clients. Useful when the proxy reaches
// storage at an internal address (e.g. 127.0.0.1 or a Docker hostname)
// but clients must use a public one.
DirectServeBaseURL string `json:"direct_serve_base_url" yaml:"direct_serve_base_url"`
// CacheArtifacts stores fetched artifacts so later downloads are served
// from storage. When false, every download streams from upstream and
// nothing is stored; metadata is still cached, and cooldown and the
// denylist still apply. Useful when another caching layer sits in front
// of the proxy. False is incompatible with scanning, direct_serve and
// mirror_api, which all depend on stored artifacts. Default: true.
CacheArtifacts bool `json:"cache_artifacts" yaml:"cache_artifacts"`
// Retention evicts cached artifacts that have not been accessed for a
// configured time, per ecosystem and per package.
Retention RetentionConfig `json:"retention" yaml:"retention"`
}
StorageConfig configures artifact storage.
type UpstreamConfig ¶
type UpstreamConfig struct {
// AllowPrivateHosts permits listed upstream hosts to resolve to private addresses.
AllowPrivateHosts []string `json:"allow_private_hosts" yaml:"allow_private_hosts"`
// AllowLoopback permits upstream requests and redirects to loopback addresses.
AllowLoopback bool `json:"allow_loopback" yaml:"allow_loopback"`
// NPM is the upstream npm registry URL.
// Default: https://registry.npmjs.org
NPM string `json:"npm" yaml:"npm"`
// NPMFullMetadata always requests the full packument (application/json)
// from the npm upstream, so served metadata carries the "time" map even
// when cooldown is disabled. Clients that gate on publish age (for
// example Yarn's npmMinimalAgeGate) need this.
// Default: false (the abbreviated format is preferred).
NPMFullMetadata bool `json:"npm_full_metadata" yaml:"npm_full_metadata"`
// NPMRoutes maps package name patterns to npm registry URLs. A package
// whose name matches a pattern is fetched only from that registry, never
// from upstream.npm, so a public package cannot stand in for it. Patterns
// use path.Match syntax, e.g. "@example/*"; the longest matching pattern
// wins.
NPMRoutes map[string]string `json:"npm_routes" yaml:"npm_routes"`
// Cargo is the upstream cargo index URL.
// Default: https://index.crates.io
Cargo string `json:"cargo" yaml:"cargo"`
// CargoDownload is the upstream cargo download URL.
// Default: https://static.crates.io/crates
CargoDownload string `json:"cargo_download" yaml:"cargo_download"`
// Gem is the upstream RubyGems registry URL.
// Default: https://rubygems.org
Gem string `json:"gem" yaml:"gem"`
// Go is the upstream Go module proxy URL.
// Default: https://proxy.golang.org
Go string `json:"go" yaml:"go"`
// GoSumDBs maps Go checksum database names to their base URLs, served at
// /go/sumdb/{name}/ so the go command reaches the database through
// GOPROXY. Unknown names get 404, which makes the go command contact the
// database directly.
// Default when empty: {"sum.golang.org": "https://sum.golang.org"}.
GoSumDBs map[string]string `json:"go_sumdbs" yaml:"go_sumdbs"`
// GoSumDBsOffline keeps answering for a checksum database from its
// cached signed tree, however old, when the database cannot be reached.
// Set this when clients have no route to the database of their own;
// otherwise the proxy stops answering once the cached tree is older than
// metadata_ttl, and the go command contacts the database directly.
// Requires cache_metadata. Default: false.
GoSumDBsOffline bool `json:"go_sumdbs_offline" yaml:"go_sumdbs_offline"`
// GoVulnDB is the Go vulnerability database served at /go/vulndb, for
// govulncheck -db pointing at the proxy.
// Default: https://vuln.go.dev
GoVulnDB string `json:"go_vulndb" yaml:"go_vulndb"`
// Hex is the upstream Hex repository URL.
// Default: https://repo.hex.pm
Hex string `json:"hex" yaml:"hex"`
// HexAPI is the upstream Hex API URL used for package timestamps.
// Default: https://hex.pm
HexAPI string `json:"hex_api" yaml:"hex_api"`
// Pub is the upstream pub registry URL.
// Default: https://pub.dev
Pub string `json:"pub" yaml:"pub"`
// PyPI is the upstream PyPI index and API URL.
// Default: https://pypi.org
PyPI string `json:"pypi" yaml:"pypi"`
// PyPIDownload is the upstream PyPI package download URL.
// Default: https://files.pythonhosted.org
PyPIDownload string `json:"pypi_download" yaml:"pypi_download"`
// Maven is the upstream Maven repository URL.
// Default: https://repo1.maven.org/maven2
Maven string `json:"maven" yaml:"maven"`
// MavenRepositories maps repository names to additional Maven repository
// base URLs, served at /maven/{name}/. upstream.maven stays the default
// at /maven/. A name must not be the first segment of a group ID, such
// as "org" or "tools", since it would hide those groups in the default
// repository; see validateMavenRepositoryName.
// Example: {"grails": "https://repo.grails.org/grails/restricted"}.
MavenRepositories map[string]string `json:"maven_repositories" yaml:"maven_repositories"`
// GradlePluginPortal is the upstream Gradle Plugin Portal Maven URL.
// Used to resolve Gradle plugin marker artifacts.
// Default: https://plugins.gradle.org/m2
GradlePluginPortal string `json:"gradle_plugin_portal" yaml:"gradle_plugin_portal"`
// NuGet is the upstream NuGet API URL.
// Default: https://api.nuget.org
NuGet string `json:"nuget" yaml:"nuget"`
// NuGetSearch is the upstream NuGet search API URL.
// Default: https://azuresearch-usnc.nuget.org
NuGetSearch string `json:"nuget_search" yaml:"nuget_search"`
// Composer is the upstream Packagist API URL.
// Default: https://packagist.org
Composer string `json:"composer" yaml:"composer"`
// ComposerRepository is the upstream Packagist repository URL.
// Default: https://repo.packagist.org
ComposerRepository string `json:"composer_repository" yaml:"composer_repository"`
// ComposerRoutes maps package name patterns to Composer repository URLs
// (the base that serves /p2/{vendor}/{package}.json). A package whose
// name matches a pattern is fetched only from that repository, never
// from upstream.composer_repository, so a public package cannot stand in
// for it. Patterns use path.Match syntax, e.g. "example/*"; the longest
// matching pattern wins.
ComposerRoutes map[string]string `json:"composer_routes" yaml:"composer_routes"`
// Conan is the upstream Conan registry URL.
// Default: https://center.conan.io
Conan string `json:"conan" yaml:"conan"`
// Chef is the upstream Chef Supermarket URL, served at /chef/. Point it
// at a private Supermarket to proxy that instead of the public one.
// Default: https://supermarket.chef.io
Chef string `json:"chef" yaml:"chef"`
// Conda is the upstream Conda channel base URL.
// Default: https://conda.anaconda.org
Conda string `json:"conda" yaml:"conda"`
// CRAN is the upstream CRAN mirror URL.
// Default: https://cloud.r-project.org
CRAN string `json:"cran" yaml:"cran"`
// Julia is the upstream Julia package server URL.
// Default: https://pkg.julialang.org
Julia string `json:"julia" yaml:"julia"`
// OCIDefault is the default upstream OCI registry URL.
// Default: https://registry-1.docker.io
OCIDefault string `json:"oci_default" yaml:"oci_default"`
// Swift is the upstream Swift Package Registry URL.
// Default: https://tuist.dev/api/registry/swift
Swift string `json:"swift" yaml:"swift"`
// Debian is the upstream APT repository base URL, served at /debian/.
// Example: http://archive.ubuntu.com/ubuntu would get Ubuntu.
// Default: http://deb.debian.org/debian
Debian string `json:"debian" yaml:"debian"`
// DebianRepositories maps repository names to additional APT repository
// base URLs, served at /debian/{name}/.
// Example: {"security": "https://security.debian.org/debian-security"}.
DebianRepositories map[string]string `json:"debian_repositories" yaml:"debian_repositories"`
// RPM is the upstream RPM repository base URL.
// Default: https://dl.fedoraproject.org/pub/fedora/linux
RPM string `json:"rpm" yaml:"rpm"`
// HomebrewAPI is the upstream Homebrew JSON API URL.
// Default: https://formulae.brew.sh/api
HomebrewAPI string `json:"homebrew_api" yaml:"homebrew_api"`
// HomebrewArtifact is the upstream registry URL for Homebrew artifacts.
// Default: https://ghcr.io
HomebrewArtifact string `json:"homebrew_artifact" yaml:"homebrew_artifact"`
// Helm maps repository names to HTTP Helm chart repository URLs.
// Requests use /helm/{name}/index.yaml and chart URLs in the index are
// rewritten to the same named proxy endpoint.
Helm map[string]string `json:"helm" yaml:"helm"`
// APK maps repository names to Alpine APK repository base URLs, served
// at /apk/{name}/. The remaining request path mirrors the upstream
// layout, e.g. /apk/alpine/v3.22/main/x86_64/APKINDEX.tar.gz.
// Default when empty: {"alpine": "https://dl-cdn.alpinelinux.org/alpine"}.
APK map[string]string `json:"apk" yaml:"apk"`
// Arch maps repository names to Arch Linux pacman mirror base URLs,
// served at /arch/{name}/. The remaining request path mirrors the
// upstream layout, e.g. /arch/archlinux/core/os/x86_64/core.db.
// Default when empty: {"archlinux": "https://geo.mirror.pkgbuild.com"}.
Arch map[string]string `json:"arch" yaml:"arch"`
// FreeBSD maps repository names to FreeBSD pkg mirror base URLs, served
// at /freebsd/{name}/. The remaining request path mirrors the upstream
// layout, e.g. /freebsd/freebsd/FreeBSD:14:amd64/latest/packagesite.pkg.
// Default when empty: {"freebsd": "https://pkg.freebsd.org"}.
FreeBSD map[string]string `json:"freebsd" yaml:"freebsd"`
// OCI maps names to OCI registry URLs. Requests to a named registry use
// the repository prefix upstream/{name}/, for example
// oci://proxy.example.com/upstream/ghcr/owner/chart.
OCI map[string]string `json:"oci" yaml:"oci"`
// OCIMirrors lists, per upstream.oci name, the registry hosts that
// upstream mirrors, for example {"ghcr": ["ghcr.io"]} for an Artifactory
// remote of ghcr.io. containerd requests whose ns query parameter names
// one of these hosts are served by that upstream.
OCIMirrors map[string][]string `json:"oci_mirrors" yaml:"oci_mirrors"`
// Generic maps names to plain HTTP upstream base URLs, served at
// /generic/{name}/. The remaining request path and query string are
// appended to the upstream URL. GitHub release asset paths
// ({owner}/{repo}/releases/download/{tag}/{asset}) and paths matching
// GenericArtifacts are cached in the artifact cache; everything else
// goes through the metadata cache.
// Example: {"github": "https://github.com", "github-api": "https://api.github.com"}.
Generic map[string]string `json:"generic" yaml:"generic"`
// GenericArtifacts maps a Generic upstream name to regular expressions for
// its version-pinned download paths. A request path after
// /generic/{name}/ that one of them matches in full is cached in the
// artifact cache like a GitHub release asset. Each pattern needs `version`
// and `file` named groups; an optional `name` group names the package,
// which otherwise is the upstream name.
// Example: {"apache": ["dist/(?P<name>maven)/maven-3/(?P<version>[^/]+)/binaries/(?P<file>[^/]+)"]}.
GenericArtifacts map[string][]string `json:"generic_artifacts" yaml:"generic_artifacts"`
// GenericPaths maps a Generic upstream name to the paths it may serve,
// as patterns for the request path after /generic/{name}/ with the same
// syntax as GitUpstream.Repos: path.Match, where a pattern ending in
// "/**" also matches every path nested below its prefix. Other paths
// answer 404. Empty serves every path. Required when upstream.auth has
// credentials for the upstream, since everyone who can reach the proxy
// can use them for any path otherwise.
// Example: {"github-api": ["repos/*/*/releases/**"]}.
GenericPaths map[string][]string `json:"generic_paths" yaml:"generic_paths"`
// Git maps names to Git servers, served read-only at /git/{name}/{repo}
// from a local cache of bare repositories. See GitUpstream.
// Example: {"github": {"url": "https://github.com"}}.
Git map[string]GitUpstream `json:"git" yaml:"git"`
// Auth configures authentication for upstream registries.
// Keys are absolute URL scopes matched by scheme, host, effective port,
// and path-segment prefix.
// Example: "https://npm.pkg.github.com" matches all requests to that host.
Auth map[string]AuthConfig `json:"auth" yaml:"auth"`
}
UpstreamConfig configures upstream URLs for built-in routes and authentication. Leave empty to use defaults.
func (*UpstreamConfig) AuthForURL ¶
func (u *UpstreamConfig) AuthForURL(url string) *AuthConfig
AuthForURL returns the auth config that matches the given URL. The longest matching URL scope wins.
func (*UpstreamConfig) HasAuthWithin ¶ added in v0.11.0
func (u *UpstreamConfig) HasAuthWithin(baseURL string) bool
HasAuthWithin reports whether an upstream.auth scope covers baseURL or a path under it.
func (*UpstreamConfig) Validate ¶ added in v0.7.0
func (u *UpstreamConfig) Validate() error
Validate checks upstream authentication URL scopes.