> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-mintlify-8c05c8a2.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>"}
```

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="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`).
