> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-trino-dialect.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Documentation for the web terminal, an in-browser `clickhouse-client` session over WebSocket

# Web Terminal

The web terminal is an in-browser interface that provides an interactive `clickhouse-client` session over WebSocket. It is served from any ClickHouse HTTP port at the `/webterminal` path.

Navigate to `/webterminal` on any ClickHouse HTTP port (for example, `http://localhost:8123/webterminal`) to open the terminal.

<h2 id="enabling-the-feature">
  Enabling and disabling the feature
</h2>

The `/webterminal` endpoint is enabled by default and is controlled by the `enable_webterminal` server setting. To disable it, set the setting to `false`; requests to `/webterminal` then return HTTP status `403 Forbidden`.

```xml theme={null}
<clickhouse>
    <enable_webterminal>false</enable_webterminal>
</clickhouse>
```

<Note>
  `enable_webterminal` replaces the former `allow_experimental_webterminal` setting. The old name is still honored for backward compatibility when `enable_webterminal` is not set.
</Note>

<h2 id="authentication">
  Authentication
</h2>

The web terminal authenticates the user against the same `Session` and access-control checks as the HTTP protocol, but credentials are exchanged in-band over the established WebSocket connection rather than via the HTTP upgrade request. After the WebSocket handshake completes, the browser sends the first message as JSON:

```json theme={null}
{"type": "auth", "user": "<user>", "password": "<password>"}
```

The `user` field is optional: when it is omitted or empty, the user name falls back to the `default_session_user` [server setting](/operations/server-configuration-parameters/settings) (or its per-endpoint override in a [composable protocols](/operations/settings/composable-protocols) configuration), `default` unless configured otherwise. If `default_session_user` is set to an empty string, connections without a user name are prohibited: an `auth` message with an omitted or empty `user` fails authentication, the server closes the WebSocket with code `1008`, and, when the `session_log` section is enabled in the server configuration, the reject is recorded in [`system.session_log`](/operations/system-tables/session_log) as a `LoginFailure` event with an empty `user`.

This avoids placing credentials in URL query parameters or `Authorization` headers attached to the upgrade request, where they could end up in browser history, server access logs, and reverse-proxy logs. URL parameters, HTTP Basic, and `X-ClickHouse-User`/`X-ClickHouse-Key` headers on the upgrade request are intentionally **not** consulted by `/webterminal`.

Invalid credentials cause the server to close the WebSocket with code `1008`; the browser UI re-prompts for credentials.

<h2 id="session">
  What the session looks like
</h2>

Once authenticated, the server runs `clickhouse-client` attached to a pseudoterminal and bridges its input and output over WebSocket. The session supports the full `clickhouse-client` experience, including:

* Syntax highlighting.
* Autocompletion.
* Multi-line queries.
* Command history (stored on the server side for the duration of the session).

The terminal uses [xterm.js](https://xtermjs.org/) for rendering. All assets are served from the ClickHouse binary itself — no third-party CDNs are loaded.

<h2 id="play-integration">
  Integration with `/play`
</h2>

The [`/play`](/concepts/features/interfaces/http) Web SQL UI embeds the web terminal as a dockable panel. Toggle it with the terminal icon in the sidebar or press the `~` key when the query editor is empty. The `/play` page detects `/webterminal` availability at load time and hides the terminal controls when the endpoint is unavailable (for example, when `enable_webterminal` is set to `false`).

<h2 id="docs-integration">
  Integration with the documentation website
</h2>

This documentation website embeds the same terminal in a narrow developer tray along the bottom of the page, connected to the [ClickHouse playground](https://play.clickhouse.com) as the read-only `play` user, so that the examples on any page can be tried out without leaving it. The fixed tray reserves matching space at the end of the page so it does not obscure footer controls. While the terminal is open, the documentation page is locked and its scrollbar is hidden. Scrolling over the terminal is contained within its scrollback and does not move the documentation page behind it. Click the "ClickHouse terminal" bar or press the `~` key to open the padded panel above the bar. Click the bar again, use its chevron, press `~` or `Escape`, or drag the panel's top edge down to collapse it; that top edge also resizes it. Ending the session — `exit` or `Ctrl+D` — collapses the panel too.

Closing the panel keeps the session and its scrollback: reopening the terminal returns to the same prompt. The session lives in the page, so it survives navigation between documentation pages, but not a reload of the browser tab — after a reload the panel comes back with a new session.

The terminal tray is part of the desktop layout of the website and is not available on narrow viewports.

<h2 id="security">
  Security considerations
</h2>

The web terminal exposes an interactive shell-like session to anyone who can authenticate against the ClickHouse HTTP endpoint, so the same caveats that apply to the HTTP protocol apply here:

* Always serve `/webterminal` over HTTPS in untrusted environments to protect credentials and session traffic.
* Restrict access at the network level (firewall, reverse proxy, or the `listen_host` configuration) the same way you restrict access to the HTTP protocol.
* The endpoint validates the `Origin` header against the `Host` to mitigate cross-origin WebSocket hijacking; configure reverse proxies accordingly if you terminate TLS externally.
* Behind a TLS-terminating reverse proxy, the upstream connection to ClickHouse is plain `http` even though the browser uses `https`, so the strict same-origin check would reject legitimate connections. For these deployments, set `webterminal_allowed_origins` to a comma-separated list of full origins that are allowed to open WebSocket sessions; when this setting is non-empty, it replaces the default same-origin check. Example: `<webterminal_allowed_origins>https://example.com,https://app.example.com:8443</webterminal_allowed_origins>`.

The handler also enforces WebSocket protocol conformance per RFC 6455: unmasked client frames, reserved opcodes, oversized or fragmented control frames, and reserved RSV bits are rejected with protocol-error close codes.

<h2 id="platform">
  Platform availability
</h2>

The handler is compiled on all platforms ClickHouse supports. The pseudoterminal layer used by the embedded `clickhouse-client` runner is implemented on top of portable POSIX primitives (`posix_openpt`/`grantpt`/`unlockpt`), with a Linux-specific path that uses the thread-safe `ptsname_r`. The links to `/webterminal` on the ClickHouse start page and in `/play` are hidden automatically when the endpoint is unavailable (for example, when `enable_webterminal` is set to `false`).
