config

package
v0.0.3 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Index

Constants

View Source
const ConfigFlag = "config"

ConfigFlag is the name of the always-registered persistent flag that points the loader at a config file. RegisterFlags registers it unconditionally.

View Source
const ConfigPathEnv = "FORGE_CONFIG"

ConfigPathEnv is the documented environment variable that supplies the config-file path when the --config flag is not set. The flag, when set, takes precedence over this env var. Set FORGE_CONFIG to load a config file without passing --config (e.g. in a container entrypoint).

Variables

This section is empty.

Functions

func DevAuthBypass

func DevAuthBypass(msg proto.Message) bool

DevAuthBypass reports whether this server runs with NO real auth: authn passthrough + authz allow-all + synthetic dev claims.

It is an EXPLICIT, two-factor opt-in and is NEVER implied by the mode field alone: development mode gives dev ergonomics but KEEPS auth enforced. To actually bypass auth you must ALSO set AUTH_DEV_MODE=true. In production the bypass is impossible — Mode is never dev there.

func Load

func Load(cmd *cobra.Command, msg proto.Message) error

Load populates msg in place from cobra flags > environment variables > proto defaults, for every field carrying a (forge.v1.config) option. It is the cobra-facing alias of LoadInto. cmd may be nil (env + defaults only). Sensitive fields resolve from env / Secret mount only.

func LoadInto

func LoadInto(cmd *cobra.Command, msg proto.Message) error

LoadInto populates msg in place using the full forge config precedence — later layers OVERRIDE earlier ones:

	defaults  →  config file  →  environment  →  flags
	(earliest)                                   (wins)

  - defaults: every annotated field's proto default (sensitive fields get
    none — an inline secret default would be a leak).
  - config file: when a path is EXPLICITLY given via the --config flag or
    the FORGE_CONFIG env var, the file is proto-native unmarshaled INTO msg,
    overlaying the defaults (see filelayer.go). A missing/invalid explicit
    file is a LOUD error — never a silent fallback. With no path given this
    layer is simply skipped (normal precedence, not a fallback).
  - environment: each field's env var overrides the file/default value.
  - flags: a flag changed on THIS invocation overrides everything.

It is the runtime, descriptor-driven loader: empty-env handling, required- field errors, and per-kind parsing all key off the (forge.v1.config) field options. cmd may be nil (file via FORGE_CONFIG + env + defaults only), so LoadInto works from non-cobra entrypoints too.

Durations: declare a duration-shaped field as google.protobuf.Duration in the config proto — env/flag layers parse the Go-duration string ("5s") into the message, and consumers read it with .AsDuration(). (A plain string field stays a string; the descriptor has no name heuristic.)

The companion semantics — Mode/DevAuthBypass (role=MODE) and Validate (TLS/CORS roles + allowed_values) — live in this package too (semantic.go), as FREE FUNCTIONS over the message. There is no parallel generated struct: a project holds the proto config type and calls these directly.

func LoadTyped

func LoadTyped[T proto.Message](cmd *cobra.Command) (T, error)

LoadTyped is the generic convenience: it allocates a fresh T, loads it, and returns it typed. T must be a pointer proto message type (e.g. *configv1.AppConfig). Usage:

cfg, err := config.LoadTyped[*configv1.AppConfig](cmd)

It mirrors the generated Load(cmd) (*Config, error) signature shape so a project can drop the generated loader and call this directly.

func RegisterFlags

func RegisterFlags(cmd *cobra.Command, msg proto.Message) error

RegisterFlags registers one cobra flag per config-bound field of msg that carries a non-empty flag annotation, using the annotated name, default, and description. Sensitive fields are skipped (env/Secret only). It is the cobra-facing form of RegisterFlagsFor and is generic over ANY config message — no per-field codegen.

It ALSO registers a persistent --config <path> flag (ConfigFlag) — always, for every config message. This is the first-class config-FILE layer's entry point: it is on, not dormant. Load resolves the file from this flag (or the FORGE_CONFIG env var) and unmarshals it as the layer between defaults and env. Registering it persistent means it is also visible to subcommands. The flag is registered idempotently so re-registering on the same command (or a parent that already has it) is safe.

func RegisterFlagsFor

func RegisterFlagsFor(flags *pflag.FlagSet, msg proto.Message) error

RegisterFlagsFor walks msg's fields and registers one cobra/pflag flag per field that carries a non-empty (forge.v1.config).flag. The flag's type matches the proto field kind (string/int32/int64/bool/float; duration messages register as a string flag — LoadInto parses "5s" → Duration), and its default is the proto option's DefaultValue.

It is the pflag-level primitive; the cobra-facing RegisterFlags(cmd, msg) in semantic.go wraps it. It recurses into nested config blocks.

Fields without a flag (typically secrets sourced only from env / Secret mounts) are intentionally skipped — defense-in-depth against shell-history / `ps` exposure of credentials.

func Validate

func Validate(msg proto.Message) error

Validate runs the cross-field and closed-set config invariants that cannot be expressed as per-field defaults, failing fast (before the listener binds) on the known misconfiguration classes. It is the annotation/TYPE-driven replacement for the deleted name-matched validators (CORS-wildcard / TLS-pair / log-format):

  • allowed_values: a string field carrying a closed value set is a string ENUM; a resolved value outside the set is rejected. (True proto enum fields need no check — protoreflect enforces their domain. The empty value is always allowed: an unset, non-required field.)
  • TLS keypair: the fields tagged role=TLS_CERT and role=TLS_KEY are both-or-neither. Exactly one set is an error (the server would silently serve plaintext).
  • CORS: a wildcard origin ("*") in the role=CORS_ORIGINS field combined with role=CORS_ALLOW_CREDENTIALS=true is spec-invalid and rejected.

Every check keys off the ANNOTATION, never the field name — renaming a field never silently drops its guard. Validate recurses into nested config blocks so a block can carry its own allowed_values fields. The cross-field TLS/CORS checks operate per message level (the role fields of the same message), which is where those pairs naturally live.

Types

type RuntimeMode

type RuntimeMode int

RuntimeMode is the typed runtime mode. The zero value is ModeProduction: a message with no role=MODE field (or one whose mode field is empty) always reports production — dev permissiveness is never the default.

const (
	// ModeProduction is the zero value: authz enforced, auth required.
	ModeProduction RuntimeMode = iota
	// ModeDevelopment enables local-dev permissiveness. Never set in
	// deployed environments.
	ModeDevelopment
)

func Mode

func Mode(msg proto.Message) RuntimeMode

Mode derives the runtime mode from msg's role=MODE field: "development"/"dev" (case-insensitive) → ModeDevelopment, anything else (including no role field) → ModeProduction. Deriving — rather than caching — means a hand-built message in tests can never disagree with its own mode value.

func (RuntimeMode) IsDev

func (m RuntimeMode) IsDev() bool

IsDev reports whether the mode is ModeDevelopment. It gates NON-SECURITY dev ergonomics only (permissive CORS, verbose errors, dev DB defaults). It MUST NOT gate auth — see DevAuthBypass.

Jump to

Keyboard shortcuts

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