Skip to main content
Formal supports ClickHouse over HTTP and HTTPS. Configure clients and drivers to use the HTTP protocol rather than ClickHouse’s native TCP protocol.

Requirements

Native User Permissions

Create ClickHouse native users with the upstream grants that their mapped Formal users need. For example, map analysts to a ClickHouse native user with SELECT access. Map data engineers to one with the required write or DDL grants. Formal does not need an administrative ClickHouse user to proxy queries. See Select a default Native User for selection examples.

Connect to ClickHouse

  1. Go to Resources and click Create Resource.
  2. Set Technology to ClickHouse.
  3. Enter a Resource name and the upstream ClickHouse HTTP hostname and port.
  4. Configure Resource TLS when the upstream endpoint uses HTTPS.
  5. Create a Password native user. Set its username and password to the credentials of the upstream ClickHouse user.
  6. Configure a default Native User.
Verify: Run the curl query under Direct connection examples. A successful Resource returns the selected database and native ClickHouse username.

Authentication

Choose one of these authentication methods:
  • Formal Endpoint: Route requests through Transparent Mode as the signed-in Formal user.
  • Direct with a Formal identity: Send a Formal username and access token to the Connector. Formal connects upstream through the Native User selected by the Resource’s default Native User selection.
  • Direct with native credentials: Forward an end user’s native ClickHouse credentials directly to ClickHouse.

Route traffic through the Formal Endpoint

Formal Endpoint Transparent Mode supports ClickHouse HTTP traffic. Configure a network rule that selects the ClickHouse Resource and forwards traffic to the Connector. Clients keep using the Resource’s real hostname. The Formal Endpoint automatically applies the signed-in user’s Formal credentials. See Transparent Mode for setup and platform requirements.

Connect directly with a Formal identity

Clients can send a Formal username and access token using either ClickHouse authentication headers or HTTP Basic authentication:
  • X-ClickHouse-User and X-ClickHouse-Key
  • HTTP Basic authentication

Direct connection examples

These examples connect directly to the Connector with a Formal identity.

curl

Get your Formal username and access token from the Control Plane, then send a query in the request body:

Python with ClickHouse Connect

clickhouse-connect uses the ClickHouse HTTP interface:
Set secure=False only when the client-to-Connector listener intentionally uses plain HTTP. Verify: The script prints 1 after the Connector authenticates the user and ClickHouse executes the query.

Smart Routing

The Connector supports Smart Routing for ClickHouse. Configure a technology listener to route one port to multiple HTTP-based resources. Prefix the Connector hostname with the Resource name:
For example, analytics-ch.connector.example.com selects the ClickHouse Resource named analytics-ch. Configure wildcard DNS and a wildcard TLS certificate when using hostname-based routing.

ClickHouse compatibility

ClickHouse Connect and the official Go driver work when configured for HTTP. Formal supports common query workflows, named sessions, query parameters, settings, and compression.

Policy evaluation

Formal evaluates ClickHouse traffic at all three policy stages: For common identity, device, Resource, Connector, and Space inputs, see Policy Evaluation. The inputs below describe the ClickHouse request and response.

Inputs by stage

ClickHouse exposes input.http at request and response policy. Request policy receives request transport details. Response policy combines the request method, path, and query with the response headers and body.

Database input

input.db_name identifies the database used for a query. It may be empty for a request that does not target a database.

SQL and table inputs

At request policy, input.sql_query provides: input.sql_query may be incomplete. Check input.sql_query.incomplete before relying on the full statement. For INSERT statements, input.sql_query never includes VALUES. input.table_paths contains table paths when Formal can identify them. The list may be incomplete. Keep ClickHouse permissions as the primary table-level control.

Request-local ClickHouse inputs

input.clickhouse.url_settings contains only settings supplied in the current request URL. It does not include profile defaults, named-session settings, or SQL SETTINGS clauses. An absent setting does not describe its effective value. input.clickhouse.url_filters contains each filter URL parameter in request order. It does not include filters from profiles, sessions, paths, or server configuration. Likewise, input.clickhouse.request_parameters contains only bindings supplied by the current request. It does not include bindings retained by a named session.

Restrict the selected database

The following request policy allows query requests only when the selected database is analytics or reporting:
input.db_name is the explicit database, the named session’s current database, or the authenticated user’s default. It does not identify every database named inside the SQL statement. ClickHouse permissions must restrict cross-database access through qualified table names. Combine input.db_name with identity, group, or device inputs for more specific selected-database rules.

Require read-only queries

ClickHouse enforces read-only access when clients set readonly=1. The following request policy requires this setting for every query:
Clients can supply this setting in the connection configuration or as readonly=1 in the request URL.

Govern native users

Use separate upstream ClickHouse users for each privilege level. Select among them with the Resource’s default Native User selection. Then enforce the result in session policy. This example prevents users from explicitly requesting the admin label:

Response policies

ClickHouse response policies use input.http to inspect the response body and headers. They can block a response, rewrite headers, replace the full body, or encrypt supported HTTP targets. These controls also apply to compressed responses. Formal does not currently expose ClickHouse response columns or cells to policy, so ClickHouse response rules should not reference input.row, input.columns, or column-aware mask and filter actions. If a policy produces an active structured mask action for a ClickHouse response, Formal fails closed rather than returning data without the requested protection.

Application and end-user attribution

ClickHouse clients and BI tools can attach Formal attribution parameters to a request: These values are available to policies and Formal audit logs. They can also appear in ClickHouse’s system.query_log.

Troubleshooting

  • The client disconnects before running a query: confirm that it uses the HTTP protocol. For clickhouse-go, set Protocol: clickhouse.HTTP.
  • No Native User is resolved: configure a default Native User selection or request a label explicitly.
  • Smart Routing selects the wrong Resource: verify that the first hostname label exactly matches the Resource name and that wildcard DNS reaches the Connector.

Next steps

Write policies

Build identity-aware access controls

Review logs

Inspect ClickHouse query activity