Skip to content

feat: offer 'enclave vnc-viewer' - #29

Draft
sdirix wants to merge 8 commits into
mainfrom
feat/vnc-gui
Draft

sdirix wants to merge 8 commits into
mainfrom
feat/vnc-gui

Conversation

@sdirix

@sdirix sdirix commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What it does

Resolves the current project's VNC-enabled session, its published RFB
binding, and its per-session password, then launches a host viewer. The
default is xtigervncviewer on Linux and macOS Screen Sharing via open,
overridable with the vnc_viewer config key.

The password reaches the viewer through the environment (VNC_PASSWORD,
ENCLAVE_VNC_PASSWORD) rather than argv, which /proc would expose to
every local user for the viewer's lifetime. TigerVNC reads VNC_PASSWORD
itself, so the default viewer needs no placeholder and nothing is
written to disk.

gui_viewer is a registry option without a CLI flag. It configures a host
command, so a one-shot override on the command line would just be the
command the user could run directly.

Based on #24

How to test

  1. Install xtigervncviewer if you don't have it already. sudo apt install tigervnc-viewer
  2. Run an enclave with the vnc feature ./bin/enclave --features +vnc
  3. In the same directory run ./bin/enclave vnc-viewer

Follow-ups

Breaking changes

  • This PR introduces breaking changes and has been coordinated with maintainers.

Review checklist

Opt-in `vnc` mixin: a virtual X display (Xvnc) running a fullscreened
Chromium, served over VNC (RFB). The raw RFB port is published on the host
loopback so any VNC client can attach directly. Find the port with
`enclave ps --json` and read the per-session password from
/tmp/enclave-vnc/vnc-password.

A supervisor keeps Xvnc, matchbox-window-manager, and a headful Chromium at
$VNC_URL alive with restart loops. Xvnc listens on all container interfaces so
the published port reaches it, and enforces a random password at the RFB layer
(VncAuth). That password is what shapes the boundary: holding it is what grants
control of the display, and because it is generated per session it reaches
exactly one session's display, which is why the agent knowing it is harmless.

Exporting DISPLAY and BROWSER=vnc-open routes "open in browser" flows onto the
contained display, where all real browsing stays on the session's
gateway-restricted network.
@sdirix

sdirix commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

I will rework this command to be named enclave vnc-viewer instead of enclave gui to avoid any misunderstandings with HomeShell and making it more explicit.

sdirix added 3 commits August 6, 2026 12:57
- share one Chromium invocation (new vnc-chromium wrapper) between the
  supervisor and vnc-open, and quiet Chromium's background networking
- park the supervisor's browser restart loop while another live process
  holds the profile singleton instead of respawning every 2s
- install chromium via install.sh instead of the shared aptPackages
  stage so an Ubuntu base fails only this feature, with a clear error
- log vnc-open output to /tmp/enclave-vnc/log/ instead of /dev/null
- merge into /etc/xdg/mimeapps.list instead of truncating it
- drop the unusable VNC_RFB_PORT knob (spec.yaml pins the port)
- cover the extension-less vnc scripts with shellcheck in make lint,
  lint-report, and lint-changed
- document bridge-level RFB reachability under residual risks and keep
  the xdg-mime rationale in one place (vnc-open's header)
Namespace the feature's environment variables with ENCLAVE_, move the
installed scripts under bin/ so the shellcheck globs generalize to any
extension, bound the startup URL wait, and mirror supervisor diagnostics
into a log file since the entrypoint discards stdout and stderr.
@sdirix sdirix changed the title feat: offer 'enclave gui' feat: offer 'enclave vnc-viewer' Aug 7, 2026
@sdirix

sdirix commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@planger @xai Should we move this vnc feature and the vnc-viewer feature to the extension repository?

@planger

planger commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Yes, I'd be in favor of that in general: make sure enclave(-core) provides all the generic extensibility needed and let extensions mature outside and decide later. The maturity bar can be much lower in the enclave-extensions.

Of course the vnc viewer is a bit of a special case because it is a great generic feature, but still it might be easier to just move it to the extensions and have it merged asap.

@xai

xai commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

It is a great feature that unlocks a ton of use cases for enclave users, so it is a really hard decision. But in the end, I agree with Philip, as the extension path will make it available and visible faster to users.

Regenerate the extension surface golden for the display_name field, list vnc
among the opt-in features on the website configuration page, and make the
engine-specific wording accurate now that podman is a supported backend.
environment.variables rejects the ENCLAVE_ prefix as reserved for enclave internals, so the prefixed names were silently dropped.
Resolves the current project's VNC-enabled session, its published RFB
binding, and its per-session password, then launches a host viewer. The
default is xtigervncviewer on Linux and macOS Screen Sharing via open,
overridable with the vnc_viewer config key.

The command and the config key name the protocol rather than the generic
"GUI": a viewer has to speak VNC to be usable here, and "GUI" reads as if
it were a UI for enclave itself.

A named session goes through the shared session resolver, so a container
name, a container ID, or a session name passed to --name all address the
display, as they do for attach, stop, and theia; --tool disambiguates a
session name used by more than one tool. The no-argument form stays
VNC-aware and selects among the project's VNC-enabled sessions only, so a
session running without the feature is never the implied target and
naming one reports that rather than a missing container.

The password reaches the viewer through the environment (VNC_PASSWORD,
ENCLAVE_VNC_PASSWORD) rather than argv, which /proc would expose to
every local user for the viewer's lifetime. TigerVNC reads VNC_PASSWORD
itself, so the default viewer needs no placeholder and nothing is
written to disk.

vnc_viewer is a registry option without a CLI flag. It configures a host
command, so a one-shot override on the command line would just be the
command the user could run directly.
@github-actions

Copy link
Copy Markdown

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.

3 participants