Skip to main content

One replica is a correctness requirement

Browser WebSockets and pending commands live in one server’s memory. PostgreSQL does not route browser messages between processes. More replicas would produce offline-browser errors or send requests to the wrong process. Sticky sessions do not solve this for independent MCP clients, extension connections, and restarts.
  • Keep replicaCount: 1. Do not add an HPA, a second Deployment pointing at the same database, or a multi-worker process manager.
  • The Helm Deployment uses Recreate, not rolling surge, to avoid overlapping replicas.
  • Restarting disconnects browsers and interrupts pending commands. Browser reconnect does not replay completed or interrupted commands safely.
  • No high-availability, zero-downtime, or exactly-once browser action guarantee is provided.
Plan maintenance windows. Do not blindly retry a click, form submission, purchase, delete, or arbitrary JavaScript after a timeout; inspect the browser state first because the action may already have happened.

Health, readiness, and migration failures

GET /healthz checks process liveness. GET /readyz checks database connectivity. Neither reports that a particular user’s extension is connected; check the dashboard’s browser status and last-seen metadata. If the server pod is stuck in Init:
  1. Inspect the revision-named migration Job and its pods.
  2. If wait-for-database is pending, verify database readiness, DNS, network policy, credentials, and TLS.
  3. If migrations failed, read the migration logs and fix the root cause. Do not bypass the startup gate or mark a failed Job successful.
  4. If migrations completed but the server is waiting, verify the Job name, namespace-scoped Role/RoleBinding, projected token/CA, and reachability of kubernetes.default.svc.
Job backoff and a 600-second active deadline bound migrations by default. The startup gate retries status reads for a bounded period and fails closed. Use a new Helm revision after correcting a failed migration; do not mutate an immutable Job spec in place. Keep the current successful migration Job for future pod restarts.

Upgrade checklist

  1. Verify both-edition CI, the target image digest, chart version, and database migration notes.
  2. Take a PostgreSQL backup and confirm the encryption key can be recovered.
  3. Tell users about disconnections and stop sensitive browser actions.
  4. Render and server-dry-run the intended configuration, then perform helm upgrade --wait --wait-for-jobs.
  5. Check migration completion, rollout status, Pod readiness, events, and /readyz.
  6. Reconnect a test browser and run browser_tabs plus a snapshot on a harmless page.
A chart rollback is not a database rollback. Review schema compatibility before using helm rollback; restore from a tested backup if a destructive migration requires it. Do not change the PostgreSQL major version by merely editing its image tag on an existing volume.

Persistent data and secrets

PostgreSQL stores users, sessions, browser registrations, token hashes, encrypted settings, pending approvals, and metadata-only audit events. Back it up on an operator-defined schedule. Retention and cleanup policy are operator responsibilities; the chart is not a backup service. The bundled database uses an explicit Ceph RBD RWO PVC with a dedicated child PGDATA path and full-volume mount. No node-local storage or subPath is used. Retain and restore keys independently of storage snapshots. Database password changes require coordinated SQL role rotation and secret updates; environment changes do not reinitialize existing data.

Logs, monitoring, and networking

Monitor readiness failures, restart counts, migration failures, database capacity, and connection/error rates using your normal cluster tooling. Audit entries contain tool name, status, and timestamp metadata, not tool arguments or page results. Avoid logging HTTP bodies, authorization headers, cookies, device verifiers, screenshots, and evaluated code in ingress/APM systems. Restrict database access and Kubernetes API permissions. If adding NetworkPolicies, allow server/migration access to PostgreSQL, DNS, and required identity providers; the startup gate also needs the Kubernetes API. Configure WebSocket-capable proxies with timeouts that permit 20-second heartbeats.

Incident response

Disconnect the extension to pause control. Revoke affected MCP tokens and rotate the connection token; inspect account sessions and audit metadata. Assume exposed MCP credentials could have accessed signed-in browser data. Review actions in the websites themselves, rotate downstream credentials when needed, and follow your operator’s notification policy. Revocation cannot undo completed actions or erase data already returned to a client.