var (
ErrNoBuckets = errors.New("at least one bucket is required")
ErrBucketNameRequired = errors.New("bucket name is required")
ErrBucketNameHasSlash = errors.New("bucket name must not contain '/'")
ErrDuplicateBucketName = errors.New("duplicate bucket name")
ErrNoCredential = errors.New("at least one credential is required")
ErrInvalidCredential = errors.New("must have access_key_id+secret_access_key or token")
ErrDuplicateCredential = errors.New("duplicate access_key_id")
ErrNegativeMaxUploads = errors.New("max_multipart_uploads must be >= 0")
)
Backend validation errors.
var (
ErrNoBackends = errors.New("at least one backend is required")
ErrDuplicateBackend = errors.New("duplicate backend name")
ErrEndpointRequired = errors.New("endpoint is required")
ErrBackendBucketReqd = errors.New("bucket is required")
ErrAccessKeyIDReqd = errors.New("access_key_id is required")
ErrSecretAccessKeyReqd = errors.New("secret_access_key is required")
ErrNegativeQuota = errors.New("quota_bytes must not be negative")
ErrNegativeMaxObject = errors.New("max_object_size must not be negative")
ErrNegativeAPILimit = errors.New("api_request_limit must not be negative")
ErrNegativeEgress = errors.New("egress_byte_limit must not be negative")
ErrNegativeIngress = errors.New("ingress_byte_limit must not be negative")
// ErrInvalidCredentialSource: unknown credential_source value (allowed: "static", "default_chain").ErrInvalidCredentialSource = errors.New(`credential_source must be "static" or "default_chain"`)
// ErrCredentialsWithDefaultChain: static keys present alongside credential_source=default_chain.ErrCredentialsWithDefaultChain = errors.New("access_key_id/secret_access_key must be empty when credential_source is default_chain")
)
Server and TLS errors.
var (
ErrInvalidTLSConfig = errors.New("both cert_file and key_file are required for TLS")
ErrInvalidTLSVersion = errors.New("invalid TLS min_version")
ErrInvalidLogLevel = errors.New("invalid log_level")
)
UI / auth errors.
var (
ErrAdminAuthIncomplete = errors.New("admin_key and admin_secret must both be set (or both empty)")
ErrSessionSecretReqd = errors.New("session_secret is required when UI is enabled")
)
Rate limit errors.
var (
ErrInvalidCIDR = errors.New("invalid CIDR in trusted_proxies")
ErrRateLimitRPSNotPositive = errors.New("rate_limit.requests_per_sec must be positive")
ErrRateLimitBurstNotPositive = errors.New("rate_limit.burst must be positive")
)
Encryption errors.
var (
ErrInvalidChunkSize = errors.New("encryption.chunk_size must be between 4096 (4KB) and 1048576 (1MB)")
ErrChunkSizeNotPowerOf2 = errors.New("encryption.chunk_size must be a power of 2")
ErrKeySourceRequired = errors.New("encryption: exactly one of master_key, master_key_file, or vault is required")
ErrMultipleKeySources = errors.New("encryption: only one of master_key, master_key_file, or vault may be set")
ErrInvalidBase64Key = errors.New("invalid base64 key material")
ErrInvalidKeyLength = errors.New("key must be 256 bits (32 bytes)")
ErrInvalidKeyFile = errors.New("invalid master_key_file")
ErrPreviousKeyInvalid = errors.New("previous_keys entry invalid")
ErrVaultAddressRequired = errors.New("encryption.vault.address is required")
ErrVaultTokenRequired = errors.New("encryption.vault: one of token or token_file is required")
ErrVaultTokenAmbiguous = errors.New("encryption.vault: only one of token or token_file may be set")
ErrVaultKeyNameRequired = errors.New("encryption.vault.key_name is required")
)
Redis / counter errors.
var (
ErrRedisAddressRequired = errors.New("redis.address is required when redis section is present")
ErrRedisFailureThresholdNotPos = errors.New("redis.failure_threshold must be positive")
ErrRedisOpenTimeoutNotPos = errors.New("redis.open_timeout must be positive")
)
Notifications errors.
var (
ErrNotificationURLRequired = errors.New("notifications endpoint url is required")
ErrNotificationEventsRequired = errors.New("notifications endpoint requires at least one event pattern")
)
Lifecycle errors.
var (
ErrLifecyclePrefixRequired = errors.New("lifecycle.rules: prefix must not be empty (would match all objects)")
ErrInvalidExpiration = errors.New("lifecycle.rules: expiration_days must be positive")
ErrDuplicatePrefix = errors.New("duplicate prefix")
)
Rebalance / replication errors.
var (
ErrInvalidRebalanceStrategy = errors.New("rebalance.strategy must be 'pack' or 'spread'")
ErrRebalanceIntervalNotPos = errors.New("rebalance.interval must be positive")
ErrRebalanceBatchNotPos = errors.New("rebalance.batch_size must be positive")
ErrRebalanceThresholdRange = errors.New("rebalance.threshold must be between 0 and 1")
ErrRebalanceConcurrencyNotPos = errors.New("rebalance.concurrency must be positive")
ErrReplicationFactorMin = errors.New("replication.factor must be at least 1")
ErrReplicationFactorTooLarge = errors.New("replication.factor exceeds number of backends")
ErrReplicationIntervalNotPos = errors.New("replication.worker_interval must be positive")
ErrReplicationBatchNotPos = errors.New("replication.batch_size must be positive")
ErrInvalidRoutingStrategy = errors.New("routing_strategy must be 'pack' or 'spread'")
ErrQuotaMixNotAllowed = errors.New("cannot mix unlimited (quota_bytes: 0) and quota-limited backends")
ErrUnlimitedNeedsReplication = errors.New("multiple backends with unlimited quota require replication.factor >= 2")
)
Usage flush / adaptive errors.
var (
ErrUsageFlushFastInterval = errors.New("usage_flush.fast_interval must be less than interval")
ErrUsageFlushThresholdRange = errors.New("usage_flush.adaptive_threshold must be between 0 and 1")
)
Cache / storage misc.
var (
ErrCacheMaxSizeNotPositive = errors.New("cache.max_size must be positive")
ErrCacheMaxObjectNotPositive = errors.New("cache.max_object_size must be positive")
ErrCacheMaxObjectExceedsMaxSize = errors.New("cache.max_object_size cannot exceed cache.max_size")
)
Telemetry errors.
var (
ErrTracingEndpointRequired = errors.New("telemetry.tracing.endpoint is required when tracing is enabled")
)
NonReloadableFieldsChanged compares two configs and returns a list of non-reloadable field descriptions that differ. Used by the SIGHUP handler to warn about changes that require a restart.
func ParseLogLevel
funcParseLogLevel(sstring) slog.Level
ParseLogLevel maps a log level string to a slog.Level. Returns slog.LevelInfo for unrecognized values. Callers should validate via SetDefaultsAndValidate before calling this function.
type BackendCircuitBreakerConfig
BackendCircuitBreakerConfig holds settings for per-backend circuit breakers. When a backend is unreachable or returns errors (e.g. expired credentials), the circuit opens and the backend is excluded from request routing until recovery is detected via a probe request.
BackendConfig holds configuration for an S3-compatible storage backend.
typeBackendConfigstruct {
Namestring`yaml:"name"`// Identifier for metrics/tracingEndpointstring`yaml:"endpoint"`// S3-compatible endpoint URLRegionstring`yaml:"region"`// AWS region or equivalentBucketstring`yaml:"bucket"`// Target bucket nameAccessKeyIDstring`yaml:"access_key_id"`// AWS access key ID (required when credential_source is "static")SecretAccessKeystring`yaml:"secret_access_key"`// AWS secret access key (required when credential_source is "static")// CredentialSource selects how credentials are resolved: "static" (default, uses keys above) or "default_chain" (AWS SDK chain: env, IMDS, SSO, STS).CredentialSourcestring`yaml:"credential_source"`ForcePathStylebool`yaml:"force_path_style"`// Use path-style URLsUnsignedPayload*bool`yaml:"unsigned_payload"`// Skip SigV4 payload hash to stream uploads without buffering (default: true)DisableChecksumbool`yaml:"disable_checksum"`// Disable SDK default checksums for GCS and other providers that reject them (default: false)StripSDKHeadersbool`yaml:"strip_sdk_headers"`// Remove SDK v2 headers (amz-sdk-*, accept-encoding, x-id) before signing for GCS compatibility (default: false)QuotaBytesint64`yaml:"quota_bytes"`// Maximum bytes allowed on this backend (0 = unlimited)MaxObjectSizeint64`yaml:"max_object_size"`// Maximum size of a single object in bytes (0 = unlimited)APIRequestLimitint64`yaml:"api_request_limit"`// Monthly API request limit (0 = unlimited)EgressByteLimitint64`yaml:"egress_byte_limit"`// Monthly egress byte limit (0 = unlimited)IngressByteLimitint64`yaml:"ingress_byte_limit"`// Monthly ingress byte limit (0 = unlimited)}
type BucketConfig
BucketConfig defines a virtual bucket with one or more credential sets. Multiple services can share a bucket by each having their own credentials.
typeBucketConfigstruct {
Namestring`yaml:"name"`Credentials []CredentialConfig`yaml:"credentials"`MaxMultipartUploadsint`yaml:"max_multipart_uploads"`// Max active multipart uploads per bucket (0 = unlimited)}
type CacheConfig
CacheConfig holds settings for the object data cache.
typeCacheConfigstruct {
Enabledbool`yaml:"enabled"`// Enable the object data cache (default: false)MaxSizestring`yaml:"max_size"`// Maximum total cache size (e.g., "256MB", "1GB")MaxObjectSizestring`yaml:"max_object_size"`// Maximum cacheable object size (e.g., "10MB"); 0 = no limitTTLtime.Duration`yaml:"ttl"`// Time before a cached entry expires (default: 5m)// Parsed values (not from YAML)MaxSizeBytesint64`yaml:"-"`MaxObjectSizeBytesint64`yaml:"-"`}
type CircuitBreakerConfig
CircuitBreakerConfig holds settings for the database circuit breaker. When the database becomes unreachable, the proxy enters degraded mode: reads broadcast to all backends, writes return 503.
typeCircuitBreakerConfigstruct {
FailureThresholdint`yaml:"failure_threshold"`// Consecutive failures before opening (default: 3)OpenTimeouttime.Duration`yaml:"open_timeout"`// Delay before probing recovery (default: 15s)CacheTTLtime.Duration`yaml:"cache_ttl"`// TTL for key->backend cache during degraded reads (default: 60s)ParallelBroadcastbool`yaml:"parallel_broadcast"`// Fan-out reads to all backends in parallel during degraded mode (default: false)// DegradedBroadcastParallelism caps the number of backends probed// concurrently during a parallel degraded-mode broadcast. 0 means no// cap (every configured backend is probed at once, the historical// behaviour). With a positive value, probes run as a rolling window:// the first N are launched immediately, and each failure replenishes// the next pending backend so at most N goroutines are in flight at// any time. Only meaningful when ParallelBroadcast is true.DegradedBroadcastParallelismint`yaml:"degraded_broadcast_parallelism"`// DegradedReadsEnabled opts out of degraded-mode broadcasts (default true; set false to fail fast on DB outage).DegradedReadsEnabled*bool`yaml:"degraded_reads_enabled"`}
type CleanupQueueConfig
CleanupQueueConfig holds settings for the background orphan cleanup worker and multipart upload housekeeping.
ClaimGracePeriod controls how long a per-row claim stamp held by an instance remains exclusive before another instance is allowed to reclaim the row. A short value lets a crashed worker’s rows recover quickly at the cost of a higher chance of duplicate processing if a real worker is merely slow; a long value is the inverse trade-off. The 5-minute default covers the realistic worst case for a single backend DELETE plus its retry budget within one tick. Hot-reloadable.
typeCleanupQueueConfigstruct {
Concurrencyint`yaml:"concurrency"`// Parallel cleanup deletions (default: 10)MultipartStaleTimeouttime.Duration`yaml:"multipart_stale_timeout"`// Abandon multipart uploads older than this (default: 24h)ClaimGracePeriodtime.Duration`yaml:"claim_grace_period"`// Reclaim stale per-row claims older than this (default: 5m)}
type Config
Config holds the complete service configuration.
typeConfigstruct {
ServerServerConfig`yaml:"server"`Buckets []BucketConfig`yaml:"buckets"`DatabaseDatabaseConfig`yaml:"database"`Backends []BackendConfig`yaml:"backends"`TelemetryTelemetryConfig`yaml:"telemetry"`RebalanceRebalanceConfig`yaml:"rebalance"`ReplicationReplicationConfig`yaml:"replication"`RateLimitRateLimitConfig`yaml:"rate_limit"`CircuitBreakerCircuitBreakerConfig`yaml:"circuit_breaker"`BackendCircuitBreakerBackendCircuitBreakerConfig`yaml:"backend_circuit_breaker"`EncryptionEncryptionConfig`yaml:"encryption"`UIUIConfig`yaml:"ui"`CleanupQueueCleanupQueueConfig`yaml:"cleanup_queue"`WritePathWritePathConfig`yaml:"write_path"`UsageFlushUsageFlushConfig`yaml:"usage_flush"`LifecycleLifecycleConfig`yaml:"lifecycle"`ReconcileReconcileConfig`yaml:"reconcile"`IntegrityIntegrityConfig`yaml:"integrity"`CacheCacheConfig`yaml:"cache"`Redis*RedisConfig`yaml:"redis"`NotificationsNotificationConfig`yaml:"notifications"`RoutingStrategyRoutingStrategy`yaml:"routing_strategy"`// "pack" (default) or "spread"}
func LoadConfig
funcLoadConfig(pathstring) (*Config, error)
LoadConfig reads and parses the configuration file with environment variable expansion. Returns an error if the file cannot be read, parsed, or validated.
func (*Config) SetDefaultsAndValidate
func (c*Config) SetDefaultsAndValidate() error
SetDefaultsAndValidate applies default values for optional fields and checks that all required configuration values are present. Delegates to per-type validators and performs cross-field validation.
type CredentialConfig
CredentialConfig holds a single set of client credentials for accessing a virtual bucket. Supports SigV4 (access_key_id + secret_access_key) or legacy token auth.
DatabaseConfig holds metadata store connection settings. The Driver field selects between “sqlite” (embedded, zero-dependency default) and “postgres” (required for multi-instance deployments).
typeDatabaseConfigstruct {
Driverstring`yaml:"driver"`// "sqlite" or "postgres" (default: inferred from config)Pathstring`yaml:"path"`// SQLite file path (default: "s3-orchestrator.db")Hoststring`yaml:"host"`Portint`yaml:"port"`Databasestring`yaml:"database"`Userstring`yaml:"user"`Passwordstring`yaml:"password"`//nolint:gosec // G117: config struct field, not a hardcoded credentialSSLModestring`yaml:"ssl_mode"`MaxConnsint32`yaml:"max_conns"`// Max pool connections (default: 50; size to 2-3x max concurrent requests)MinConnsint32`yaml:"min_conns"`// Min idle connections (default: 5)MaxConnLifetimetime.Duration`yaml:"max_conn_lifetime"`// Max connection age (default: 5m)}
func (*DatabaseConfig) ConnectionString
func (c*DatabaseConfig) ConnectionString() string
ConnectionString returns a PostgreSQL connection URI with properly escaped credentials, safe for passwords containing special characters.
type EncryptionConfig
EncryptionConfig holds settings for server-side envelope encryption. When enabled, objects are encrypted with per-object DEKs using chunked AES-256-GCM before being stored on backends. Exactly one key source (master_key, master_key_file, or vault) must be configured.
typeEncryptionConfigstruct {
Enabledbool`yaml:"enabled"`ChunkSizeint`yaml:"chunk_size"`// Plaintext bytes per chunk (default: 65536, range: 4KB-1MB, must be power of 2)MasterKeystring`yaml:"master_key"`// Base64-encoded 256-bit key (inline or via env var)MasterKeyFilestring`yaml:"master_key_file"`// Path to file containing raw 32-byte keyVault*VaultTransitConfig`yaml:"vault"`// Vault Transit key managementPreviousKeys []string`yaml:"previous_keys"`// Base64-encoded previous master keys for rotation (unwrap only)}
type IntegrityConfig
IntegrityConfig holds settings for object integrity verification. When enabled, objects are checksummed on write and optionally verified on read and during replication.
typeIntegrityConfigstruct {
Enabledbool`yaml:"enabled"`// Enable integrity verification (default: false)VerifyOnReadbool`yaml:"verify_on_read"`// Hash-check every GET response (default: false)VerifyOnReplicate*bool`yaml:"verify_on_replicate"`// Hash-check before recording a replica (default: true when enabled)ScrubberIntervaltime.Duration`yaml:"scrubber_interval"`// Background verification interval (0 = disabled)ScrubberBatchSizeint`yaml:"scrubber_batch_size"`// Objects per scrub cycle (default: 100)}
ShouldVerifyOnReplicate returns whether replication copies should be hash-verified. Defaults to true when integrity is enabled.
type LifecycleConfig
LifecycleConfig holds rules for automatic object expiration. Objects matching a rule’s prefix that are older than expiration_days are deleted by a background worker. Empty rules list disables lifecycle processing.
typeLifecycleConfigstruct {
Rules []LifecycleRule`yaml:"rules"`BatchSizeint`yaml:"batch_size"`// objects per DB query (default 100)}
type LifecycleRule
LifecycleRule defines a single object expiration rule.
Pprof is opt-in and off by default. The net/http/pprof handlers expose deep runtime state (de-anonymized stack frames, command-line flags, on-demand CPU profiles that double as DoS amplifiers), so production deployments should leave Pprof false. When enabled, it is only mounted on the dedicated metrics listener (Listen must be set) - never on the main S3 listener.
typeMetricsConfigstruct {
Enabledbool`yaml:"enabled"`Pathstring`yaml:"path"`Listenstring`yaml:"listen"`// Separate listener address (e.g. "127.0.0.1:9091"); if empty, metrics are served on the main listenerPprofbool`yaml:"pprof"`// Mount /debug/pprof/* on the metrics listener. Off by default; requires Listen to be set.}
type NotificationConfig
NotificationConfig holds the list of webhook endpoints for event delivery. An empty Endpoints slice disables notifications entirely.
NotificationEndpoint configures a single webhook destination.
typeNotificationEndpointstruct {
URLstring`yaml:"url"`// Webhook URL (required)Events []string`yaml:"events"`// Event type patterns with wildcard support (required)Prefixstring`yaml:"prefix"`// Only emit data events for keys matching this prefix (optional)Secretstring`yaml:"secret"`//nolint:gosec // G117: config struct, not a hardcoded credentialTimeouttime.Duration`yaml:"timeout"`// HTTP request timeout (default: 5s)MaxRetriesint`yaml:"max_retries"`// Delivery attempts before dropping (default: 3)}
type PendingPatternConfig
PendingPatternConfig configures the pending-row pattern used by the write path to avoid losing the prior copy of an overwritten key when the metadata commit fails.
typePendingPatternConfigstruct {
Enabled*bool`yaml:"enabled"`// Default: true. Set to false to disable.ReaperTicktime.Duration`yaml:"reaper_tick"`// How often the reaper resolves abandoned intents (default: 1m)MinAgetime.Duration`yaml:"min_age"`// Don't reap intents younger than this - guards in-flight PUTs (default: 5m)BatchSizeint`yaml:"batch_size"`// Max intents resolved per tick (default: 50)}
func (*PendingPatternConfig) IsEnabled
func (p*PendingPatternConfig) IsEnabled() bool
IsEnabled returns true unless the operator has explicitly disabled the pending pattern. The pointer-typed Enabled field lets the YAML loader distinguish “absent” (default true) from “explicitly false”.
type RateLimitConfig
RateLimitConfig holds per-IP rate limiting settings. Disabled by default.
typeRateLimitConfigstruct {
Enabledbool`yaml:"enabled"`RequestsPerSecfloat64`yaml:"requests_per_sec"`// Token refill rate (default: 100)Burstint`yaml:"burst"`// Max burst size (default: 200)TrustedProxies []string`yaml:"trusted_proxies"`// CIDRs whose X-Forwarded-For is trusted (e.g. ["10.0.0.0/8", "172.16.0.0/12"])CleanupIntervaltime.Duration`yaml:"cleanup_interval"`// How often stale entries are evicted (default: 1m)CleanupMaxAgetime.Duration`yaml:"cleanup_max_age"`// Entries older than this are evicted (default: 5m)}
type RebalanceConfig
RebalanceConfig holds settings for the periodic backend rebalancer. Disabled by default to avoid unexpected API calls and egress charges.
typeRebalanceConfigstruct {
Enabledbool`yaml:"enabled"`Strategystring`yaml:"strategy"`// "pack" or "spread"Intervaltime.Duration`yaml:"interval"`BatchSizeint`yaml:"batch_size"`Thresholdfloat64`yaml:"threshold"`// min utilization spread to triggerConcurrencyint`yaml:"concurrency"`// parallel moves (default: 5)}
type ReconcileConfig
ReconcileConfig controls the background orphan reconciler that periodically scans backends and imports untracked objects into the metadata database. Disabled by default.
typeReconcileConfigstruct {
Enabledbool`yaml:"enabled"`Intervaltime.Duration`yaml:"interval"`// How often to run (default: 24h)}
type RedisConfig
RedisConfig holds optional Redis connection settings for shared usage counters in multi-instance deployments. When omitted, counters are stored in local memory (single-instance default).
typeRedisConfigstruct {
Addressstring`yaml:"address"`// Redis address (host:port)Passwordstring`yaml:"password"`//nolint:gosec // G117: config struct, not a hardcoded credentialDBint`yaml:"db"`// Redis database number (default: 0)TLSbool`yaml:"tls"`// Use TLS for Redis connectionKeyPrefixstring`yaml:"key_prefix"`// Key prefix for namespacing (default: "s3orch")FailureThresholdint`yaml:"failure_threshold"`// Consecutive failures before circuit opens (default: 3)OpenTimeouttime.Duration`yaml:"open_timeout"`// Delay before probing recovery (default: 15s)}
type ReplicationConfig
ReplicationConfig holds settings for the background replication worker. When factor is 1, replication is disabled and behavior is identical to the single-copy default.
typeReplicationConfigstruct {
Factorint`yaml:"factor"`WorkerIntervaltime.Duration`yaml:"worker_interval"`BatchSizeint`yaml:"batch_size"`Concurrencyint`yaml:"concurrency"`// Parallel object replications (default: 5)UnhealthyThresholdtime.Duration`yaml:"unhealthy_threshold"`// Grace period before replacing copies on circuit-broken backends (default: 10m)}
type RoutingStrategy
RoutingStrategy determines how write operations select a target backend.
typeRoutingStrategystring
RoutingPack and related constants used by this package.
const (
// RoutingPack fills backends in order, returning the first with space.RoutingPackRoutingStrategy = "pack"// RoutingSpread distributes writes across backends by utilization ratio.RoutingSpreadRoutingStrategy = "spread")
type ServerConfig
ServerConfig holds HTTP server settings.
typeServerConfigstruct {
ListenAddrstring`yaml:"listen_addr"`LogLevelstring`yaml:"log_level"`// Log level: debug, info, warn, error (default: info)MaxObjectSizeint64`yaml:"max_object_size"`// Max upload size in bytes (default: 5GB)MaxConcurrentRequestsint`yaml:"max_concurrent_requests"`// Max concurrent S3 requests (default: 1000)MaxConcurrentReadsint`yaml:"max_concurrent_reads"`// Max concurrent read requests (0 = use global limit)MaxConcurrentWritesint`yaml:"max_concurrent_writes"`// Max concurrent write requests (0 = use global limit)LoadShedThresholdfloat64`yaml:"load_shed_threshold"`// Active shedding threshold (0.0-1.0, 0 = disabled)AdmissionWaittime.Duration`yaml:"admission_wait"`// Brief wait before rejection (0 = instant reject)BackendTimeouttime.Duration`yaml:"backend_timeout"`// Per-operation timeout for backend S3 calls (default: 30s)ReadHeaderTimeouttime.Duration`yaml:"read_header_timeout"`// Max time to read request headers (default: 10s)ReadTimeouttime.Duration`yaml:"read_timeout"`// Max time to read entire request including body (default: 5m)WriteTimeouttime.Duration`yaml:"write_timeout"`// Max time to write response (default: 5m)IdleTimeouttime.Duration`yaml:"idle_timeout"`// Max time to wait for next request on keep-alive (default: 120s)ShutdownDelaytime.Duration`yaml:"shutdown_delay"`// Delay before HTTP drain on SIGTERM for LB deregistration (default: 0)TLSTLSConfig`yaml:"tls"`}
type TLSConfig
TLSConfig holds optional TLS settings for the HTTP server. When CertFile and KeyFile are both set, the server listens with TLS. When both are empty, the server runs plain HTTP for backward compatibility.
typeTLSConfigstruct {
CertFilestring`yaml:"cert_file"`// Path to PEM-encoded certificate (or chain)KeyFilestring`yaml:"key_file"`// Path to PEM-encoded private keyMinVersionstring`yaml:"min_version"`// Minimum TLS version: "1.2" (default) or "1.3"ClientCAFilestring`yaml:"client_ca_file"`// Path to CA bundle for client certificate verification (mTLS)}
typeTracingConfigstruct {
Enabledbool`yaml:"enabled"`Endpointstring`yaml:"endpoint"`SampleRatefloat64`yaml:"sample_rate"`Insecurebool`yaml:"insecure"`// Use insecure connection (no TLS)}
type UIConfig
UIConfig holds settings for the built-in web dashboard. Disabled by default.
typeUIConfigstruct {
Enabledbool`yaml:"enabled"`Pathstring`yaml:"path"`// URL prefix for the dashboard (default: "/ui")AdminKeystring`yaml:"admin_key"`// Access key for dashboard loginAdminSecretstring`yaml:"admin_secret"`// Secret key for dashboard login (plaintext or bcrypt hash)AdminTokenstring`yaml:"admin_token"`// Separate token for admin API (defaults to admin_key if empty)SessionSecretstring`yaml:"session_secret"`//nolint:gosec // G117: config struct, not a hardcoded credential - HMAC key for session cookie derivation (independent of admin_secret)ForceSecureCookiesbool`yaml:"force_secure_cookies"`// Always set Secure flag on session cookies (use behind TLS-terminating proxy)}
type UsageFlushConfig
UsageFlushConfig holds settings for the periodic usage counter flush to the database. When adaptive flushing is enabled, the flush interval shortens automatically when any backend approaches a usage limit.
typeUsageFlushConfigstruct {
Intervaltime.Duration`yaml:"interval"`// Base flush interval (default: 30s)AdaptiveEnabledbool`yaml:"adaptive_enabled"`// Shorten interval near limitsAdaptiveThresholdfloat64`yaml:"adaptive_threshold"`// Ratio to trigger fast flush (default: 0.8)FastIntervaltime.Duration`yaml:"fast_interval"`// Interval when near limits (default: 5s)}
type VaultTransitConfig
VaultTransitConfig holds settings for HashiCorp Vault Transit key management.
typeVaultTransitConfigstruct {
Addressstring`yaml:"address"`// Vault server URLTokenstring`yaml:"token"`// Vault token (or via env var)TokenFilestring`yaml:"token_file"`// Path to file containing Vault token (re-read on each renewal tick; for Nomad workload identity)KeyNamestring`yaml:"key_name"`// Transit key nameMountPathstring`yaml:"mount_path"`// Transit mount path (default: "transit")CACertstring`yaml:"ca_cert"`// Path to PEM CA certificate for TLS verificationRenewIntervaltime.Duration`yaml:"renew_interval"`// Token renewal check interval (default: 5m)}
type WritePathConfig
WritePathConfig gates write-path correctness features. The pending-row pattern (PUT-before-COMMIT intent tracking) is on by default; operators can disable it to fall back to the legacy delete-on-record-failure path, which trades data-loss safety for one fewer round-trip per PUT.