Security
Authentication (gateway ↔ node)
Section titled “Authentication (gateway ↔ node)”Every node RPC may require a shared secret in gRPC metadata key authorization (Bearer <token> or raw token).
export MOMO_AUTH_TOKEN=$(openssl rand -hex 32) # same value on gateway + nodesWhen MOMO_AUTH_TOKEN is set on the node, missing/wrong tokens are rejected with gRPC UNAUTHENTICATED before handlers run. When unset, auth is disabled (local dev only).
Production (MOMO_ENV=production) requires an auth token.
Transport (TLS / mTLS)
Section titled “Transport (TLS / mTLS)”# Node (server)export MOMO_TLS_CERT=/etc/momo/tls/node.pemexport MOMO_TLS_KEY=/etc/momo/tls/node-key.pemexport MOMO_TLS_CA=/etc/momo/tls/ca.pem # verify clients when set
# Gateway (client)export MOMO_TLS_CA=/etc/momo/tls/ca.pemexport MOMO_TLS_CLIENT_CERT=/etc/momo/tls/gateway.pemexport MOMO_TLS_CLIENT_KEY=/etc/momo/tls/gateway-key.pemProduction requires secure transport (TLS material configured). Prefer both shared-secret auth and mTLS across untrusted networks.
Public binds
Section titled “Public binds”Defaults are loopback (127.0.0.1). Binding 0.0.0.0 requires:
export MOMO_ALLOW_PUBLIC_BIND=1Put a reverse proxy / load balancer (or optional momo edge) in front of the gateway for public HTTP. Do not expose the gateway directly to the public internet when using hop-based forwarded headers.
momo edge exposure
Section titled “momo edge exposure”- Static TLS: mount PEM cert/key; HTTP defaults to HTTPS redirect.
- ACME HTTP-01: public
:80must reach the edge for/.well-known/acme-challenge/; private keys underacme-dirare created0600(dir0700) where the OS allows. - Prefer
--acme-stagingbefore production issuance.
Forwarded headers (gateway → app)
Section titled “Forwarded headers (gateway → app)”The gateway propagates inbound X-Forwarded-Proto, X-Forwarded-For, and X-Forwarded-Host to application containers when present (values must be http/https for proto). When absent, defaults are proto=http, for=127.0.0.1 (or the connecting peer when available), and host from the request Host.
Trust boundary: these headers are only trustworthy from the immediate edge hop (momo edge or another reverse proxy you control). Clients that can reach the gateway directly can spoof them — keep the gateway on loopback/private networks when an edge terminates TLS.
Unsafe Docker options
Section titled “Unsafe Docker options”Cluster policy defaults reject:
| Option | Policy flag |
|---|---|
| Bind mounts | allow_bind_mounts |
| Privileged | allow_privileged |
| Host network | allow_host_network |
| Docker socket mounts | allow_docker_socket (always sensitive) |
| Devices | allow_devices |
| Raw capabilities | allow_raw_capabilities |
| Raw host config | allow_raw_host_config |
reject_plaintext_secret_env defaults on — env keys that look like secrets with plaintext values are rejected unless the policy is disabled.
Document supported vs unsafe Docker surface in app specs; see Spec schema.
Secrets handling
Section titled “Secrets handling”- Prefer secret references / external providers (future); do not put production credentials in committed YAML.
- Store credentials live in the store URI / filesystem permissions / Postgres role.
- Export snapshots (
momo export) may contain plaintext env from AppSpecs — treat backups as secrets.
Operator posture checklist
Section titled “Operator posture checklist”momo doctor --store "$MOMO_STORE" --gateway-url http://127.0.0.1:8080Doctor fails production checks when auth, TLS, or JSON logging is missing.