config

package
v0.2.2 Latest Latest
Warning

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

Go to latest
Published: Oct 24, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package config loads the server configuration: one YAML file, decoded strictly, plus MYOWNPKI_* environment overrides (go-conventions.md "Configuration", PLAN §14).

Rules:

  • Unknown keys, a second YAML document and files over MaxFileSize are errors.
  • Unknown MYOWNPKI_* variables are errors too: a typo must not be ignored.
  • Dev mode is a command-line flag (serve --dev), never a config key.
  • No secrets: the unseal passphrase is never read from a file or variable.

Load returns a validated Config or an error that names every problem.

Index

Constants

View Source
const EnvConfigFile = EnvPrefix + "CONFIG"

EnvConfigFile names the config file when --config is not given.

View Source
const EnvPrefix = "MYOWNPKI_"

EnvPrefix starts every environment variable this package reads.

View Source
const MaxFileSize = 64 << 10

MaxFileSize limits the config file; a real one is a few hundred bytes.

Variables

View Source
var (
	LogLevels  = []string{"debug", "info", "warn", "error"}
	LogFormats = []string{"json", "text"}
)

Allowed values.

View Source
var ErrInvalid = errors.New("invalid configuration")

ErrInvalid is wrapped by every error about a malformed or inconsistent configuration.

Functions

func ACMEBaseURL added in v0.2.0

func ACMEBaseURL(s string) (string, error)

ACMEBaseURL checks acme.base_url and returns it without a trailing slash: https only (the proxy terminates TLS; RFC 8555 §6.1), a host, no user, query or fragment.

func ACMEHost added in v0.2.2

func ACMEHost(base string) string

ACMEHost is the host of acme.base_url in lower case: the name (or IP) in the certificate of the ACME listener with acme.tls_issuer.

func ACMEResolver added in v0.2.0

func ACMEResolver(s string) (string, error)

ACMEResolver checks acme.resolver: empty, an IP (port 53) or IP:port.

func DefaultPath

func DefaultPath(goos string, getenv func(string) string) string

DefaultPath is the config file used when neither --config nor MYOWNPKI_CONFIG is given: %ProgramData%\MyOwnPKI\config.yaml on Windows, /etc/myownpki/config.yaml elsewhere. getenv is os.Getenv in production.

func EnvNames

func EnvNames() []string

EnvNames returns the override variables, sorted.

func Load

func Load(path string, environ []string) (Config, Source, error)

Load reads the file at path, applies the environment and validates the result.

func ParseNetworks

func ParseNetworks(s string) ([]netip.Prefix, error)

ParseNetworks parses a comma-separated list of IPs and CIDRs (trusted proxies, the admin allowlist). A single IP becomes a /32 or /128. Zones and host bits in a CIDR are refused – a typo like 10.0.0.1/8 must not silently trust a whole network.

func ParseTLSNames

func ParseTLSNames(s string) ([]string, []netip.Addr, error)

ParseTLSNames splits admin.tls_names into DNS names and IPs. DNS names are LDH labels in lower case (a wildcard is not allowed: the bootstrap certificate names exactly the hosts admins use).

func PasskeyRPID

func PasskeyRPID(origin string) (string, error)

PasskeyRPID checks auth.passkey_origin and returns its host name, the WebAuthn RP ID ("" when passkeys are off). Browsers allow WebAuthn only in a secure context: https, or http on localhost.

Types

type ACME added in v0.2.0

type ACME struct {
	// Listen is IP:port of the ACME listener – never the public CRL port, so
	// nobody talks ACME in clear text. Without TLSIssuer it is for the reverse
	// proxy only; with it, for the clients (e.g. :443).
	Listen string `yaml:"listen"`
	// BaseURL is what clients use (the proxy's https URL, e.g.
	// https://pki.homelab.lan/acme); every URL the server hands out is built
	// from it. Empty: ACME is off.
	BaseURL string `yaml:"base_url"`
	// TrustedProxies may connect to Listen (others get 403), and only their
	// X-Forwarded-For is believed (IPs or CIDRs, comma-separated). Ignored
	// with TLSIssuer: then every client connects directly and the peer is
	// the client address.
	TrustedProxies string `yaml:"trusted_proxies"`
	// Resolver is the DNS server (IP or IP:port) for dns-01 and for resolving
	// http-01 names. Empty: the system resolver.
	Resolver string `yaml:"resolver"`
	// TLSIssuer names a CA of this instance: ACME runs with TLS on Listen,
	// with a certificate for the host of BaseURL that the server issues from
	// this CA itself. Empty: plain HTTP behind a reverse proxy.
	TLSIssuer string `yaml:"tls_issuer"`
}

ACME is the ACME server (PHASE2): by default plain HTTP on its own listener, only behind a reverse proxy that terminates TLS (owner Q1 2026-10-22); with TLSIssuer it speaks TLS itself (v0.2.2, owner 2026-10-24).

func (ACME) DirectTLS added in v0.2.2

func (a ACME) DirectTLS() bool

DirectTLS reports whether the ACME listener speaks TLS itself.

type Admin

type Admin struct {
	// Listen is IP:port; an empty IP means all interfaces.
	Listen string `yaml:"listen"`
	// TLSCertFile and TLSKeyFile name an operator-provided certificate. Both
	// empty: a self-signed bootstrap certificate is created (PLAN §5).
	TLSCertFile string `yaml:"tls_cert_file"`
	TLSKeyFile  string `yaml:"tls_key_file"`
	// TLSNames are further DNS names or IPs (comma-separated) for the
	// bootstrap certificate, besides the host name, the listen IP and
	// loopback – the names admins type into the browser. With TLSIssuer they
	// are exactly the names of the issued certificate.
	TLSNames string `yaml:"tls_names"`
	// TLSIssuer names a CA of this instance (v0.2.2): the server issues the
	// listener's certificate from it itself, while unsealed, and renews it.
	// Empty: the operator certificate or the bootstrap certificate.
	TLSIssuer string `yaml:"tls_issuer"`
	// AllowedNetworks limits who may connect (IPs or CIDRs, comma-separated);
	// empty: everybody. Checked against the direct peer before TLS (ADR-08).
	AllowedNetworks string `yaml:"allowed_networks"`
}

Admin is the admin listener: web UI and REST API (ADR-08).

type Auth

type Auth struct {
	// KeyFile holds the key that encrypts the TOTP secrets and keys the
	// recovery code hashes. Empty: <data_dir>/auth.key. It may live outside
	// the data directory (Docker secret, systemd credential): then a copy of
	// the databases alone holds no usable TOTP secret.
	KeyFile string `yaml:"key_file"`
	// TrustedProxies lists reverse proxies (IPs or CIDRs, comma-separated)
	// whose X-Forwarded-For header is believed. Empty: the direct peer is
	// the client – the safe default.
	TrustedProxies string `yaml:"trusted_proxies"`
	// PasskeyOrigin is the address users open the admin UI with, e.g.
	// https://pki.homelab.lan:9443 (PHASE1 step 17). Passkeys are bound to its
	// host name (the WebAuthn RP ID). Empty: no passkeys, TOTP only.
	PasskeyOrigin string `yaml:"passkey_origin"`
}

Auth configures sign-in (PHASE1 step 10).

type Config

type Config struct {
	// DataDir holds system.db and the tenant directories. Absolute path.
	DataDir string `yaml:"data_dir"`
	Log     Log    `yaml:"log"`
	Admin   Admin  `yaml:"admin"`
	Public  Public `yaml:"public"`
	Auth    Auth   `yaml:"auth"`
	ACME    ACME   `yaml:"acme"`
}

Config is the server configuration. Field order is the order of the example file.

func Default

func Default() Config

Default returns the configuration used for every key the file leaves out. The admin listener binds to loopback only: remote administration is a deliberate decision of the operator.

func Parse

func Parse(name string, data []byte) (Config, error)

Parse decodes a config file over the defaults. name is used in messages only.

func (*Config) ApplyEnv

func (c *Config) ApplyEnv(environ []string) ([]string, error)

ApplyEnv applies MYOWNPKI_* overrides from environ (os.Environ format) and returns the names it applied, sorted. An unknown MYOWNPKI_* variable is an error: a typo would otherwise be ignored silently. An empty value is applied as well, so MYOWNPKI_PUBLIC_LISTEN= disables the public listener.

func (Config) AuthKeyFile

func (c Config) AuthKeyFile() string

AuthKeyFile returns the path of the auth key: auth.key_file or <data_dir>/auth.key.

func (Config) Validate

func (c Config) Validate() error

Validate checks every value and returns all problems at once.

type Log

type Log struct {
	Level  string `yaml:"level"`  // debug, info, warn, error
	Format string `yaml:"format"` // json (production) or text
}

Log configures the process log (not the audit log).

type Public

type Public struct {
	// Listen is IP:port; empty disables the listener.
	Listen string `yaml:"listen"`
}

Public is the public listener: CRL now, OCSP, AIA and ACME later (ADR-08).

type Source

type Source struct {
	File string   // the config file that was read
	Env  []string // MYOWNPKI_* variables that overrode a value, sorted
}

Source describes where the configuration came from, for `config check`.

Jump to

Keyboard shortcuts

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