# teesql-example configuration template. # # Copy to `.env`, fill in the cluster identity, and source it before running # any teesql-example subcommand. All variables are read by # src/teesql_example/config.py and validated at startup; misconfigured # values fail loud rather than getting injected as None. # ── Cluster identity (operator gives you these) ────────────────────────────── # 10-hex-char cluster UUID. Lookup is `_teesql-leader..teesql.com TXT`. TEESQL_EXAMPLE_CLUSTER_UUID= # 20-byte hex of the dns-controller's manifest_signer pubkey, with or without # 0x prefix. The forwarder verifies the leader manifest signature against this # address; a wrong value rejects every signed TXT record. TEESQL_EXAMPLE_MANIFEST_SIGNER= # Which database on the cluster's primary your roles can connect to. Must # already exist (the cluster operator runs `provision.sql` once per cluster # to create per-tenant DBs). TEESQL_EXAMPLE_DATABASE= # ── Auth — the cluster_secret your operator allowlisted for you ────────────── # 64-char hex (32 raw bytes). Cluster-wide secret allowlisted for one or both # postgres roles below. The cluster sidecar substitutes the KMS-derived # password on the wire after verifying your TDX quote — this secret is the # customer-side allowlist token, NOT the postgres password itself. TEESQL_EXAMPLE_CLUSTER_SECRET= # Roles. The example uses TWO long-lived connections — one read-write, one # read-only — so it can demonstrate the write/read split end-to-end. Both # authenticate with the same cluster_secret; the cluster's grants enforce # the role separation. TEESQL_EXAMPLE_PRIMARY_ROLE=teesql_readwrite TEESQL_EXAMPLE_SECONDARY_ROLE=teesql_read # ── Polling cadence ────────────────────────────────────────────────────────── # The secondary connection polls `events WHERE id > last_seen` on this # interval and broadcasts new rows over WebSocket to every connected # browser. The connection is opened ONCE at process start, NOT re-handshaken # per poll, so the per-tick cost is one SELECT round-trip on an existing # RA-TLS session. # # 50ms is a good default — feels real-time in the browser, well below the # pace at which RA-TLS handshakes would matter. Bump to 100-250ms if you # want lower DB load. Values <20ms start hitting psycopg's per-query # overhead before they hit network. TEESQL_EXAMPLE_POLL_INTERVAL_MS=50 # ── HTTP / WebSocket bind ──────────────────────────────────────────────────── # Where the FastAPI app listens. Inside a CVM, bind 0.0.0.0:8080 and let # the dstack gateway expose it via the SNI router as `-8080.`. TEESQL_EXAMPLE_HOST=0.0.0.0 TEESQL_EXAMPLE_PORT=8080 # ── dstack guest agent (TDX attestation) ───────────────────────────────────── # Path to the dstack guest agent socket. Default works inside a CVM. For # local development with the dstack simulator, point this at the simulator # socket (e.g. /tmp/dstack-simulator.sock). TEESQL_EXAMPLE_DSTACK_SOCK=/var/run/dstack.sock # Permit running with the dstack simulator instead of a real CVM. NEVER set # this in a customer-facing deployment — the simulator emits fake quotes the # cluster sidecar will refuse if it has DCAP enabled. TEESQL_EXAMPLE_ALLOW_SIMULATOR=false # ── Operational ────────────────────────────────────────────────────────────── # Log level. INFO is enough to trace the connection ceremony and per-tick # row counts; DEBUG also logs every poll's row count + every WebSocket # subscribe/unsubscribe (verbose). TEESQL_EXAMPLE_LOG_LEVEL=INFO