Skip to content

feat: add optional LiveView end-to-end encryption - #43

Merged
kryptocodes merged 3 commits into
mainfrom
codex/liveview-e2e
Aug 27, 2026
Merged

kryptocodes merged 3 commits into
mainfrom
codex/liveview-e2e

Conversation

@AbdulRashidReshamwala

Copy link
Copy Markdown
Contributor

Summary

  • add optional liveViewEncryption: "e2e" session creation while keeping the standard transport as the default
  • use the same LiveView and noVNC implementation for both transport modes
  • bind the first viewer X25519 key with a one-time enrollment secret and Noise IK
  • encrypt framebuffer, clipboard, keyboard, touch, and viewer-control traffic between the viewer and pod
  • close plaintext RFB and user-facing control paths for E2E-bound pods
  • add admin session creation, reconnect storage, production image packaging, and protocol documentation
  • keep CDP on authenticated WSS and session status or TTL requests on authenticated HTTPS

Data flow

The gateway forwards encrypted LiveView frames and observes connection metadata, frame sizes, and timing. The client and pod decrypt message contents. Redis stores session-to-pod route metadata.

CDP remains available for Playwright and server automation through authenticated WSS. The gateway terminates TLS for CDP, session status, and TTL requests.

Verification

  • cd services/control-plane && bun test (92 passed)
  • cd services/pool-manager && bun test (36 passed)
  • cd packages/trusted-liveview && npm test (12 passed)
  • cd packages/trusted-liveview && npm run build:check
  • cd images/minimal-vnc-desktop/proxy && go test -race ./...
  • ./images/minimal-vnc-desktop/build.sh

@AbdulRashidReshamwala

Copy link
Copy Markdown
Contributor Author

Addressed findings 2–6 in b4f58f0.

  • Direct pod access: the browser fleet now installs ingress isolation by default. Browser-runtime pods accept declared user-facing/CDP ports only from labeled gateway and Pool Manager pods in configured namespaces; undeclared internal ports are not reachable through this policy. CDP remains gateway-terminated by design: CDP, session status, TTL, and refresh are server-facing APIs protected by their existing authentication and TLS, while LiveView framebuffer, clipboard, input, and viewer-control traffic use Noise.
  • Nonce/authentication failure: JavaScript advances the receive nonce only after successful authentication. A failed record permanently fails the channel, closes it with policy violation, clears queued plaintext, and prevents later records from being decrypted or delivered. Records queued during the handshake are authenticated before the channel is returned.
  • Connection lifetime: encrypted connections refresh the read deadline on traffic and send WebSocket pings using the shared frame-write lock, so an active or idle healthy viewer does not hit the original absolute 75-second deadline.
  • Plaintext allocation race: the proxy watches Agones allocation metadata from pod startup. When an E2E allocation arrives, it installs the binding and closes plaintext RFB/control WebSockets that were opened while the pod was idle. New plaintext connections remain rejected for the allocation.
  • Enrollment durability: first enrollment publishes the bound client public key and consumed marker through Agones before the handshake succeeds. Proxy restarts reload that durable binding. After successful enrollment, the viewer removes the raw bootstrap secret from retained session data and reconnects with the retained device key.

Verification completed:

  • go test -race ./...
  • trusted viewer tests: 13 passed
  • trusted viewer production bundle check
  • control-plane tests: 92 passed
  • Pool Manager tests: 36 passed
  • Helm lint and default chart render
  • full minimal-vnc-desktop production image build
  • git diff --check

@kryptocodes
kryptocodes merged commit e05a455 into main Aug 27, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants