--- id: browser-console title: Browser console sidebar_label: 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](./ssh-keys.md). 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 |