3 min read

Helicone lets users query shared ClickHouse safely

Helicone added direct SQL access to a shared ClickHouse table, then used row policies and per-query settings to keep tenants isolated.

Image: Hacker News

Helicone has added a SQL editor called HQL that lets customers run SELECT queries directly against its shared ClickHouse cluster. That setup puts every organization’s request data in the same table, request_response_rmt, separated only by an organization_id column — which makes tenant isolation the whole problem.

Instead of rewriting customer queries in the application, Helicone pushed the security boundary into the database itself. The company uses two lesser-known ClickHouse features together: row policies and custom settings.

A dedicated database user, hql_user, is created solely for HQL traffic. Helicone then attaches a row policy to that user so every SELECT on request_response_rmt is automatically filtered as if it included:

  • WHERE organization_id = getSetting('SQL_helicone_organization_id')

That matters because customers all query the same underlying table, but the database enforces isolation regardless of what SQL they write.

On ClickHouse Cloud, custom settings must use the SQL_ prefix, so Helicone passes the tenant ID on every request as SQL_helicone_organization_id=<org>. In its Node client, it also sets guardrails including:

Recommended reading

Z.AI powers 1GW AI hub without Nvidia chips

  • readonly: “1”
  • allow_ddl: 0
  • max_execution_time: 30
  • max_memory_usage: “4000000000”
  • max_result_rows: “10000”

The readonly = 1 setting closes an obvious hole: ClickHouse allows a SELECT to end with a SETTINGS clause, which could otherwise let a customer try to override the tenant ID. Helicone also rejects any query text that mentions the reserved setting name, though ClickHouse is the real enforcement layer.

ClickHouse permissions and parser limits

Helicone also stripped hql_user down to a single useful permission. It revokes access from *system., information_schema., and default., then grants only SELECT on default.request_response_rmt. That matters because tables like system.query_log** could otherwise expose every tenant’s SQL history.

The application still parses SQL, but only for convenience features such as inserting or clamping LIMIT. Helicone uses node-sql-parser in PostgreSQL mode because the library has no ClickHouse dialect. When parsing fails on ClickHouse-specific syntax, it falls back to regex-based LIMIT handling.

Crucially, that parser is not responsible for tenancy. Helicone argues that app-side query rewriting is too fragile, especially with subqueries, CTEs, UNION branches, self-joins, arrayJoin, and map subscripts like properties['user_id']. A missed edge case could leak data.

Testing subqueries, CTEs, and hostile queries

That concern shaped the company’s tests. Helicone says hqlSecurityTests.test.ts runs 843 lines of adversarial queries against a real ClickHouse instance with the real row policy enabled. The suite covers settings overrides, system table access, file(), url(), s3(), mysql(), UNION attacks, permission escalation, and parsing edge cases.

One of the simplest tests is also the clearest: a query that asks ClickHouse to count rows from every other organization. The result is 0. The query runs normally; the rows just are not visible.

Helicone says the most important property of the design is that it fails closed. If the app forgets to send SQL_helicone_organization_id, getSetting throws an error and the query dies instead of returning someone else’s data. For customer-facing SQL on ClickHouse, that is the difference between a parser bug causing inconvenience and a parser bug causing a leak.

Marcus Vance

Enterprise Editor

Marcus follows the money. He covers enterprise software, cloud architecture, and the tectonic shifts in Big Tech strategy. He translates dense earnings calls and complex M&A activity into actionable insights about where the industry is actually heading. If a tech giant makes a silent pivot, Marcus is usually the first to notice.

via Hacker News

// Keep reading