Files
vantage-docs/docs/vantage/browser-console.md
T
mrhid6 e2c08da6a7 fix: bound and complete console relay teardown, restore proxy_failed audit
- Arm the unclaimed-relay watchdog in NewSession rather than Serve, so an
  agent that never opens its ProxyStream is bounded to 10s and reports
  reason "agent_timeout", per the design spec's failure-mode table.
- Session.Close now also closes the accepted net.Conn (stored via setConn),
  so ConsoleProxy.Close() is an unconditional kill of the whole relay chain
  instead of only closing an already-idle listener.
- Emit console.proxy_failed and end the console session from a defer in
  consoleTunnel guarded on relay.Reason(), since guac's OnDisconnect never
  runs when the connect callback errors -- which is the path every relay
  failure this feature introduces takes. Update the two docsite
  troubleshooting rows to match what the audit event can now actually show.
2026-07-31 09:21:07 +01:00

3.3 KiB

id, title, sidebar_label
id title sidebar_label
browser-console Browser console Browser console

An SSH, RDP or VNC session in a browser tab, with no client software and no inbound port on the target beyond the one the protocol already uses.

Protocol handling is Apache Guacamole's the control plane proxies a WebSocket to a guacd daemon and manages credentials around it.

Requirements

  • guacd running and reachable from the server. The bundled Compose stack includes it; GUACD_ADDR defaults to guacd:4822.
  • KEY_ENCRYPTION_KEY set, since every credential involved is stored encrypted.
  • The target's agent must be online. Console traffic is relayed over the agent's existing outbound connection, so the control plane never needs a route to the server's address — but it does need the agent.
  • No inbound port on the target, beyond what the protocol already listens on locally. A service bound only to 127.0.0.1 works, because the agent dials loopback on the target itself.

Opening a session

From a server's page, choose Console. Then:

  1. The UI calls POST /api/console/connect, which mints a one-time session token. If the target's agent is not connected, this fails immediately with 409 agent_offline rather than hanging.
  2. The browser opens a WebSocket to GET /api/console/tunnel with that token.
  3. The server marks the token consumed atomically, so a second use cannot race and proxies the connection to guacd.

Credentials

SSH

Authenticates with a private key stored in the key library. The key must have its private half uploaded; a public-only key cannot open a session.

RDP and VNC

You supply credentials when connecting. They are encrypted, single-use, and consumed when the tunnel opens. They are not retained for the next session.

:::info Why single-use A stored console credential is a standing grant to that machine for anyone who can reach the endpoint. Consuming it at tunnel-open means a leaked session token is worth one connection at most, and only until it is used. :::

Session behaviour

Closing the tab ends the session. There is no reconnect and no session persistence reopening mints a new token and a new connection.

Auditing

Opening a console is an audited action, with actor, server and time. What happens inside the session is not recorded: there is no session capture or keystroke log. If you need that, it has to come from the target machine.

When it does not work

Symptom Cause
Connects then closes immediately guacd unreachable check GUACD_ADDR and that the container is up
SSH refuses the key The stored key has no private half, or is not in the target's authorized_keys
RDP fails on a fresh credential Credentials are consumed on open; a retry needs them entered again
Hangs, then disconnects The agent never claimed the relay, nothing is listening on the protocol port on the target's own loopback address, or guacd never dialled in time. Check the audit log for console.proxy_failed — its reason (agent_timeout, dial_refused, guacd_timeout, rejected) names which