Security hardening and deployment boundary
Updated for version v0.69.0
This guide describes the controls included in the v0.61 security hardening,
the v0.65 production launch controls, and the boundaries that remain the
operator's responsibility.
Start a protected production instance
The production Compose profile refuses to start without a password. Generate a
unique secret outside the repository, store it in a secret manager, and inject
it at deploy time:
export SPEDO_REQUIREPASS="$(openssl rand -base64 32)"
docker compose -f docker-compose.prod.yml up -dThe published container image fails closed if no credential is configured.
SPEDO_ALLOW_UNAUTHENTICATED=true exists only for deliberate local development
and must not be used in a production deployment. The production Compose
profiles also require a readable license file through SPEDO_LICENSE_FILE and
set SPEDO_PRODUCTION=true; this prevents a silent degraded-license startup.
Use noeviction and keep SPEDO_COL_ENABLED=false for durable data. An LRU
or ColdArchive configuration belongs only to an explicitly rebuildable cache
profile. The public stack leaves the documentation assistant disabled unless
the assistant profile and its persistent /data volume are intentionally
enabled.
For separate application identities, use SPEDO_USERS instead. A role suffix
is optional and defaults to rw; passwords may contain : when the final
token is a recognized role.
export SPEDO_USERS='writer:replace-me:rw,reader:replace-me:ro,operator:replace-me:admin'SPEDO_REQUIREPASS is the canonical single-password setting. Older
SPEDO_ADMIN_PASSWORD and SPEDO_AUTH_PASSWORD names remain compatibility
aliases and emit a startup warning. A configured credential cannot be disabled
by SPEDO_AUTH_MODE.
Authorization model
The RBAC policy is deny-by-default for non-admin roles. rw and ro receive
only reviewed data-plane commands; they cannot enumerate global keys, inspect
clients or IP metadata, enable tracking, subscribe to global channels, manage
ACLs/configuration, save/flush the database, or execute/register scripts.
Administrative commands, client tracking, observability controls, scripts,
and push subscriptions require the admin role.
Roles are not tenant isolation. An rw or ro identity that may read a key
can read all data keys it is authorized to use; Spedo does not provide
per-prefix or per-tenant ACLs. Use separate instances or an application-level
authorization boundary for mutually untrusted tenants.
Bounded network input
Every accepted connection receives a bounded request buffer. The defaults are
intentionally below the former unbounded behavior:
Malformed or over-limit frames return an error and close the connection. A
connection also has a bounded number of failed authentication attempts.
Observability and portal exposure
Prometheus is a separate unauthenticated HTTP listener. It is disabled unless
SPEDO_METRICS_ENABLED=true; it also returns 404 unless the internal
Prometheus observability switch is enabled. Bind it to a private interface or
scrape it from a private sidecar only.
The default portal starts a read-only public documentation application on the
local development loopback. It has no account, OAuth, administration, billing,
signing, or generated API routes. Private portal features require explicit
enablement and operator-provided bootstrap credentials; no known password or
administrative account is shipped. Expose either portal mode only through an
explicit TLS reverse proxy or ingress.
Persistence and memory safeguards
WAL writers reject frames that recovery would refuse, and PEXPIRE/PERSIST
write durable state changes. DEL, FLUSHDB, and snapshot restore clear the
volatile feature stores associated with a keyspace. Matrix dimensions are
checked before allocation; scripts, CDC, and feature stores have bounded
retention/accounting controls.
Logical deletion does not securely wipe historical bytes from an append-only
disk tier. Use encrypted volumes and a storage-erasure procedure when physical
media erasure is a requirement.
Still required outside Spedo
- Terminate TLS and restrict ingress with a VPC, firewall, or trusted proxy.
- Keep secret values out of Compose files, images, logs, and source control.
- Rotate credentials and portal data if an older image or repository history
ever contained them.
- Treat the optional cAdvisor observability profile as host-sensitive: it has
privileged host visibility and is not suitable for an untrusted shared host.
- This remains a single-node product boundary, not a distributed HA or tenant
isolation system.
- Run
scripts/backup_snapshot.shwithSPEDO_REQUIREPASSnightly, verify
the emitted SHA-256 file, and replicate the archive to encrypted off-host
storage. Restore drills are an operator requirement, not a background
feature of the engine.