Security checklist
What to check before putting the team server and the runner in production.
Go through this list before production. Each line links to where it is explained.
Both services
- Served over HTTPS only, with a certificate your clients trust (TLS).
-
Post-quantum key exchange required once every desktop is upgraded:
--tls-pq require(OXYSDB_SERVER_TLS_PQ/OXYSDB_RUNNER_TLS_PQ) and the desktops’ network settingpqTls: require; a TLS proxy in front must offer X25519MLKEM768 itself (TLS). -
Behind a proxy,
server.trustedProxies/OXYSDB_SERVER_TRUSTED_PROXIESnames exactly the proxy (otherwise every user shares one sign-in throttle), and the API port admits nothing but the proxy. -
Secrets come from your secret manager (
existingSecret, External Secrets) or compose secret files, never from command-line arguments (URLs with passwords are refused there anyway). -
Images pinned by digest (
image.digest, third-party images@sha256:…). - NetworkPolicies on (the chart default) with a CNI that enforces them, and the ingress source matching your controller (Helm).
- Metrics, if on, reachable by the scraper only.
- Backups of the store and of the secrets, restore tested (Backups).
- One deployment per tenant: neither service isolates customers from each other.
Team server
- At least 2 replicas with the PodDisruptionBudget and topology spread (HA stores only).
-
Open sign-up off, or on with
verify-accountfor every new address;trustSignUponly behind single sign-on or on an internal network (Operations). -
Storage quotas suited to your team (
maxAccountMiB,maxFolderMiB). - Users told to keep Don’t copy credentials unless needed: copied passwords are readable by every folder member and stored without application-level encryption.
Runner
- Runs as a dedicated unprivileged user (the images use uid 65532).
- The access token is known only to those who may run tasks: it lets them read and write every database whose connection is sent to the runner.
-
Master password given as a file (
OXYSDB_RUNNER_MASTER_PASSWORD_FILE), stored safely. -
Its own database user and store (
runner.database.mode: external), not the team server’s credentials, unless you acceptedallowSharedCredentialsknowingly. -
intellishellScriptleft out of--allow-task-typesunless you trust everyone holding the token: a script runs code as the runner’s user. -
--credentials-dirholds only the keys and certificates tasks need; ambient credentials (Kerberos, cloud role, SSH agent) stay off unless required. -
Egress restricted where possible (
runner.networkPolicy.egress.restrict, allowlist), static egress addresses if target firewalls filter by source, pull-only pools for zones that accept no inbound connection. -
In database mode, per-pod volumes kept (
runner.persistence.perReplica.enabled, the default).
Report a vulnerability
See SECURITY.md in the repository for how to report a security issue privately.