config

package
v0.7.5 Latest Latest
Warning

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

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

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func SaveAgentConfig

func SaveAgentConfig(path string, cfg *AgentConfig) error

SaveAgentConfig writes cfg to path atomically (tmp + fsync + rename) with mode 0600. The parent directory is created with mode 0755 if missing. The server URL is validated with the same rules as LoadAgentConfig so a config that would be refused at the next startup is never written.

func SaveServerConfig

func SaveServerConfig(path string, cfg *ServerConfig) error

SaveServerConfig writes the config to path atomically (temp file + rename). Existing comments and unknown fields in the file are not preserved.

func ValidateAgentServerURL added in v0.4.0

func ValidateAgentServerURL(serverURL string, allowInsecure bool) error

ValidateAgentServerURL guards the agent's management-server URL. The URL must be http/https with a host. A plaintext http:// URL is accepted only for a loopback host (local testing, an on-host TLS-terminating proxy) unless allowInsecure opts out — everywhere else the enrollment token and the host's rendered Nebula config would transit a real network in cleartext. The CLI and the server already carry the equivalent guards (#219, #179); this covers the agent.

Exposed as a function rather than only a load-time check so the enroll path can validate the --server flag before the token is sent, when no config file exists yet.

func ValidateWebhookURL added in v0.6.0

func ValidateWebhookURL(field, rawURL string, allowPrivate bool) error

ValidateWebhookURL guards a webhook URL against SSRF (#188): the URL must be http/https with a host, and (unless allowPrivate) must not target a private/loopback/link-local address. field names the offending config key in errors so both alerts.webhook_url and webhooks.url can reuse it. DNS names are not resolved here — this is the config-load layer; the delivery-time layer (post-resolution dialer guard + per-redirect-hop re-check) lives in the alerts WebhookSink and the webhook.Dispatcher.

Types

type AgentConfig

type AgentConfig struct {
	ServerURL        string        `yaml:"server_url"`
	DataDir          string        `yaml:"data_dir"`
	SigningKeyPath   string        `yaml:"signing_key_path"`
	PollInterval     time.Duration `yaml:"poll_interval"`
	NebulaConfigPath string        `yaml:"nebula_config_path"`
	NebulaPIDFile    string        `yaml:"nebula_pid_file"`

	// AllowInsecureHTTP opts out of the https-required guard on server_url.
	// Without it a plaintext http:// URL is only accepted for loopback
	// hosts — over any other network the enrollment token, certificates,
	// and the Nebula config the agent installs would transit in cleartext,
	// where an on-path attacker can steal the token or inject a malicious
	// config. Mirrors the server's allow_insecure_http (#179).
	AllowInsecureHTTP bool `yaml:"allow_insecure_http,omitempty"`
}

func DefaultAgentConfig

func DefaultAgentConfig() *AgentConfig

DefaultAgentConfig returns a config populated with the defaults the agent applies when fields are missing.

SigningKeyPath defaults to /etc/nebula-agent/host.signing.key — agent's Ed25519 poll-signature key lives next to agent.yml, deliberately *not* in /etc/nebula where Nebula's own secrets live (ADR 0004 + #88).

func LoadAgentConfig

func LoadAgentConfig(path string) (*AgentConfig, error)

type AlertsConfig

type AlertsConfig struct {
	Enabled           bool   `yaml:"enabled,omitempty"`
	Interval          string `yaml:"interval,omitempty"`
	Threshold         string `yaml:"threshold,omitempty"`
	WebhookURL        string `yaml:"webhook_url,omitempty"`
	WebhookHMACSecret string `yaml:"webhook_hmac_secret,omitempty"`

	// AllowPrivateWebhook permits webhook_url to point at a loopback/private/
	// link-local address. Default false rejects such targets at startup as an
	// SSRF guard (#188); set true for an intentional internal sink (e.g. a
	// co-located Alertmanager).
	AllowPrivateWebhook bool `yaml:"allow_private_webhook,omitempty"`
}

AlertsConfig drives the periodic cert-expiry scanner and its sinks. Threshold and Interval are parsed as Go durations (e.g. "72h", "5m").

func (AlertsConfig) IntervalDuration

func (a AlertsConfig) IntervalDuration() time.Duration

IntervalDuration returns Interval as a time.Duration. Falls back to 5m when unset or unparseable, matching the documented default.

func (AlertsConfig) ThresholdDuration

func (a AlertsConfig) ThresholdDuration() time.Duration

ThresholdDuration returns Threshold as a time.Duration. Falls back to 72h (three days) when unset or unparseable, matching the documented default.

type CAAutoRotateConfig

type CAAutoRotateConfig struct {
	Enabled   bool          `yaml:"enabled,omitempty"`
	Interval  time.Duration `yaml:"interval,omitempty"`
	Threshold float64       `yaml:"threshold,omitempty"`
}

CAAutoRotateConfig configures the CA auto-rotation scanner: interval between scans, and threshold (as fraction of total lifetime) to trigger rotation. Defaults: Interval=6h, Threshold=0.20 (applied at runtime in the scanner).

type MetricsConfig

type MetricsConfig struct {
	// Prometheus is a pointer so an unset value (yaml omitted) is treated
	// as the default (true). A user setting `prometheus: false` cleanly
	// disables the exporter.
	Prometheus *bool `yaml:"prometheus,omitempty"`

	// RequireAuth gates the /metrics endpoint behind the same bearer auth as
	// the API (#187). It is a pointer so an unset value (yaml omitted) takes
	// the default (true, #262): the metric labels expose host/network/CA IDs
	// and operational counters, so unauthenticated scraping is opt-in. Set
	// `require_auth: false` to allow it on a trusted network.
	RequireAuth *bool `yaml:"require_auth,omitempty"`
}

MetricsConfig toggles the Prometheus exporter and whether it requires auth.

func (MetricsConfig) PrometheusEnabled

func (m MetricsConfig) PrometheusEnabled() bool

PrometheusEnabled returns whether the Prometheus exporter should be served. Defaults to true when unset.

func (MetricsConfig) RequireAuthEnabled added in v0.7.0

func (m MetricsConfig) RequireAuthEnabled() bool

RequireAuthEnabled returns whether /metrics must be bearer-authenticated. Defaults to true when unset (#262); set `require_auth: false` to opt into unauthenticated scraping on a trusted network.

type OIDCConfig

type OIDCConfig struct {
	Enabled       bool     `yaml:"enabled"`
	Issuer        string   `yaml:"issuer"`
	ClientID      string   `yaml:"client_id"`
	ClientSecret  string   `yaml:"client_secret"`
	RedirectURL   string   `yaml:"redirect_url"`
	Scopes        []string `yaml:"scopes,omitempty"`
	UsernameClaim string   `yaml:"username_claim,omitempty"` // default "preferred_username"
	NameClaim     string   `yaml:"name_claim,omitempty"`     // default "name"
	GroupsClaim   string   `yaml:"groups_claim,omitempty"`   // default "groups"
	AllowedGroups []string `yaml:"allowed_groups,omitempty"`
	AllowedEmails []string `yaml:"allowed_emails,omitempty"`
	DefaultRole   string   `yaml:"default_role,omitempty"`

	// RequireEmailVerified gates the post-callback email_verified claim
	// check. Pointer-bool to distinguish unset (default true: the IdP
	// must assert email_verified before the address counts toward
	// AllowedEmails) from an explicit `false` opt-out. The explicit
	// opt-out is the escape hatch for legacy IdPs that omit the claim
	// or send it in a shape HandleCallback can't decode (numeric,
	// nested object, etc). emailVerifiedRequired() resolves nil → true.
	RequireEmailVerified *bool `yaml:"require_email_verified,omitempty"`

	// TLSCACert optionally pins the IdP's TLS trust to a PEM CA bundle at this
	// path (#264). When set, OIDC discovery, JWKS fetch, and token exchange use
	// a dedicated HTTP client whose RootCAs is this bundle, so a CA compromise
	// in the system trust store cannot MITM the IdP. Empty = use the system
	// trust store (default). The system store is untouched for every other
	// connection.
	TLSCACert string `yaml:"tls_ca_cert,omitempty"`
}

OIDCConfig configures an OpenID Connect identity provider for operator login. If nil or Enabled=false, OIDC login is not offered.

func (*OIDCConfig) EmailVerifiedRequired

func (o *OIDCConfig) EmailVerifiedRequired() bool

EmailVerifiedRequired reports whether HandleCallback must enforce the email_verified claim. Defaults to true when RequireEmailVerified is unset.

func (*OIDCConfig) Validate

func (o *OIDCConfig) Validate() error

Validate refuses configurations that would silently auto-provision the first OIDC user as admin. Either constrain who can log in (allowed_groups or allowed_emails), or auto-provision as a lower-privileged role (default_role != "admin"). Setting default_role: admin with empty allowlists is permitted only as a deliberate two-field opt-in to "anyone-who-can-log-in-is-admin".

type PasswordConfig

type PasswordConfig struct {
	MinLength      *int  `yaml:"min_length,omitempty"`
	RequireClasses *int  `yaml:"require_classes,omitempty"`
	BlockCommon    *bool `yaml:"block_common,omitempty"`
	BlockUsername  *bool `yaml:"block_username,omitempty"`
}

PasswordConfig overrides the password policy defaults.

type RateLimitConfig

type RateLimitConfig struct {
	// Enabled is a pointer so an absent YAML block defaults to "true"
	// (issue #52 requires on-by-default) while still allowing a
	// `rate_limit: { enabled: false }` to disable it.
	Enabled          *bool                           `yaml:"enabled,omitempty"`
	TrustProxyHeader bool                            `yaml:"trust_proxy_header,omitempty"`
	Groups           map[string]RateLimitGroupConfig `yaml:"groups,omitempty"`
}

RateLimitConfig drives the rate-limit middleware. Enabled defaults to true; turn it off in trusted-network deployments by setting `rate_limit: { enabled: false }`. Set `trust_proxy_header: true` when running behind a reverse proxy that adds X-Forwarded-For.

func (RateLimitConfig) IsEnabled

func (c RateLimitConfig) IsEnabled() bool

IsEnabled returns whether the limiter should run. Default: true.

type RateLimitGroupConfig

type RateLimitGroupConfig struct {
	Rate  float64 `yaml:"rate"`
	Burst int     `yaml:"burst"`
}

RateLimitGroupConfig is the per-group rate/burst pair.

type ServerConfig

type ServerConfig struct {
	Listen     string      `yaml:"listen"`
	DataDir    string      `yaml:"data_dir"`
	DBPath     string      `yaml:"db_path"`
	UIPassword string      `yaml:"ui_password,omitempty"`
	LogLevel   string      `yaml:"log_level"`
	TLSCert    string      `yaml:"tls_cert,omitempty"`
	TLSKey     string      `yaml:"tls_key,omitempty"`
	OIDC       *OIDCConfig `yaml:"oidc,omitempty"`

	// AllowInsecureHTTP opts out of the plaintext-HTTP guard (#179). Without
	// TLS, the server only binds a loopback address (safe behind a local
	// reverse proxy); binding a routable address in cleartext is refused
	// unless this is set true (or the --insecure-http flag is passed). Keep
	// it false in production — credentials would otherwise transit in the clear.
	AllowInsecureHTTP bool `yaml:"allow_insecure_http,omitempty"`

	// MasterKey is a base64-encoded 32-byte AES-256 key used to wrap
	// per-CA DEKs in the cas table. May be supplied via the
	// NEBULA_MGMT_MASTER_KEY env var instead.
	MasterKey string `yaml:"master_key,omitempty"`

	// AllowSelfRegistration controls whether unauthenticated visitors can
	// create their own operator account through /ui/register. Defaults to
	// false so closed deployments stay closed by default; administrators
	// can still create operators manually via the existing
	// `nebula-mgmt user create` CLI or `POST /api/v1/operators` API.
	AllowSelfRegistration bool `yaml:"allow_self_registration,omitempty"`

	// Metrics configures the optional /metrics Prometheus exporter. Default
	// is "enabled" so out-of-the-box installs can be scraped immediately;
	// air-gapped deployments can set Prometheus=false to drop the route.
	Metrics MetricsConfig `yaml:"metrics,omitempty"`

	// Alerts configures the cert-expiry alerter (see issue #41). Disabled
	// by default — operators must opt in by setting Enabled=true.
	Alerts AlertsConfig `yaml:"alerts,omitempty"`

	// Webhooks configures outbound lifecycle-event delivery (#256). Disabled
	// by default — operators opt in by setting Enabled=true and a URL.
	Webhooks WebhooksConfig `yaml:"webhooks,omitempty"`

	// RateLimit configures the per-IP, per-route-group token-bucket
	// limiter that fronts the Web UI and API (see issue #52). Enabled
	// by default so login + enrolment endpoints are protected from
	// online brute-force out of the box.
	RateLimit RateLimitConfig `yaml:"rate_limit,omitempty"`

	// Password configures the password policy applied to every server-
	// side password-setting path (see issue #48). All knobs are
	// optional: unset values fall back to the production defaults
	// (10-char min, 3-of-4 classes, common-pw + username block on).
	Password PasswordConfig `yaml:"password,omitempty"`

	// EnforceTOTP toggles admin-enforced 2FA (issue #49). When set, the
	// value is written into the server_settings table on startup so it
	// stays in effect across restarts. A nil pointer (unset YAML) leaves
	// the DB value alone — the future Settings UI (#47) will edit the
	// same row at runtime.
	EnforceTOTP *bool `yaml:"enforce_2fa,omitempty"`

	// EnrollmentTokenTTL is the default lifetime applied to freshly minted
	// enrollment tokens (ADR 0004 / #75). Per-network overrides live in
	// the `network_config` table under the `enrollment_token_ttl` key.
	// Empty / unparseable value falls back to 24h.
	EnrollmentTokenTTL string `yaml:"enrollment_token_ttl,omitempty"`

	// CAAutoRotate configures the periodic CA auto-rotation scanner (issue #110).
	// Disabled by default — operators must opt in by setting Enabled=true.
	CAAutoRotate CAAutoRotateConfig `yaml:"ca_auto_rotate,omitempty"`

	// CookieSecure controls the `Secure` attribute on session and OIDC
	// state cookies (GHSA-rqfj-vv8r-xhqc). When unset, the effective
	// value is inferred from the TLS configuration: true if both
	// tls_cert and tls_key are populated, false otherwise. Operators
	// terminating TLS at a reverse proxy must set this to true
	// explicitly — `rate_limit.trust_proxy_header` is not a reliable
	// signal that the proxy speaks TLS to clients.
	CookieSecure *bool `yaml:"cookie_secure,omitempty"`
	// contains filtered or unexported fields
}

func LoadServerConfig

func LoadServerConfig(path string) (*ServerConfig, error)

func (ServerConfig) CookieSecureResolved

func (c ServerConfig) CookieSecureResolved() bool

CookieSecureResolved returns the effective Secure-cookie flag for this configuration. Explicit value wins; if unset, infer from the presence of TLS material on the server itself.

func (ServerConfig) EnrollmentTokenTTLDuration

func (c ServerConfig) EnrollmentTokenTTLDuration() time.Duration

EnrollmentTokenTTLDuration returns the configured default token TTL parsed as a Go duration. Falls back to 24h when unset or invalid so the server always has a sane default.

func (*ServerConfig) HasLegacyAPIKey

func (c *ServerConfig) HasLegacyAPIKey() bool

HasLegacyAPIKey reports whether the YAML config contained a top-level `api_key:` key. The field was removed per #127 in favor of one-time stdout output and recovery via `nebula-mgmt ops mint-admin-key`.

func (*ServerConfig) RequireSecureBind added in v0.3.7

func (c *ServerConfig) RequireSecureBind() error

RequireSecureBind enforces the plaintext-HTTP guard (#179). It returns an error when the server would serve cleartext on a routable address:

  • TLS configured (tls_cert+tls_key) → always allowed.
  • No TLS, AllowInsecureHTTP set → allowed (explicit opt-out).
  • No TLS, Listen bound to a loopback address → allowed (proxy-friendly).
  • No TLS, Listen bound to anything else → refused.

Called at startup after the --insecure-http flag has been folded into AllowInsecureHTTP, so the CLI flag and the config field share one code path.

type WebhooksConfig added in v0.6.0

type WebhooksConfig struct {
	Enabled      bool     `yaml:"enabled,omitempty"`
	URL          string   `yaml:"url,omitempty"`
	HMACSecret   string   `yaml:"hmac_secret,omitempty"`
	AllowPrivate bool     `yaml:"allow_private,omitempty"`
	Events       []string `yaml:"events,omitempty"`
}

WebhooksConfig configures the outbound lifecycle-event webhook (#256). The dispatcher signs each delivery (HMACSecret), filters by event type (Events; empty means all), and SSRF-guards the target unless AllowPrivate is set.

Jump to

Keyboard shortcuts

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