Skip to content

Security: ossko/colonies

Security

docs/Security.md

Security model and hardening

ColonyOS uses zero-trust, signature-based authentication: every RPC is signed with the caller's secp256k1 private key and the server recovers the caller's identity from the signature. There are no cookies or sessions, so CSRF is not a concern; authorization is checked per handler against the recovered identity.

This document covers the transport- and protocol-level hardening added in v2.0 and the settings that control it. All settings live in the Security config section and can be set with COLONIES_SECURITY_* environment variables (or the config file). Defaults are chosen to be safe without breaking existing executors and SDKs.

HTTP transport

Setting Env Default Notes
Read-header timeout COLONIES_SECURITY_READ_HEADER_TIMEOUT 20 s Slowloris defense. Does not affect the response side, so the executor long-poll assign is unaffected. 0 disables.
Idle timeout COLONIES_SECURITY_IDLE_TIMEOUT 120 s Keep-alive idle bound. 0 disables.
Max body bytes COLONIES_SECURITY_MAX_BODY_BYTES 104857600 (100 MiB) Caps request bodies so an unauthenticated caller cannot exhaust memory. Also caps a single websocket message. 0 disables.
CORS allowlist COLONIES_SECURITY_CORS_ALLOW_ORIGINS empty Comma-separated browser origin allowlist. Empty denies cross-origin browser requests; non-browser clients (executors, SDKs, CLI) send no Origin header and are always allowed. * restores allow-all.
WebSocket origin allowlist COLONIES_SECURITY_WS_ALLOW_ORIGINS empty Same semantics for /pubsub. Empty allows no-Origin (non-browser) and same-origin requests only. * allows any.
Rate limit COLONIES_SECURITY_RATE_LIMIT 0 (off) Per-client-IP requests/second on /api. /health is exempt. The assign long-poll and /pubsub subscribe count against the limit, so size it for the number of executors sharing a source IP.
Rate-limit burst COLONIES_SECURITY_RATE_LIMIT_BURST rate Allowed burst above the rate.

The server always runs gin in release mode. When TLS is configured it is served with a minimum version of TLS 1.2.

Deliberately, no ReadTimeout/WriteTimeout is set on the HTTP server: the executor long-poll assign holds the response open, and /pubsub websockets are long-lived, so a blanket read/write deadline would break legitimate connections.

RPC replay protection

Signed RPC messages carry an optional nonce and timestamp. When present, the signature covers the payload, timestamp, and nonce together, binding them against tampering. The server rejects a message whose timestamp is outside the allowed skew window or whose nonce has already been seen.

Setting Env Default Notes
Mode COLONIES_SECURITY_REPLAY_PROTECTION advisory off: ignore replay fields. advisory: check messages that carry replay fields, still accept legacy messages that omit them. enforce: additionally reject messages that lack replay fields.
Window COLONIES_SECURITY_REPLAY_WINDOW 300 s Allowed timestamp skew; also the nonce retention window.

Rollout is staged: v2.0 defaults to advisory so v2.0 clients are protected immediately while pre-v2.0 clients keep working. A later release is expected to default to enforce. Old clients that sign the payload only remain valid in off/advisory modes.

Cluster (multi-node only)

Single-node deployments run no relay or etcd. Multi-node clusters do, and those ports must be reachable only from trusted peers.

  • COLONIES_CLUSTER_SECRET authenticates the cluster relay: peers HMAC-sign each broadcast and the receiver rejects unsigned or mismatched posts. Set the same value on every node. When unset, the relay logs a warning at startup.
  • The embedded etcd peer/client ports have no TLS or authentication. Restrict them to a private/firewalled network. The server logs a warning when etcd binds to all interfaces in a multi-node configuration. (Full etcd mTLS is planned; see the modernization backlog.)

S3 credentials

S3 credentials are read from server/executor configuration (AWS_S3_*), never from per-file database records. The server does not persist or return S3 access keys, secret keys, or encryption keys; a migration blanks any that older versions stored. See modernization/DB-MIGRATION-NOTES.md.

There aren't any published security advisories