Documentation
¶
Overview ¶
Package config loads and validates /etc/mooring/config.yaml — the root of trust (plan §5.1). Everything here is fail-closed: any precondition violation returns an error and the binary refuses to boot. No web route ever reads or writes this file; it is edited only over SSH.
Index ¶
- Constants
- func DecodeKey(s string) ([]byte, error)
- type AdminConfig
- type AlertingConfig
- type AuthConfig
- type BackupConfig
- type BackupS3
- type Config
- func (c *Config) AdminEdgeListen() string
- func (c *Config) AdminExposed() bool
- func (c *Config) AdminHostnameResolved() string
- func (c *Config) Allowlist() []netip.Prefix
- func (c *Config) BackupHelperImage() string
- func (c *Config) BackupRetention() int
- func (c *Config) BackupSchedule() time.Duration
- func (c *Config) BackupsOn() bool
- func (c *Config) BaseDomainByName(name string) (EdgeBaseDomain, bool)
- func (c *Config) EdgeCAByName(name string) (EdgeCA, bool)
- func (c *Config) HasBaseDomain(name string) bool
- func (c *Config) HasEdgeCA(name string) bool
- func (c *Config) IsProtectedProject(project string) bool
- func (c *Config) NamespaceForHost(host string) (string, bool)
- func (c Config) String() string
- func (c *Config) TrustedProxyPrefixes() []netip.Prefix
- func (c *Config) Users() []User
- func (c *Config) Validate() error
- type CookieConfig
- type DockerConfig
- type Duration
- type EdgeBaseDomain
- type EdgeCA
- type EdgeConfig
- type EdgeDNS01
- type EdgeMode
- type EditorBlock
- type EditorMode
- type GitConfig
- type GitHubConfig
- type MonitorConfig
- type RetentionConfig
- type Role
- type ServerConfig
- type ServerFileRoot
- type SessionConfig
- type SetupConfig
- type User
- type UserConfig
Constants ¶
const DefaultPath = "/etc/mooring/config.yaml"
DefaultPath is where the root-of-trust config lives in production.
const DevInsecurePermsEnv = "MOORING_DEV_INSECURE_PERMS"
DevInsecurePermsEnv, when set to a truthy value, relaxes the config-file ownership/permission enforcement for LOCAL DEVELOPMENT only. It is read from the environment (never from the config file itself) so the file can never disable its own root-of-trust checks (review #6).
Variables ¶
This section is empty.
Functions ¶
Types ¶
type AdminConfig ¶
type AdminConfig struct {
Hostname string `yaml:"hostname"`
Listen string `yaml:"listen"`
// Subdomain is the shorthand for exposing the dashboard through the managed edge at
// <subdomain>.<edge.base_domain> (e.g. admin → admin.mooring.example.com). Set EITHER
// this (with edge.base_domain) or the full Hostname above. Empty = admin stays
// loopback-only (the default; reach it over an SSH tunnel).
Subdomain string `yaml:"subdomain"`
// EdgeListen is a SECOND, dedicated loopback listener the managed edge proxies the
// admin vhost to (default 127.0.0.1:9001). It is separate from bind_addr (the
// SSH-tunnel listener) precisely so the two access paths carry different trust: the
// edge listener REQUIRES an X-Forwarded-For from the edge and re-gates the REAL client
// against ip_allowlist, while the tunnel keeps peer-allowlisting. Loopback-only.
EdgeListen string `yaml:"edge_listen"`
}
AdminConfig optionally fronts the admin UI through the edge and points at the Caddy admin endpoint (plan §6.1 SBD-1/SBD-2).
type AlertingConfig ¶
type AlertingConfig struct {
Enabled bool `yaml:"enabled"`
EvalInterval Duration `yaml:"eval_interval"` // evaluator tick
NotifyMinInterval Duration `yaml:"notify_min_interval"` // global rate limit between sends
QuietStartHour int `yaml:"quiet_start_hour"` // [0..23], -1 disables (suppresses WARNING; CRITICAL always pages)
QuietEndHour int `yaml:"quiet_end_hour"`
DeadMansURL string `yaml:"dead_mans_url"` // outbound heartbeat to an external cron-monitor
DeadMansInterval Duration `yaml:"dead_mans_interval"`
}
AlertingConfig is the Tier-1 tuning for the read-and-notify alert engine (plan §8). Channels + rules are operator-managed in the DB; this only tunes the engine. Off by default (no engine goroutines run unless enabled).
type AuthConfig ¶
type AuthConfig struct {
Username string `yaml:"username"`
PasswordHash string `yaml:"password_hash"`
TOTPSecret string `yaml:"totp_secret"`
}
AuthConfig holds the PRIMARY operator's credentials — always an owner. Additional operators go in the top-level `users:` list (see UserConfig). With no `users:`, Mooring is single-user exactly as before.
type BackupConfig ¶ added in v0.6.0
type BackupConfig struct {
Enabled bool `yaml:"enabled"`
Schedule Duration `yaml:"schedule"` // default 24h; clamped to a 1h floor
Retention int `yaml:"retention"` // keep N most-recent per target; default 7
HelperImage string `yaml:"helper_image"` // image with `tar` for volume snapshots; default below
S3 *BackupS3 `yaml:"s3,omitempty"` // optional off-box destination
}
BackupConfig configures scheduled, encrypted app-data backups (OPT-IN, default off). When Enabled, the scheduler snapshots every app's data volumes on Schedule (encrypted with the master key), keeps Retention snapshots per target, and — if S3 is set — also uploads each snapshot off-box. Credentials live HERE (operator config, the root of trust), never in an app repo, so a repo can never name an exfil bucket or hold keys.
type BackupS3 ¶ added in v0.6.0
type BackupS3 struct {
Bucket string `yaml:"bucket"`
Endpoint string `yaml:"endpoint"` // host[:port], e.g. s3.us-east-1.amazonaws.com
Region string `yaml:"region"`
AccessKeyID string `yaml:"access_key_id"`
SecretAccessKey string `yaml:"secret_access_key"`
Prefix string `yaml:"prefix"` // optional key prefix, e.g. "mooring/"
PathStyle *bool `yaml:"path_style"` // default true (S3-compatible endpoints)
Insecure bool `yaml:"insecure"` // allow http:// (private MinIO); default https
}
BackupS3 is the optional off-box object-store destination for backups (S3/MinIO/R2/B2).
type Config ¶
type Config struct {
BindAddr string `yaml:"bind_addr"`
EncryptionKey string `yaml:"encryption_key"`
EncryptionKeyPrevious string `yaml:"encryption_key_previous"`
IPAllowlist []string `yaml:"ip_allowlist"`
TrustProxy bool `yaml:"trust_proxy"`
TrustedProxies []string `yaml:"trusted_proxies"`
Auth AuthConfig `yaml:"auth"`
ExtraUsers []UserConfig `yaml:"users"` // additional operators beyond the auth owner (RBAC)
Edge EdgeConfig `yaml:"edge"`
Admin AdminConfig `yaml:"admin"`
Session SessionConfig `yaml:"session"`
Cookie CookieConfig `yaml:"cookie"`
Docker DockerConfig `yaml:"docker"`
Monitor MonitorConfig `yaml:"monitor"`
Git GitConfig `yaml:"git"`
GitHub GitHubConfig `yaml:"github"`
CaddyEditor EditorBlock `yaml:"caddy_editor"`
ComposeValidation EditorBlock `yaml:"compose_validation"`
Setup SetupConfig `yaml:"setup"`
Retention RetentionConfig `yaml:"retention"`
Alerting AlertingConfig `yaml:"alerting"`
Server ServerConfig `yaml:"server"`
Backups BackupConfig `yaml:"backups"`
DataDir string `yaml:"data_dir"`
// ProtectedProjects are Compose projects Mooring must never start/stop/
// redeploy (the socket-proxy, and later the edge) — plan §3 protected set.
ProtectedProjects []string `yaml:"protected_projects"`
// contains filtered or unexported fields
}
Config is the typed root-of-trust document. Secret-bearing fields are kept as plain strings here (the file itself is 0600 root:root) but are never echoed: String() is overridden to redact them.
func Load ¶
Load reads, parses, and fully validates the config at path. It is the only entry point; a returned error means refuse-to-boot.
func Parse ¶
Parse decodes and validates config bytes (used by Load and by tests). Unknown keys are a hard error so a typo or smuggled key cannot slip through.
func (*Config) AdminEdgeListen ¶ added in v0.5.1
AdminEdgeListen is the second loopback listener the edge dials for the admin vhost.
func (*Config) AdminExposed ¶ added in v0.5.1
AdminExposed reports whether the dashboard is fronted publicly by the managed edge.
func (*Config) AdminHostnameResolved ¶ added in v0.5.1
AdminHostnameResolved returns the public hostname the dashboard is exposed at through the managed edge, or "" when it stays loopback-only. An explicit admin.hostname wins; otherwise admin.subdomain is expanded against edge.base_domain.
func (*Config) BackupHelperImage ¶ added in v0.6.0
BackupHelperImage is the image (with tar) used for volume snapshots/restores.
func (*Config) BackupRetention ¶ added in v0.6.0
BackupRetention is how many snapshots to keep per target (default 7, min 1).
func (*Config) BackupSchedule ¶ added in v0.6.0
BackupSchedule is the interval between backup runs (default 24h, 1h floor).
func (*Config) BackupsOn ¶ added in v0.6.0
BackupsOn reports whether scheduled app-data backups are enabled (default off).
func (*Config) BaseDomainByName ¶ added in v0.9.0
func (c *Config) BaseDomainByName(name string) (EdgeBaseDomain, bool)
BaseDomainByName resolves a subdomain-namespace reference to its apex + optional wildcard dns01. The empty name "" means the DEFAULT namespace — the scalar edge.base_domain (with the scalar edge.dns01). A non-empty name looks up edge.base_domains. This is the single resolver every subdomain-expansion site uses, so named and default namespaces behave identically. ok=false means the namespace isn't configured (unknown name, or "" with no base_domain set).
func (*Config) EdgeCAByName ¶
EdgeCAByName returns the configured CA with the given name.
func (*Config) HasBaseDomain ¶ added in v0.9.0
HasBaseDomain reports whether a base_domain namespace exists (a named one, or the default when name is "").
func (*Config) IsProtectedProject ¶
IsProtectedProject reports whether a compose project is in the protected set.
func (*Config) NamespaceForHost ¶ added in v0.9.0
NamespaceForHost returns the NAME of the declared namespace whose apex `host` is a single-label subdomain of ("" = the default base_domain), and ok=false if host is under no declared apex. Named namespaces are checked before the default; apexes are validated disjoint, so at most one matches. Used to recover which namespace an already-expanded (literal) hostname belongs to.
func (Config) String ¶
String redacts the secret-bearing fields so a Config can never be logged in the clear (plan §5.5 / §15 lint).
func (*Config) TrustedProxyPrefixes ¶
TrustedProxyPrefixes returns the parsed trusted-proxy prefixes.
type CookieConfig ¶
type CookieConfig struct {
Prefix string `yaml:"prefix"` // "__Host-" (default) or "__Secure-"
BasePath string `yaml:"base_path"` // required iff prefix is __Secure-
}
CookieConfig selects the session cookie prefix model (plan §5.3). __Host- mandates Path=/ and no base path; __Secure- pairs with a base_path.
type DockerConfig ¶
type DockerConfig struct {
ProxyAddr string `yaml:"proxy_addr"`
ExternalProxy bool `yaml:"external_proxy"`
}
DockerConfig points at the read-only docker-socket-proxy (plan §3). Mooring NEVER talks to the raw socket; ProxyAddr must be a loopback endpoint.
By default Mooring MANAGES this proxy itself: at boot it brings up the embedded, Mooring-owned read-only proxy compose so the operator never runs a docker command (they only ever write mooring.yaml). Set external_proxy: true if you run your own proxy/endpoint at proxy_addr and want Mooring to leave it alone.
type EdgeBaseDomain ¶ added in v0.9.0
type EdgeBaseDomain struct {
Name string `yaml:"name"` // [a-z][a-z0-9-]{0,30}; referenced as `base_domain: <name>`
Domain string `yaml:"domain"` // the apex FQDN, e.g. staging.example.com
DNS01 *EdgeDNS01 `yaml:"dns01,omitempty"`
}
EdgeBaseDomain is a NAMED subdomain namespace — an additional apex the operator declares so colocated apps can each use the `subdomain:` shorthand under their own root. An app (or a single route/cert_binding) opts in by Name; unset = the default scalar edge.base_domain. Declared ONLY in the root-of-trust config (an app repo must never introduce an apex). Domain must be a bare FQDN (no wildcards). DNS01, when set, issues a *.<Domain> wildcard cert via ACME DNS-01 for THIS namespace (Phase 2 wires the issuance).
type EdgeCA ¶
type EdgeCA struct {
Name string `yaml:"name"` // [a-z][a-z0-9-]{0,30}; referenced as `ca: <name>`
DirectoryURL string `yaml:"directory_url"` // the ACME directory URL (https)
Email string `yaml:"email"` // optional ACME contact; falls back to acme_email
TrustedRoot string `yaml:"trusted_root"` // optional PEM file Caddy trusts for the CA's OWN https
}
EdgeCA is an additional ACME issuer — a private/internal CA (e.g. step-ca). A mooring.yaml edge route or cert binding opts into it by Name; everything else keeps using the default edge.acme_ca. Defined ONLY here in the root-of-trust config (an app repo must never be able to introduce a trusted CA).
type EdgeConfig ¶
type EdgeConfig struct {
Mode EdgeMode `yaml:"mode"`
ACMEEmail string `yaml:"acme_email"`
ACMECA string `yaml:"acme_ca"`
CAs []EdgeCA `yaml:"cas"` // extra named issuers (private CAs) routes/cert-bindings can opt into by name
// BaseDomain is the namespace root for the subdomain shorthand: a route or cert_binding
// that sets `subdomain: mqtt` (instead of a full hostname) is expanded to
// mqtt.<base_domain> at deploy time. The operator points a SINGLE wildcard DNS record
// (*.<base_domain> → this server) and every declared subdomain resolves. "" disables the
// shorthand (full hostnames still work). Must be a FQDN, no wildcards.
BaseDomain string `yaml:"base_domain"`
// DNS01, when set, issues a single *.<base_domain> WILDCARD certificate via ACME DNS-01
// (instead of a per-subdomain HTTP-01 cert each) — one cert for every subdomain, no
// per-name rate limits, and it works for names that aren't HTTP-reachable. It REQUIRES a
// caddy binary with your DNS provider's module compiled in (vanilla Caddy has none —
// build one with xcaddy). Optional; leave unset to keep per-subdomain HTTP-01.
DNS01 *EdgeDNS01 `yaml:"dns01,omitempty"`
// BaseDomains are ADDITIONAL, named subdomain namespaces on top of the default base_domain
// above. Colocated apps (e.g. prod + staging on one box) each opt into one BY NAME so both
// can keep the `subdomain:` shorthand under their own apex without a route collision. The
// scalar base_domain stays the DEFAULT (unnamed) namespace — this is purely additive, and
// mirrors how the scalar acme_ca coexists with the named `cas` list. Declared ONLY here in
// the root-of-trust config; an app references a name and can never introduce an apex.
BaseDomains []EdgeBaseDomain `yaml:"base_domains,omitempty"`
ApplyProbeWindow Duration `yaml:"apply_probe_window"`
L4Enabled bool `yaml:"l4_enabled"` // own a managed L4 (TCP/UDP) load balancer (nginx-stream)
L4NginxDigest string `yaml:"l4_nginx_digest"` // pinned SHA-256 of the nginx binary (optional)
}
EdgeConfig configures the managed edge (plan §3.1, §6).
type EdgeDNS01 ¶ added in v0.5.2
EdgeDNS01 configures the optional *.<base_domain> wildcard cert via ACME DNS-01. Provider is the Caddy DNS module name (e.g. "cloudflare", "digitalocean", "route53"); APIToken is the provider credential (secret-bearing — redacted, and never leaves this box except to the DNS provider via the caddy child). The module must be compiled into the caddy binary.
type EdgeMode ¶
type EdgeMode string
EdgeMode is the managed/external switch (plan §3.1). Default managed.
type EditorBlock ¶
type EditorBlock struct {
Mode EditorMode `yaml:"mode"`
}
EditorBlock is the strict|review knob shared by the Caddy editor and the compose importer.
type EditorMode ¶
type EditorMode string
EditorMode gates how far the Caddy editor / compose importer may soften lints.
const ( EditorStrict EditorMode = "strict" EditorReview EditorMode = "review" )
type GitConfig ¶
type GitConfig struct {
PollInterval *Duration `yaml:"poll_interval"`
}
GitConfig tunes the connected-repo auto-fetch poller. So a repo connected in the dashboard "just works" with no webhook setup, Mooring fetches every connected repo on this cadence — READ-PLANE ONLY: the poller never deploys, it just surfaces an "update available" the operator then deploys with a click. (Push-to-deploy stays an explicit opt-in via the webhook + auto_deploy, never the background poller.)
PollInterval is a pointer so an omitted key (nil → the 2 min default) is distinguishable from an explicit "poll_interval: 0" (disables polling). A negative value also disables.
func (GitConfig) PollIntervalD ¶
PollIntervalD returns the effective poll interval (0 when disabled / unset).
type GitHubConfig ¶
type GitHubConfig struct {
ClientID string `yaml:"client_id"`
ClientSecret string `yaml:"client_secret"`
}
GitHubConfig holds the optional "Connect with GitHub" OAuth App credentials. The operator registers an OAuth App once in their GitHub settings and pastes the id + secret here (install-time, SSH — never a browser). When both are set, the dashboard offers one-click repo connect (pick a repo; Mooring installs a read-only deploy key for it — no key pasting). Empty = the feature is simply off.
func (GitHubConfig) Enabled ¶
func (g GitHubConfig) Enabled() bool
Enabled reports whether GitHub connect is configured.
type MonitorConfig ¶
type MonitorConfig struct {
PollInterval Duration `yaml:"poll_interval"`
MetricsRetention Duration `yaml:"metrics_retention"`
}
MonitorConfig tunes the read-plane poller (plan §4 read plane).
type RetentionConfig ¶
type RetentionConfig struct {
Interval Duration `yaml:"interval"` // how often the retention pass runs
EventsMaxAge Duration `yaml:"events_max_age"` // audit rows older than this are prunable
EventsMaxRows int `yaml:"events_max_rows"` // hard cap on audit rows (oldest trimmed)
ArchiveMaxMB int `yaml:"archive_max_mb"` // rotate the security-archive NDJSON past this
}
RetentionConfig is the Tier-1 (SSH-only, SIGHUP-reloadable) audit-retention block (plan §16.1). It bounds the events/audit table so it can never become the disk-wedge that kills the write plane — while NEVER silently dropping a security row (those are archived to NDJSON first, fail-closed).
type Role ¶ added in v0.6.0
type Role string
Role is an operator's authorization tier. owner does everything (deploy + all Tier-1: keys/reveal/setup/delete/tokens/trust); deployer can deploy, roll back, and edit an app's env/config/scaling; viewer is read-only.
type ServerConfig ¶
type ServerConfig struct {
// FileRoots are directories the operator may browse READ-ONLY in the Server
// tab (e.g. an app's log dir). Each needs a stable name (used in the URL).
FileRoots []ServerFileRoot `yaml:"file_roots"`
// DebCacheDir is the directory the operator downloads Mooring .deb packages
// into; the Server tab can delete OLD ones there (never the running version),
// behind password+TOTP re-auth. Must be absolute. It also must be within the
// service's writable paths for the delete to succeed (see docs).
DebCacheDir string `yaml:"deb_cache_dir"`
// VersionCheckEnabled controls the periodic self-update check: Mooring asks the
// GitHub API whether a newer release exists and whether the RUNNING version is
// affected by a published security advisory (→ a persistent banner + a CRITICAL
// alert). It is ON by default (a *bool so "unset" means on); set it to false to
// disable — then Mooring never contacts GitHub. When on it contacts ONLY
// api.github.com and sends no telemetry payload.
VersionCheckEnabled *bool `yaml:"version_check_enabled"`
// VersionCheckInterval is how often to poll (default 6h; clamped to a 1h floor).
VersionCheckInterval Duration `yaml:"version_check_interval"`
// ImageScanEnabled controls periodic vulnerability scanning of each deployed app's
// images + dependencies with Trivy (High/Critical → an alert; results on the Server
// tab). ON by default (set false to disable). It is HEAVY — Trivy downloads a
// vulnerability database and scanning uses CPU/RAM — so a small box may want it off.
// The scanner never gets the Docker socket: upstream images are scanned from the
// registry, build checkouts as a filesystem.
ImageScanEnabled *bool `yaml:"image_scan_enabled"`
// ImageScanInterval is how often to re-scan (default 24h; clamped to a 1h floor).
// Re-scanning unchanged images matters — new CVEs are disclosed daily.
ImageScanInterval Duration `yaml:"image_scan_interval"`
// DiskGCEnabled controls disk-pressure auto-reclaim: when disk usage crosses
// DiskGCThreshold, Mooring reclaims DANGLING docker images + build cache (the superseded
// builds that pile up as apps redeploy) and alerts. ON by default; safe because it only
// removes unreferenced garbage — never a tagged/in-use image, a rollback (which rebuilds),
// or any app data volume. Set false to disable.
DiskGCEnabled *bool `yaml:"disk_gc_enabled"`
// DiskGCThreshold is the disk-usage percent that triggers auto-reclaim (default 75,
// clamped to [50, 95]).
DiskGCThreshold int `yaml:"disk_gc_threshold"`
// BuildCacheKeepEnabled controls automatic reclamation of Docker/BuildKit build cache
// after a build-deploy. Mooring's generated multi-stage Dockerfiles emit a unique,
// single-use runtime layer per deploy (`COPY --from=build /app /app` + the non-root
// chown), so the cache grows without bound; Mooring runs `docker builder prune
// --keep-storage` to cap it — evicting the least-recently-used (stale) entries while
// keeping recent, reusable cache (e.g. the dependency-install layer) warm. ON by
// default (a *bool: unset = on); set false to disable — then Mooring never prunes.
BuildCacheKeepEnabled *bool `yaml:"build_cache_keep_enabled"`
// BuildCacheKeep is how much of the most-recently-used build cache to KEEP when pruning
// (default "5GB"). A size like "2GB"/"512MB". Smaller = less disk, colder rebuilds.
BuildCacheKeep string `yaml:"build_cache_keep"`
}
ServerConfig configures the read-only "Server" tab (host inspection + cleanup). Both knobs are OPT-IN and default to off/empty: with no file_roots the file view is disabled entirely (fail-closed), and with no deb_cache_dir the old-.deb cleanup is unavailable. The host monitor (CPU/memory/disk/processes) needs no config. Secret/state paths (the data dir, config, keys, DB) are ALWAYS denied to the file view regardless of what's listed here — see internal/web.
func (ServerConfig) BuildCacheGCOn ¶ added in v0.4.16
func (s ServerConfig) BuildCacheGCOn() bool
BuildCacheGCOn reports whether automatic build-cache reclamation is enabled (default on).
func (ServerConfig) BuildCacheKeepSize ¶ added in v0.4.16
func (s ServerConfig) BuildCacheKeepSize() string
BuildCacheKeepSize returns the validated keep-storage size, defaulting to "5GB" when unset or malformed. It is passed as a discrete argv element (never a shell string).
func (ServerConfig) DiskGCOn ¶ added in v0.6.0
func (s ServerConfig) DiskGCOn() bool
DiskGCOn reports whether disk-pressure auto-reclaim is enabled (default ON). When disk crosses the threshold Mooring reclaims DANGLING docker images + build cache (safe garbage — never a tagged/in-use image or any app data) and alerts. Set false to disable.
func (ServerConfig) DiskGCThresholdPct ¶ added in v0.6.0
func (s ServerConfig) DiskGCThresholdPct() int
DiskGCThresholdPct is the disk-usage percentage that triggers auto-reclaim (default 75, clamped to [50, 95] so it can neither thrash nor wait until the disk is already full).
func (ServerConfig) ImageScanOn ¶ added in v0.4.6
func (s ServerConfig) ImageScanOn() bool
ImageScanOn reports whether app vulnerability scanning is enabled (default on).
func (ServerConfig) VersionCheckOn ¶ added in v0.4.6
func (s ServerConfig) VersionCheckOn() bool
VersionCheckOn reports whether the self-update check is enabled (default on).
type ServerFileRoot ¶
type ServerFileRoot struct {
Name string `yaml:"name"` // [a-z0-9][a-z0-9-]{0,30}; used in the URL/UI
Path string `yaml:"path"` // absolute directory path
}
ServerFileRoot is one named, browsable directory.
type SessionConfig ¶
type SessionConfig struct {
IdleTimeout Duration `yaml:"idle_timeout"`
AbsoluteTimeout Duration `yaml:"absolute_timeout"`
}
SessionConfig holds idle/absolute timeouts (plan §5.3).
type SetupConfig ¶
type SetupConfig struct {
Enabled bool `yaml:"enabled"`
// Image is the digest-pinned jail base image (the throwaway container backend).
Image string `yaml:"image"`
// Resource limits — counted against the global one-docker-child semaphore.
WallClock Duration `yaml:"wall_clock"` // hard wall-clock timeout
CPUs string `yaml:"cpus"` // docker --cpus value, e.g. "1.0"
MemoryMB int `yaml:"memory_mb"` // hard memory cap (MemorySwapMax=0)
PidsLimit int `yaml:"pids_limit"` // max processes
ScratchMB int `yaml:"scratch_mb"` // writable scratch quota
OutputCapKB int `yaml:"output_cap_kb"` // captured stdout/stderr cap
}
SetupConfig gates the Mode-3 setup-script sandbox (plan §7/§9, OFF by default, hard-gated). When enabled, scripts run in a throwaway jail with the limits below; the binary refuses to boot if the host can't provide a working sandbox (plan §5.1), and a live self-test runs before EVERY execution.
type User ¶ added in v0.6.0
User is a resolved operator identity (the auth owner + each `users:` entry).
type UserConfig ¶ added in v0.6.0
type UserConfig struct {
Username string `yaml:"username"`
PasswordHash string `yaml:"password_hash"`
TOTPSecret string `yaml:"totp_secret"`
Role Role `yaml:"role"`
}
UserConfig is one ADDITIONAL operator (beyond the `auth:` owner). Credentials are minted the same way (`mooring hash-password` / `mooring gen-totp`) and pasted under `users:`.