v0.4.2-beta
·
254 commits
to master
since this release
Spooky 0.4.2-beta — Admin-Plane Security & Audit
Patch release since 0.4.1-beta. The control API moves from one shared bearer
token to roles, client certs, and an audit trail.
Added
- Admin roles —
viewerreads,operatormutates,adminrestarts.
Configure underobservability.control_api.auth.bearer_tokens[]. - Control API mTLS —
tls.client_auth.mode:disabled,optional, or
required. Scoped to the control API; downstream client auth is untouched.
Roles can come from a cert subject attribute viaauth.identity_source. - Audit stream — JSON record per privileged action (actor, action, target,
generation, result, reason, timestamp). Covers auth success/failure, denials,
reads, and attempt/result pairs for mutations. Writes to a dedicated
spooky.control_api.auditlog target or its own file. - IP allowlisting — CIDR gate under
ip_allowlist, checked before
credentials, using the TCP peer address.
Changed
- Under-scoped callers now get
403withreason: insufficient_role. Missing
or bad credentials still get401. Denial bodies gainedreasonand
required_role. - The control API builds its own TLS config instead of borrowing the primary
listener's, and advertises onlyhttp/1.1in ALPN. - Plain-text log lines now include the log target. JSON output unchanged.
Security
- Token matching is constant-time across the full set.
- Tokens never appear in
/admin/runtimeand are redacted in debug output. - Startup rejects: mTLS without CA material,
optionalmTLS as the only auth,
inverted role ordering, file audit sink with no path, malformed CIDRs.
Upgrade Notes
Nothing breaks. New settings default to off — mTLS disabled, no static tokens,
no audit, empty allowlist. auth_token still works as an admin identity.
401 will miss the new 403.
the new admin-plane fields. Roll the binary back before the config.
Migration: add role-scoped tokens next to auth_token, turn on audit to see who
still uses the legacy token, then drop it.
Known Limitations
- No CRL/OCSP — a stolen client cert works until its CA rotates
- Bearer and cert roles are unioned: a
viewertoken with anadmincert
getsadmin - Audit is per-process and local — no aggregation, no tamper-evidence
trust_proxy_headersis accepted but ignored- Pre-GA — soak test before broad rollout