configx

package
v0.17.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 31, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package configx defines the JSON configuration schema shared by the apic code generator and the generated servers, together with the validation and normalization that enforce a secure-by-default posture. It covers the runtime server settings (bind address, TLS/mTLS mode, timeouts, request-size limits, compression) and the security surface: the default-deny authentication config (api_key/jwt/cookie/mtls/webhook), the CSRF double-submit settings, and signer-key pinning. Helpers resolve secrets from the environment and fail closed when a required value (e.g. a CSRF signing key) is missing or too weak. Code generated by apic; DO NOT EDIT.

Code generated by apic; DO NOT EDIT.

Code generated by apic; DO NOT EDIT.

Index

Constants

View Source
const (
	DefaultReadHeaderTimeoutMS = 5000
	DefaultReadTimeoutMS       = 15000
	DefaultWriteTimeoutMS      = 30000
	DefaultIdleTimeoutMS       = 60000
)

Default HTTP server timeouts in milliseconds (PERF-0073). Applied by DecodeRuntimeConfig when a member is absent or non-positive so a generated server never boots with unbounded read/write/idle timeouts (slowloris / idle-connection exhaustion). Values mirror the shipped reference configs (configs/*.json). Operators override per environment in runtime config.

View Source
const (
	DefaultHealthProbeTimeoutMS    = 2000
	DefaultHealthCheckTimeoutMS    = 1000
	DefaultHealthCacheTTLMS        = 500
	DefaultHealthMaxConcurrency    = 4
	DefaultHealthDrainDelayMS      = 5000
	DefaultHealthShutdownTimeoutMS = 30000
	DefaultHealthResponseDetails   = "summary"
	DefaultHealthLivenessPath      = "/livez"
	DefaultHealthReadinessPath     = "/readyz"
	DefaultHealthStartupPath       = "/startupz"
)

Default health subsystem values (docs/HEALTH_CHECK_ENHANCEMENT.md §2), applied by ApplyDefaults when a member is absent/zero.

Variables

View Source
var (
	// ErrCSRFSecretRefMissing indicates CSRF is enabled but secret_ref is empty.
	ErrCSRFSecretRefMissing = errors.New("configx: security.csrf.secret_ref is required when CSRF is enabled")
	// ErrCSRFKeyTooShort indicates the resolved CSRF key is shorter than 32 bytes.
	ErrCSRFKeyTooShort = errors.New("configx: CSRF signing key must be at least 32 bytes")
)
View Source
var ErrPlaintextPIN = errors.New("configx: literal PKCS#11 pin is not allowed in strict/FIPS mode; use pin_env")

ErrPlaintextPIN is returned by ResolvePIN(strict=true) when a literal PIN is configured instead of the env-indirection PINEnv. SEC-0032.

Functions

func ResolveCSRFKey

func ResolveCSRFKey(c *CSRFConfig, getenv func(string) string) ([]byte, error)

ResolveCSRFKey resolves the HMAC signing key from the environment, failing closed. Returns (nil, nil) when CSRF is disabled. getenv is injected for testability (pass os.Getenv at boot).

Types

type AuditConfig

type AuditConfig struct {
	Enabled bool `json:"enabled"`
	// SignKeyID is the security.signer.keys[].id used to sign each
	// envelope under FIPS profiles (AU-9 integrity). Required when
	// security.fips=true.
	SignKeyID string            `json:"sign_key_id,omitempty"`
	Sinks     []AuditSinkConfig `json:"sinks,omitempty"`
}

AuditConfig configures the FedRAMP audit pipeline (Plan 05).

type AuditSinkConfig

type AuditSinkConfig struct {
	// Kind selects the sink implementation. Only "file" is implemented
	// today (pkg/obsx/auditx.FileSink); "syslog" and "cef" are reserved
	// future kinds and are rejected by the config validator until a real
	// sink exists, so they cannot silently no-op at runtime (GAP-0081).
	Kind   string         `json:"kind"` // "file" (implemented); "syslog"/"cef" reserved
	Config map[string]any `json:"config,omitempty"`
}

AuditSinkConfig configures one audit sink.

type AuthConfig

type AuthConfig struct {
	APIKey bool `json:"api_key"`
	JWT    bool `json:"jwt"`
	// Cookie is true when at least one REST route resolves to auth:"cookie".
	// Derived from resolved route modes (see applyAuthDefaults) and used to
	// emit the top-level cookieAuth entry in the generated OpenAPI security
	// list, mirroring the APIKey/JWT bools.
	Cookie      bool   `json:"cookie"`
	JWTIssuer   string `json:"jwt_issuer,omitempty"`
	JWTAudience string `json:"jwt_audience,omitempty"`
	// Default is the fallback auth mode applied to any REST or WebSocket
	// route that omits `auth`. Recognized: "api_key", "jwt",
	// "mtls" (REST only), "webhook" (REST only), or "public" (explicitly
	// unauthenticated). Empty means NO default: under default-deny a route
	// that omits auth and is not explicitly public is a configuration error.
	Default string `json:"default,omitempty"`
	// DefaultRequiredRoles is the minimum RBAC role set applied to any
	// authenticated route (resolved mode != public) that declares no
	// required_roles of its own. Role hierarchy: admin > manager > user.
	DefaultRequiredRoles []string `json:"default_required_roles,omitempty"`
	// DefaultRequiredScopes is the scope set applied to any authenticated
	// route that declares no required_scopes of its own.
	DefaultRequiredScopes []string `json:"default_required_scopes,omitempty"`
	// CookieName is the name of the HttpOnly cookie that carries the session
	// JWT for routes using auth:"cookie". Empty defaults to "session" (see
	// AuthCookieName). Used by the generated cookie-auth extraction, the CSRF
	// auth-source check, and the emitted OpenAPI cookie security scheme.
	CookieName string `json:"cookie_name,omitempty"`
}

AuthConfig defines the authentication surface and the secure-first default-deny posture (F0). Default/DefaultRequiredRoles/DefaultRequiredScopes are applied by the generator to any route that declares no auth of its own.

func (AuthConfig) AuthCookieName

func (a AuthConfig) AuthCookieName() string

AuthCookieName returns the configured session-cookie name, defaulting to "session".

type CORSConfig

type CORSConfig struct {
	Enabled bool     `json:"enabled"`
	Origins []string `json:"origins"`
}

CORSConfig defines CORS enablement and origins.

type CSRFConfig

type CSRFConfig struct {
	// Enabled is the master switch. When false the generator emits no CSRF
	// middleware and no /csrf endpoint.
	Enabled bool `json:"enabled"`
	// SecretRef names the environment variable holding the HMAC signing key
	// (>=32 bytes). Required when Enabled; resolution fails closed at boot.
	SecretRef string `json:"secret_ref"`
	// CookieName is the non-HttpOnly cookie carrying the token. Default
	// "csrf_token".
	CookieName string `json:"cookie_name,omitempty"`
	// HeaderName is the request header echoing the token. Default
	// "X-CSRF-Token".
	HeaderName string `json:"header_name,omitempty"`
	// EndpointPath is the GET issuance route. Default "/csrf" (joined under
	// the API prefix by the generator).
	EndpointPath string `json:"endpoint_path,omitempty"`
	// TTLSeconds is the token lifetime. Default 43200 (12h).
	TTLSeconds int `json:"ttl_seconds,omitempty"`
	// SecureCookies sets the Secure attribute on the CSRF cookie. Nil
	// defaults to TRUE; set explicit false ONLY for local-dev over plain
	// HTTP (otherwise the browser drops the cookie and every write 403s).
	SecureCookies *bool `json:"secure_cookies,omitempty"`
	// SameSite is the cookie SameSite mode: "Strict" (default), "Lax", or
	// "None".
	SameSite string `json:"same_site,omitempty"`
	// ExemptPaths are additional paths exempt from enforcement. The issuance
	// endpoint and any *_login / *_logout / health routes are auto-exempt.
	ExemptPaths []string `json:"exempt_paths,omitempty"`
}

CSRFConfig configures generated CSRF protection. Defaults (applied by Normalize) follow OWASP guidance: 12h TTL, SameSite=Strict, Secure cookies on.

func (*CSRFConfig) CSRFSecureCookies

func (c *CSRFConfig) CSRFSecureCookies() bool

CSRFSecureCookies reports the effective Secure attribute (default true).

func (*CSRFConfig) Normalize

func (c *CSRFConfig) Normalize()

Normalize applies CSRFConfig defaults in place.

type HeadersConfig added in v0.14.3

type HeadersConfig struct {
	ContentSecurityPolicy     string `json:"content_security_policy,omitempty"`
	CrossOriginOpenerPolicy   string `json:"cross_origin_opener_policy,omitempty"`
	CrossOriginEmbedderPolicy string `json:"cross_origin_embedder_policy,omitempty"`
	CrossOriginResourcePolicy string `json:"cross_origin_resource_policy,omitempty"`
	PermissionsPolicy         string `json:"permissions_policy,omitempty"`
	DisableAll                bool   `json:"disable_all,omitempty"`
}

HeadersConfig configures per-deployment overrides for the SEC-0023 hardened response-header set. Field names and semantics mirror httpx.Config's header-override knob (pkg/httpx/server.go) exactly: for each header, an empty string keeps the httpx secure default, the literal "-" suppresses that single header, and any other value is emitted verbatim. DisableAll drops the whole hardened set at once (the legacy headers -- HSTS/X-Content-Type-Options/X-Frame-Options/Referrer-Policy -- are unaffected either way, matching httpx.Config.DisableSecurityHeaders).

func (*HeadersConfig) Get added in v0.14.3

func (h *HeadersConfig) Get() HeadersConfig

Get returns *h, or the zero HeadersConfig{} (every field empty/false -- "no overrides, hardened set enabled") when h is nil. Nil-safe accessor, mirroring CSRFConfig's Normalize()/CSRFSecureCookies() pattern, so a generated server's hcfg construction never needs an explicit nil check before reading an override field.

type HealthCheckConfig added in v0.15.1

type HealthCheckConfig struct {
	// Name identifies the check; must match the name passed to
	// WithHealthCheck/WithHealthChecker at boot.
	Name string `json:"name"`
	// Probes lists which probes this check participates in: "startup"
	// and/or "readiness". External checks must never be assigned to
	// "liveness" (enforced at generation).
	Probes []string `json:"probes"`
	// Critical controls aggregation: a failing critical check fails the
	// overall probe; a failing non-critical check only degrades it to
	// "warn".
	Critical bool `json:"critical"`
	// TimeoutMS is the per-check timeout. Zero inherits
	// HealthConfig.DefaultCheckTimeoutMS.
	TimeoutMS int `json:"timeout_ms,omitempty"`
}

HealthCheckConfig declares one external dependency check that the generated server requires a hook registration for.

type HealthConfig added in v0.15.1

type HealthConfig struct {
	// Enabled is the master switch. When false (or the block is absent)
	// the generator emits no probe endpoints.
	Enabled bool `json:"enabled"`
	// Service names the process in probe responses (the "service" field).
	Service string `json:"service,omitempty"`
	// Paths overrides the default probe endpoint paths.
	Paths HealthPaths `json:"paths,omitempty"`
	// ResponseDetails controls how much a probe response discloses:
	// "none", "summary" (default), or "full". "full" is reserved for a
	// future authenticated diagnostic endpoint; the generator rejects it
	// on the public probe surface.
	ResponseDetails string `json:"response_details,omitempty"`
	// ProbeTimeoutMS bounds the overall probe evaluation (all checks for
	// that probe combined). Default 2000.
	ProbeTimeoutMS int `json:"probe_timeout_ms,omitempty"`
	// DefaultCheckTimeoutMS is the per-check timeout applied when a check
	// declares no timeout_ms of its own. Default 1000.
	DefaultCheckTimeoutMS int `json:"default_check_timeout_ms,omitempty"`
	// CacheTTLMS is how long a completed check result is reused before
	// the next probe request re-invokes the hook. Default 500.
	CacheTTLMS int `json:"cache_ttl_ms,omitempty"`
	// MaxConcurrency bounds simultaneous in-flight dependency check
	// invocations across all probes. Default 4.
	MaxConcurrency int `json:"max_concurrency,omitempty"`
	// DrainDelayMS is how long readiness reports failure before shutdown
	// proceeds, giving load balancers time to stop routing new traffic.
	// Default 5000.
	DrainDelayMS int `json:"drain_delay_ms,omitempty"`
	// ShutdownTimeoutMS bounds the graceful HTTP shutdown once draining
	// completes. Default 30000. Must not be shorter than DrainDelayMS
	// (enforced at generation).
	ShutdownTimeoutMS int `json:"shutdown_timeout_ms,omitempty"`
	// PublishOpenAPI is reserved and must be false/omitted: it is not
	// implemented in this generator version, and generation fails when true.
	// Probes are a control-plane concern and are always omitted from the
	// public OpenAPI spec regardless of this flag.
	PublishOpenAPI bool `json:"publish_openapi,omitempty"`
	// Checks declares the external dependency checks the generated
	// server expects a matching WithHealthCheck/WithHealthChecker
	// registration for at startup.
	Checks []HealthCheckConfig `json:"checks,omitempty"`
}

HealthConfig configures the generated control-plane health subsystem: the /livez, /readyz, and /startupz probe endpoints, their timeouts and caching, drain/shutdown coordination, and the declared set of external dependency checks (see docs/HEALTH_CHECK_ENHANCEMENT.md). Absence (a nil *HealthConfig on RuntimeConfig) means the subsystem is disabled, preserving byte-for-byte behavior for existing configurations.

func (*HealthConfig) ApplyDefaults added in v0.15.1

func (h *HealthConfig) ApplyDefaults()

ApplyDefaults fills zero-valued members with the package defaults. Explicit non-zero values are preserved.

func (*HealthConfig) EffectivePaths added in v0.15.1

func (h *HealthConfig) EffectivePaths() HealthPaths

EffectivePaths returns the probe paths that would be in effect, applying the package defaults for any path left unset. Nil-safe: an absent block yields the default paths (/livez, /readyz, /startupz).

func (*HealthConfig) Get added in v0.15.1

func (h *HealthConfig) Get() HealthConfig

Get is nil-safe: an unconfigured block yields the zero value (disabled, no overrides).

func (*HealthConfig) On added in v0.15.1

func (h *HealthConfig) On() bool

On reports whether the health subsystem is configured and enabled. Nil-safe: an absent block is never "on".

type HealthPaths added in v0.15.1

type HealthPaths struct {
	Liveness  string `json:"liveness,omitempty"`
	Readiness string `json:"readiness,omitempty"`
	Startup   string `json:"startup,omitempty"`
}

HealthPaths overrides the default probe endpoint paths.

type LimitConfig

type LimitConfig struct {
	MaxHeaderBytes int   `json:"max_header_bytes"`
	MaxBodyBytes   int64 `json:"max_body_bytes"`
}

LimitConfig defines request-size limits.

type LogExportConfig added in v0.15.1

type LogExportConfig struct {
	// Enabled: nil = env-driven (OTEL_LOGS_EXPORTER / OTLP endpoints);
	// true = force on; false = hard off. Governs the OTLP log exporter only;
	// on-disk File delivery is controlled by its own block.
	Enabled *bool `json:"enabled,omitempty"`
	// Endpoint overrides the logs OTLP URL (verbatim, e.g. …/v1/logs).
	Endpoint string `json:"endpoint,omitempty"`
	// File, when set, enables rotating on-disk log delivery (lumberjack) in
	// addition to stdout and any OTLP export. The file sink joins the same
	// redaction-wrapped fanout, so on-disk lines are redacted too.
	File *LogFileBlockConfig `json:"file,omitempty"`
}

LogExportConfig configures log delivery beyond the always-on stdout JSON logs: OTLP log-aggregation export and (File) rotating on-disk delivery.

func (*LogExportConfig) Get added in v0.15.1

Get is nil-safe.

type LogFileBlockConfig added in v0.15.1

type LogFileBlockConfig struct {
	// Path is the active log file path. Required when the block is present.
	Path string `json:"path"`
	// MaxSizeMB is the rotation size threshold in megabytes (0 => default).
	MaxSizeMB int `json:"max_size_mb,omitempty"`
	// MaxBackups is the number of rotated files retained (0 => default).
	MaxBackups int `json:"max_backups,omitempty"`
	// MaxAgeDays is the maximum retained age of a rotated file (0 => default).
	MaxAgeDays int `json:"max_age_days,omitempty"`
	// Compress gzips rotated backups.
	Compress bool `json:"compress,omitempty"`
}

LogFileBlockConfig is the config-file view of obsx.LogFileConfig: rotating on-disk log delivery via lumberjack. Zero size/backup/age members inherit the auditx-mirrored defaults (100 MiB / 7 backups / 365 days) at runtime.

func (*LogFileBlockConfig) Get added in v0.15.1

Get is nil-safe: an unconfigured block yields the zero value.

type MCPConfig

type MCPConfig struct {
	Transport []string `json:"transport"`
	// Tools is carried in runtime.json (the full config) but consumed only
	// at generate time -- the tool surface is baked into the generated MCP
	// handlers. Declared, accepted, and ignored so the strict runtime
	// decode of the full-config superset succeeds (see DecodeRuntimeConfig).
	// The generator's MCPConfigSection models it with a richer type.
	Tools any `json:"tools,omitempty"`
}

MCPConfig defines enabled MCP transports.

type MetricsEndpointConfig added in v0.15.1

type MetricsEndpointConfig struct {
	Enabled bool `json:"enabled"`
	// Path defaults to /metrics.
	Path string `json:"path,omitempty"`
	// Auth: "inherit" (default) or "bearer".
	Auth string `json:"auth,omitempty"`
	// BearerTokenEnv names the env var holding the scrape token when
	// Auth=="bearer" (default APIC_METRICS_TOKEN; the _FILE variant is
	// honored). Minimum 16 bytes; boot fails without it.
	BearerTokenEnv string `json:"bearer_token_env,omitempty"`
	// DisableGoCollector skips go/process runtime collectors.
	DisableGoCollector bool `json:"disable_go_collector,omitempty"`
}

MetricsEndpointConfig exposes Prometheus scraping. There is NO public mode: the endpoint is always authenticated ("inherit" = the server's composite auth surface; "bearer" = constant-time scrape token).

func (MetricsEndpointConfig) EffectiveAuth added in v0.15.1

func (m MetricsEndpointConfig) EffectiveAuth() string

EffectiveAuth returns the auth mode (default inherit).

func (MetricsEndpointConfig) EffectivePath added in v0.15.1

func (m MetricsEndpointConfig) EffectivePath() string

EffectivePath returns the scrape path (default /metrics).

func (MetricsEndpointConfig) EffectiveTokenEnv added in v0.15.1

func (m MetricsEndpointConfig) EffectiveTokenEnv() string

EffectiveTokenEnv returns the bearer-token env var name.

func (*MetricsEndpointConfig) Get added in v0.15.1

Get is nil-safe: an unconfigured block yields the zero value (disabled).

type OTELBlockConfig added in v0.15.1

type OTELBlockConfig struct {
	// Enabled: nil = env-driven (any OTLP endpoint env var activates);
	// true = force on (default endpoint http://localhost:4318 if no
	// endpoint is given anywhere); false = hard off (env vars ignored,
	// only the code-level WithOTEL/WithTelemetry options can re-enable).
	Enabled *bool `json:"enabled,omitempty"`
	// Endpoint is the base OTLP/HTTP URL (…:4318); per-signal /v1/<signal>
	// paths are appended. OTEL_EXPORTER_OTLP_ENDPOINT overrides it.
	Endpoint string `json:"endpoint,omitempty"`
	// Protocol: "http/json" (default). "grpc" fails validation.
	Protocol string `json:"protocol,omitempty"`
	// ServiceName seeds service.name (OTEL_SERVICE_NAME overrides).
	ServiceName string `json:"service_name,omitempty"`
	// HeadersEnv names an env var holding "k=v,k2=v2" export headers
	// (e.g. collector auth). Never inline secrets in config files.
	HeadersEnv string `json:"headers_env,omitempty"`
	// TracesSampler / TracesSamplerArg mirror OTEL_TRACES_SAMPLER(_ARG).
	TracesSampler    string `json:"traces_sampler,omitempty"`
	TracesSamplerArg string `json:"traces_sampler_arg,omitempty"`
	// MetricExportIntervalMS mirrors OTEL_METRIC_EXPORT_INTERVAL.
	MetricExportIntervalMS int `json:"metric_export_interval_ms,omitempty"`
}

OTELBlockConfig is the config-file baseline for the OTEL bootstrap.

func (*OTELBlockConfig) Get added in v0.15.1

Get is nil-safe: an unconfigured block yields the zero value.

type ObservabilityConfig

type ObservabilityConfig struct {
	EnableDebug bool `json:"enable_debug"`

	// OTEL configures the OpenTelemetry bootstrap baseline. Env vars
	// (OTEL_EXPORTER_OTLP_ENDPOINT, ...) override these values; the
	// generated WithOTEL option overrides both.
	OTEL *OTELBlockConfig `json:"otel,omitempty"`

	// Metrics exposes the authenticated Prometheus scrape endpoint.
	Metrics *MetricsEndpointConfig `json:"metrics,omitempty"`

	// Logs configures OTLP log-aggregation delivery (in addition to the
	// always-on stdout JSON logs).
	Logs *LogExportConfig `json:"logs,omitempty"`

	// Tracing configures the correlation-ID surface: the header propagated
	// end-to-end and whether trace/span IDs are threaded into request logs.
	Tracing *TracingBlockConfig `json:"tracing,omitempty"`
}

ObservabilityConfig controls debug endpoints and the built-in observability delivery: env-first OTEL bootstrap, the authenticated Prometheus /metrics endpoint, and OTLP log delivery. Precedence at runtime: code options (WithOTEL/WithPrometheus) > OTEL_* env vars > this block > built-in defaults.

type PasswordHashConfig

type PasswordHashConfig struct {
	// Default algorithm for fields that declare hash:"default".
	Default string `json:"default,omitempty"`
	// PepperEnv names an environment variable holding a server-side pepper
	// (optional defense-in-depth; applied via HMAC-SHA-256 before hashing).
	PepperEnv string `json:"pepper_env,omitempty"`
}

PasswordHashConfig is the global password-hashing policy block.

type PathRateLimit

type PathRateLimit struct {
	PathPrefix string  `json:"path_prefix"`
	PerIPRPS   float64 `json:"per_ip_rps"`
	PerIPBurst int     `json:"per_ip_burst"`
	// TrustedProxyCIDRs lists the reverse-proxy networks whose forwarded
	// headers (X-Forwarded-For / X-Real-IP) this path's limiter honors when
	// the global PerIPSource selects a proxy-header source. Empty (the
	// default) INHERITS the global RateLimitConfig.TrustedProxyCIDRs set, so a
	// forwarded PerIPSource keys the same way at every layer; set this field
	// to override the global set for this path only. (Only an empty GLOBAL set
	// trusts no proxy — see RateLimitConfig.TrustedProxyCIDRs.) Threaded into
	// httpx.PathLimit at generation. T-06 / GAP-0094 / GAP-0095.
	TrustedProxyCIDRs []string `json:"trusted_proxy_cidrs,omitempty"`
}

PathRateLimit is a stricter per-IP rate-limit bucket scoped to a path prefix (F3) — e.g. a tighter ceiling on /v1/auth/* to blunt credential stuffing. Applied IN ADDITION TO the global per-IP limiter.

type RateLimitConfig

type RateLimitConfig struct {
	GlobalRPS   int     `json:"global_rps"`
	Burst       int     `json:"burst"`
	PerIPRPS    float64 `json:"per_ip_rps,omitempty"`
	PerIPBurst  int     `json:"per_ip_burst,omitempty"`
	PerIPSource string  `json:"per_ip_source,omitempty"`
	// TrustedProxyCIDRs lists the reverse-proxy networks whose forwarded
	// headers (X-Forwarded-For / X-Real-IP) the global per-IP limiter honors
	// when PerIPSource is a proxy-header source. Empty (the default) trusts no
	// proxy. Each entry must be a valid CIDR (e.g. "10.0.0.0/8"); malformed
	// entries are rejected at config validation. T-06 / GAP-0094.
	TrustedProxyCIDRs []string `json:"trusted_proxy_cidrs,omitempty"`
	// PathOverrides install stricter per-IP buckets for matching path
	// prefixes, checked before the route handler. Longest-prefix match wins.
	PathOverrides []PathRateLimit `json:"path_overrides,omitempty"`
}

RateLimitConfig defines global rate-limit defaults.

GlobalRPS / Burst (-> APIOptions.GlobalRate / GlobalBurst) configure a single server-wide aggregate token bucket shared by every generated route. It is a coarse ceiling: it is checked once per request (after auth/authz, just before the per-route bucket) in addition to -- not instead of -- the per-route rateLimit buckets (which remain the tighter per-endpoint ceiling) and the per-IP limiter. When GlobalRPS is 0 (or Burst is 0) the aggregate limiter is disabled. Note: a route that declares no rateLimit of its own still falls back to GlobalRPS as its *per-route* default rate -- that pre-existing behavior is unchanged and is separate from the aggregate ceiling described here. PerIPRPS / PerIPBurst configure a coarser ceiling applied to every route, partitioned by client IP (the key source is PerIPSource: "remote_addr" (default, safe), "x-forwarded-for", "x-real-ip", or "tls-subject"). A PerIPRPS of zero disables the per-IP layer (opt-in).

When PerIPSource selects a forwarded-header source ("x-forwarded-for" or "x-real-ip"), the limiter honors that header ONLY for peers within TrustedProxyCIDRs. With no trusted CIDRs configured (the default) no proxy is trusted: forged forwarded headers are ignored and keying falls back to the peer's RemoteAddr. Set TrustedProxyCIDRs to the reverse-proxy networks in front of the server, otherwise a forwarded-header source silently collapses every client behind the proxy into a single bucket. T-06 / GAP-0094.

type RuntimeConfig

type RuntimeConfig struct {
	Server        ServerConfig        `json:"server"`
	Security      SecurityConfig      `json:"security"`
	MCP           MCPConfig           `json:"mcp"`
	Observability ObservabilityConfig `json:"observability"`
	// Health configures the control-plane health subsystem (/livez,
	// /readyz, /startupz). Nil means disabled, preserving byte-for-byte
	// behavior for existing configurations that predate this block.
	Health *HealthConfig `json:"health,omitempty"`

	// The following members are present in runtime.json (the full
	// generator config) but are consumed only at generate time -- the
	// runtime behaviour they describe is already baked into the generated
	// handlers/types. They are declared here, accepted, and ignored so the
	// strict DecodeRuntimeConfig decode of the full-config superset
	// succeeds while still rejecting genuinely unknown members. The
	// generator's Config type shadows each with its richly-typed
	// equivalent (the same embedded-vs-outer pattern already used for
	// MCP), so this raw view is used only by the runtime decoder.
	// (api/websocket/schemas/graphql/shared)
	API       any `json:"api,omitempty"`
	Websocket any `json:"websocket,omitempty"`
	Schemas   any `json:"schemas,omitempty"`
	GraphQL   any `json:"graphql,omitempty"`
	// Shared is the generate-time-only shared-runtime import prefix
	// (ENG-1424); it selects whether this generation vendors its own
	// pkg/ copy or imports a shared apic runtime tree. Accepted and
	// ignored here for the same reason as api/websocket/schemas/graphql.
	Shared any `json:"shared,omitempty"`
	// Client selects which client SDKs (react_query/react_ui/python/
	// rust/zig) to emit at generate time; the runtime never consults it.
	// Accepted and ignored here for the same reason as
	// api/websocket/schemas/graphql/shared -- without this field, any
	// config declaring a top-level "client" block (11 of the 39
	// configs/*.json fixtures) fails DecodeRuntimeConfig at boot with
	// "unknown object member name \"client\"" even though generation
	// itself succeeds cleanly.
	Client any `json:"client,omitempty"`
}

RuntimeConfig is the canonical runtime config contract used by generator and server.

func DecodeRuntimeConfig

func DecodeRuntimeConfig(raw []byte) (RuntimeConfig, error)

DecodeRuntimeConfig decodes the embedded runtime.json into RuntimeConfig with strict member checking. runtime.json is the FULL generator config (it also carries api/websocket/schemas/graphql so a single artifact reproduces the build); those generate-time-only members are declared as ignored fields on RuntimeConfig below so the strict decode accepts the superset while still rejecting genuinely unknown members (typo protection). Rejecting the superset previously made the generated server fail to boot ("unknown object member name \"api\"").

type SecurityConfig

type SecurityConfig struct {
	Auth      AuthConfig      `json:"auth"`
	CORS      CORSConfig      `json:"cors"`
	RateLimit RateLimitConfig `json:"rate_limit"`
	Roles     []string        `json:"roles,omitempty"`
	// FIPS, when true, requires the generated binary to operate inside
	// the Go 1.26 FIPS 140-3 Cryptographic Module. The apic generator
	// rejects HS256-only JWT operations under this mode (NIST 800-53
	// SC-13). Hardware-backed JWT signing comes from the security.signer
	// block (see Plan 04). Default false preserves backward compatibility.
	FIPS bool `json:"fips,omitempty"`
	// UnsafeAllowSymmetricOIDCAlg, when true, suppresses the generator
	// hard-error that fires when any route in an OIDC profile (oidc_*)
	// declares auth: "jwt" with a symmetric algorithm (HS* family) or
	// with no jwt_alg at all (legacy HS256 default). The classic
	// "OIDC capability gap" footgun — the resource-server verifier
	// defaults to HS256 against an IdP that publishes a JWKS and signs
	// with RS256, producing either a silent functional regression or
	// (in deployments where the symmetric secret leaks) an alg-confusion
	// forgery primitive. Defaults to false so the generator fails closed.
	// Mirrors the OIDCRefreshTokenPolicy.UnsafeAllowStatelessJWT
	// "explicit opt-in for known-unsafe configurations" pattern.
	UnsafeAllowSymmetricOIDCAlg bool `json:"unsafe_allow_symmetric_oidc_alg,omitempty"`
	// Signer configures the hardware- or KMS-backed crypto.Signer used
	// for TLS server certs and JWT signing (Plan 04). When nil, the
	// generator emits HS256 (forbidden under FIPS) or relies on the
	// listener's PEM-loaded key.
	Signer *SignerConfig `json:"signer,omitempty"`
	// Webauthn configures the Plan 06 WebAuthn ceremony surface when any
	// operation references a profileWebauthn* profile.
	Webauthn *WebauthnRuntimeConfig `json:"webauthn,omitempty"`
	// Audit configures the FedRAMP audit pipeline (Plan 05). Nil means
	// "no audit emit"; legacy obsx.LogAudit slog records continue to
	// flow unconditionally.
	Audit *AuditConfig `json:"audit,omitempty"`
	// Session configures AC-7 / AC-11 / AC-12 enforcement (Plan 05).
	// Nil means "no session policy enforced"; the runtime falls back to
	// stateless JWT semantics.
	Session *SessionConfig `json:"session,omitempty"`
	// Webhooks resolves named webhook secrets at boot. Keyed by the
	// WebhookContract.SecretRef value the generator emits per-route.
	// Entries with an empty SecretEnv are rejected by the runtime
	// helper at startup (fail-closed).
	Webhooks map[string]WebhookSecretRef `json:"webhooks,omitempty"`
	// CSRF configures generated CSRF protection (signed double-submit,
	// session-bound). Nil or Enabled=false means no CSRF enforcement.
	CSRF *CSRFConfig `json:"csrf,omitempty"`
	// PasswordHash configures default password-hashing policy for fields that
	// declare hash:"default". Optional; when absent the generator uses the
	// FIPS-aware built-in default (argon2id, or pbkdf2-sha256 under FIPS).
	PasswordHash *PasswordHashConfig `json:"password_hash,omitempty"`
	// Headers configures per-deployment overrides for the SEC-0023 hardened
	// response-header set that httpx applies by default
	// (Content-Security-Policy, Cross-Origin-Opener/Embedder/Resource-Policy,
	// Permissions-Policy). Nil (the default) applies the httpx secure
	// defaults unmodified -- a pure-JSON API gets `default-src 'none'`. A
	// browser-facing service (an HTML SPA's same-origin API) sets this block
	// to publish a working CSP instead of being stuck on the hardened
	// default. GENERATOR_BUGS.md L-35.
	Headers *HeadersConfig `json:"headers,omitempty"`
}

SecurityConfig defines top-level security options.

type ServerConfig

type ServerConfig struct {
	Bind              string        `json:"bind"`
	TLS               TLSConfig     `json:"tls"`
	Timeouts          TimeoutConfig `json:"timeouts"`
	Limits            LimitConfig   `json:"limits"`
	EnableCompression bool          `json:"enable_compression,omitempty"`
}

ServerConfig defines runtime server bind/tls/timeout/limit settings.

EnableCompression turns on transparent gzip of text-ish JSON responses (>=1 KiB, client must send Accept-Encoding: gzip). It is off unless the config opts in so the wire shape stays byte-identical for callers that have not requested it.

type SessionConfig

type SessionConfig struct {
	MaxFailures             int `json:"max_failures,omitempty"`              // AC-7
	LockoutDurationSeconds  int `json:"lockout_duration_seconds,omitempty"`  // AC-7
	InactivitySeconds       int `json:"inactivity_seconds,omitempty"`        // AC-11
	AbsoluteLifetimeSeconds int `json:"absolute_lifetime_seconds,omitempty"` // AC-12
}

SessionConfig configures AC-7 / AC-11 / AC-12 enforcement (Plan 05).

type SignerConfig

type SignerConfig struct {
	// Backend is the registered backend name (e.g. "softfile", "pkcs11",
	// "awskms", "azurekv"). Each backend lives behind its own build tag
	// in pkg/securex/signerx/<backend>.
	Backend string `json:"backend"`
	// Config is the raw backend-specific config blob (path, region,
	// vault_url, library_path, etc.).
	Config map[string]any `json:"config,omitempty"`
	// Keys are the keys this binary will open. Each entry pairs a
	// signerx.KeyRef.ID with a "use" tag ("tls", "jwt", "client-assertion").
	Keys []SignerKey `json:"keys,omitempty"`
}

SignerConfig configures a hardware-/KMS-backed crypto.Signer.

type SignerKey

type SignerKey struct {
	ID  string `json:"id"`
	Use string `json:"use,omitempty"` // "tls" | "jwt" | "client-assertion"
	Alg string `json:"alg,omitempty"` // "RS256" | "ES256" | "PS256"
	// PINEnv names the env var the PKCS#11 PIN is read from at boot
	// (e.g. "APIC_HSM_PIN"). SEC-0032: production-safe path that keeps
	// the secret out of config files. When set it takes precedence over
	// PIN and a literal PIN alongside it is rejected.
	PINEnv string `json:"pin_env,omitempty"`
	// PIN is a literal PKCS#11 PIN. SEC-0032: accepted only for local
	// dev/test; ResolvePIN rejects it when strict (FIPS/prod) is requested.
	PIN string `json:"pin,omitempty"`
}

SignerKey binds one backend key to a runtime role.

func (SignerKey) ResolvePIN

func (k SignerKey) ResolvePIN(strict bool) (string, error)

ResolvePIN returns the PKCS#11 PIN, preferring the PINEnv env-var indirection over a literal PIN (SEC-0032). When strict is true (FIPS or production posture) a literal PIN is refused fail-closed; a PINEnv naming an unset/empty var is also an error so misconfiguration cannot silently fall through to an empty PIN.

type TLSConfig

type TLSConfig struct {
	CertPath string `json:"cert_path"`
	KeyPath  string `json:"key_path"`
	// Mode is the listener TLS mode. The empty string (default) means TLS
	// is required: the generated server refuses to boot without a cert.
	// "off" is the EXPLICIT opt-in to serve plain HTTP for deployments that
	// terminate TLS upstream (ingress/mesh); it is the config-driven
	// equivalent of server.WithInsecureHTTP(). Any other value is treated
	// as TLS-required (secure by default).
	Mode       string  `json:"mode,omitempty"`
	MTLSCAPath *string `json:"mtls_ca_path"`
}

TLSConfig defines TLS paths and optional mTLS CA bundle.

type TimeoutConfig

type TimeoutConfig struct {
	ReadHeaderMS int `json:"read_header_ms"`
	ReadMS       int `json:"read_ms"`
	WriteMS      int `json:"write_ms"`
	IdleMS       int `json:"idle_ms"`
}

TimeoutConfig defines HTTP server timeout values in milliseconds.

func (*TimeoutConfig) ApplyDefaults

func (t *TimeoutConfig) ApplyDefaults()

ApplyDefaults fills non-positive timeout members with the package defaults (PERF-0073). Explicit positive values are preserved.

type TracingBlockConfig added in v0.15.1

type TracingBlockConfig struct {
	// Enabled: nil = on by default; explicit false disables W3C
	// trace-context propagation only (traceparent/tracestate header
	// parsing/forwarding, see PropagationOn). The correlation-ID
	// middleware is always-on by design and does not honor this flag — a
	// correlation id is minted/echoed on every request regardless of
	// Enabled.
	Enabled *bool `json:"enabled,omitempty"`
	// CorrelationHeader names the operator-controlled log/header token,
	// validated against the correlation grammar at generation time. Empty
	// defaults to "X-Correlation-ID".
	CorrelationHeader string `json:"correlation_header,omitempty"`
	// LogTraceIDs: nil or true = thread trace_id/span_id into request
	// logs; explicit false omits them. Gates trace_id/span_id only:
	// correlation_id is emitted unconditionally whenever the request
	// carries one, independent of this flag.
	LogTraceIDs *bool `json:"log_trace_ids,omitempty"`
}

TracingBlockConfig configures the correlation-ID surface: the header propagated end-to-end between services and whether trace/span IDs are threaded into request logs.

func (TracingBlockConfig) EffectiveHeader added in v0.15.1

func (t TracingBlockConfig) EffectiveHeader() string

EffectiveHeader returns the correlation header name (default X-Correlation-ID).

func (*TracingBlockConfig) Get added in v0.15.1

Get is nil-safe: an unconfigured block yields the zero value.

func (TracingBlockConfig) LogTraceIDsOn added in v0.15.1

func (t TracingBlockConfig) LogTraceIDsOn() bool

LogTraceIDsOn reports whether trace/span IDs are threaded into request logs (nil or true = on; explicit false = off).

func (TracingBlockConfig) PropagationOn added in v0.15.1

func (t TracingBlockConfig) PropagationOn() bool

PropagationOn reports whether correlation-ID propagation is active (nil or true = on; explicit false = off).

type WebauthnRuntimeConfig

type WebauthnRuntimeConfig struct {
	RPID                  string   `json:"rp_id"`
	RPDisplayName         string   `json:"rp_display_name"`
	Origins               []string `json:"origins"`
	AAGUIDAllowList       []string `json:"aaguid_allow_list,omitempty"` // hex strings
	AttestationPreference string   `json:"attestation_preference,omitempty"`
	UserVerification      string   `json:"user_verification,omitempty"`
	RequireResidentKey    bool     `json:"require_resident_key,omitempty"`
	// AttestationRootsPath is the filesystem path to a PEM bundle of
	// trusted attestation root certificates, loaded at server boot
	// (mirroring server.tls.mtls_ca_path) and passed through to
	// webauthnx.Config.AttestationRoots. REQUIRED whenever
	// AAGUIDAllowList is non-empty (R10-2 / APPSEC-14): an allow-list
	// with no trust anchor to verify attestation chains against cannot
	// distinguish a genuinely vendor-attested authenticator from a
	// trivially self-signed forgery, and webauthnx.NewServer refuses to
	// boot in that combination. Populate from your accepted FIDO vendor
	// attestation root certificates. See docs/WEBAUTHN_MODE.md.
	AttestationRootsPath string `json:"attestation_roots_path,omitempty"`
}

WebauthnRuntimeConfig configures the apic WebAuthn surface (Plan 06).

type WebhookSecretRef

type WebhookSecretRef struct {
	// SecretEnv is the env var name (e.g. "APIC_WEBHOOK_STRIPE_SECRET")
	// the runtime reads. Required; the boot helper refuses to start
	// with an empty value when any route references this entry.
	SecretEnv string `json:"secret_env"`
	// SecretFileEnv is an optional env var pointing at a file path
	// the runtime reads instead of taking the secret from an env var
	// directly. Use for FIPS / k8s-secrets-volume deployments where
	// the secret must live on disk under operator-controlled ACLs.
	// When both SecretEnv and SecretFileEnv are set the file wins.
	SecretFileEnv string `json:"secret_file_env,omitempty"`
}

WebhookSecretRef configures one inbound-webhook secret source. The runtime resolves SecretEnv at boot to fetch the HMAC key the per-route VerifyWebhook call uses. Mirrors SignerKey's env-var-named-by-operator pattern.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL