Documentation
¶
Overview ¶
Package config reads the configuration of every command from environment variables into one typed Config, validated as a whole at startup so a command stops before doing anything with a value it cannot use (ADR 0002).
The variables, their defaults and an example are in .env.example. A secret, such as the log key, is held as a Secret: it never appears in a log line, an error message or a formatted Config.
Commands write only under Config.DataDir, the data volume, so the rest of the file system can be mounted read-only.
Index ¶
Constants ¶
const ( EnvAddr = "ARNAKOFF_ADDR" EnvLogLevel = "ARNAKOFF_LOG_LEVEL" EnvLogKey = "ARNAKOFF_LOG_KEY" EnvDataDir = "ARNAKOFF_DATA_DIR" EnvSourceACPR = "ARNAKOFF_SOURCE_ACPR" EnvAlertWebhook = "ARNAKOFF_ALERT_WEBHOOK" EnvProblemBaseURL = "ARNAKOFF_PROBLEM_BASE_URL" EnvBatchMaxItems = "ARNAKOFF_BATCH_MAX_ITEMS" EnvDatabaseURL = "ARNAKOFF_DATABASE_URL" EnvAPIKeySecret = "ARNAKOFF_API_KEY_SECRET" //nolint:gosec // G101: the name of a variable, not its value. EnvAPIKeyEnv = "ARNAKOFF_API_KEY_ENV" //nolint:gosec // G101: the name of a variable, not its value. EnvRateLimitKey = "ARNAKOFF_RATE_LIMIT_KEY" EnvRateLimitIP = "ARNAKOFF_RATE_LIMIT_IP" EnvRateLimitAuth = "ARNAKOFF_RATE_LIMIT_AUTH" EnvTrustedProxies = "ARNAKOFF_TRUSTED_PROXIES" )
Environment variables read by Load.
const ( DefaultAddr = ":8100" DefaultLogLevel = "info" DefaultDataDir = "var" // DefaultSourceACPR keeps the ACPR blacklist off: its reuse licence is // still to be obtained (docs/sources.md). DefaultSourceACPR = "false" // DefaultProblemBaseURL is where arnakoff/web documents the problems // the API answers, one page per code. DefaultProblemBaseURL = "https://arnakoff.com/docs/erreurs/" )
Defaults applied by Load to an unset variable. ARNAKOFF_LOG_KEY has none.
const ( // DefaultBatchMaxItems is the most items POST /v1/check/batch accepts, // as the owner set it; the contract's example states it. DefaultBatchMaxItems = 50 // MaxBatchMaxItems is the highest value Load accepts: beyond, one // request would weigh like a thousand checks. MaxBatchMaxItems = 1000 )
Bounds of ARNAKOFF_BATCH_MAX_ITEMS.
const ( DefaultRateLimitKey = 60 DefaultRateLimitIP = 30 // DefaultRateLimitAuth is the number of refused API keys a minute of // a client address, as the owner set it (#197). DefaultRateLimitAuth = 30 // MaxRateLimit is the highest limit Load accepts. MaxRateLimit = 10000 )
Defaults of the rate limits, in requests per minute, as the owner set them until the offers of #80.
const DefaultAPIKeyEnv = "live"
DefaultAPIKeyEnv accepts the production keys, "ark_live_…".
const MinLogKeyBytes = logging.MinKeyBytes
MinLogKeyBytes is the shortest log key Load accepts, once hex-decoded: the minimum of logging.New.
Variables ¶
var ErrInvalid = errors.New("invalid configuration")
ErrInvalid means a variable holds a value Load cannot use.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// Addr is the TCP address the HTTP API listens on, "host:port" with a
// numeric port; an empty host means every interface.
Addr string
// LogLevel is the minimum level written to the log.
LogLevel slog.Level
// LogKey is the HMAC key that pseudonymises personal data in the log.
LogKey Secret
// DataDir is the only directory the commands write to: the data
// volume. Every other path may be read-only.
DataDir string
// SourceACPR turns the ACPR blacklist on, once its reuse licence is
// obtained.
SourceACPR bool
// AlertWebhook is the HTTPS URL a failed or rejected sync is posted
// to; nil when unset or empty, and then alerts are only logged. It is a
// Secret: a webhook URL usually carries its credential.
AlertWebhook Secret
// ProblemBaseURL is the HTTPS URL of the documentation of the API's
// problems, ending with a slash: the type of a problem is its code
// under it.
ProblemBaseURL string
// BatchMaxItems is the most items POST /v1/check/batch accepts, from 1
// to MaxBatchMaxItems.
BatchMaxItems int
// DatabaseURL is the PostgreSQL connection string of the API key store;
// nil when unset or empty. RequireKeyStore tells whether it is set.
DatabaseURL Secret
// APIKeySecret is the HMAC key the API keys are digested with, kept
// out of the database; nil when unset or empty.
APIKeySecret Secret
// APIKeyEnv is the environment of the API keys accepted: "live" or
// "test".
APIKeyEnv string
// RateLimitKey is the number of requests per minute of an API key,
// from 1 to MaxRateLimit.
RateLimitKey int
// RateLimitIP is the number of requests per minute of a client address
// on the routes needing no key, from 1 to MaxRateLimit.
RateLimitIP int
// RateLimitAuth is the number of refused API keys per minute of a
// client address on the check routes, from 1 to MaxRateLimit: over it,
// its keys are no longer looked up.
RateLimitAuth int
// TrustedProxies are the proxies whose X-Forwarded-For field tells the
// client's address: nil when unset, empty when set to "none".
// RequireTrustedProxies tells whether it is set.
TrustedProxies []netip.Prefix
}
Config is the configuration of every command.
func Load ¶
Load reads the configuration with lookup, such as os.LookupEnv. A variable that is set, even to an empty string, is used as is; an unset one takes its default. It returns every invalid variable at once, each wrapping ErrInvalid; an error never quotes the value of a Secret.
func (Config) RequireDatabase ¶ added in v0.39.0
RequireDatabase returns an error, wrapping ErrInvalid, unless the database of the API key store is set.
func (Config) RequireKeyStore ¶ added in v0.39.0
RequireKeyStore returns an error, wrapping ErrInvalid, unless the API key store is configured: a database and an API key secret other than the log key, so that a leaked log key does not also let anyone check a key.
func (Config) RequireTrustedProxies ¶ added in v0.40.0
RequireTrustedProxies returns an error, wrapping ErrInvalid, when the API serves live keys without ARNAKOFF_TRUSTED_PROXIES: the operator must say which proxies may tell the client's address, or that none does.
func (Config) SnapshotDir ¶
SnapshotDir is where the validated snapshots of the sources are stored, inside DataDir.
type Secret ¶
type Secret []byte
Secret is a configuration value that must never reach a log, an error or a response. Every fmt verb, encoding/json and log/slog write it as "[redacted]"; only Bytes gives the value.
func (Secret) MarshalText ¶
MarshalText implements encoding.TextMarshaler, which encoding/json uses.