03Security & trust
Your warehouse password never reaches our engine.
We write the SQL. A Query Runner in your network runs it with a read-only role, and keeps the password and the audit log.
Stage 1 of 4
Caller
Asks for a metric by name. Never writes SQL.
✗Never holds a warehouse key.
Receives
# a question, asked by metric name
Passes on
{ "metrics": ["revenue"],
"filters": [{ "region": "EU" }] }
Authorization: Bearer <JWT or API key>Stage 2 of 4
Engine
Checks the credential, applies grants and row rules, then writes the SQL.
✗Never sees the warehouse password.
Receives
semantic query + credential
Passes on
SELECT SUM(o.amount) ... WHERE o.region = $1 + runner key
Stage 3 of 4
Query Runner · yours
Runs the SQL with a read-only role. Keeps the password, the kill switch and the audit log.
✓Holds: password, kill switch, audit log.
Receives
bound SQL + runner key
Passes on
native connection (read-only role)
Stage 4 of 4
Warehouse · yours
Returns rows to the runner. Only the runner can connect.
✓Your data never leaves your side as a copy.
Receives
read-only connection
Passes on
rows (not kept by the engine)
✗Engine → warehouse directly. There is no such path.
Why this shape
Writing SQL and running it are different jobs
Most semantic layers hold your warehouse connection. We split it in two, so the part that talks to agents never holds the keys.
The longer version is in The engine never opens your warehouse →
- 01
Compiling isn't executing
If the process that writes SQL also holds the password, you have to trust it with production.
- 02
Agents widen the blast radius
Agents are many and always on. None of them should be one step from your password.
- 03
Custody sits by the warehouse
The runner owns the password, the kill switch and the audit log.
Query Runner
Compile here, execute there
The engine sends SQL to a runner beside your warehouse. Pause the runner and every query stops. The engine has no other way in.
datahashi engine
CompileChecks access, applies row rules, writes the SQL.SELECT SUM(o.amount) AS revenue FROM analytics.orders o WHERE o.region = $1
Query Runner · yours
ExecuteHolds the DSN and runs the SQL next to your warehouse.✓ connected · read-only roleOnly your runner connects
Nothing else opens a connection to your warehouse.
Read-only, on your terms
It uses a read-only role that you create and can revoke.
Nothing copied out
No extracts or syncs. Rows pass through and aren't kept. Rollups are opt-in.
Every request
Five checks, in this order, every time
Callers name metrics. There's no way to ask for a raw table or a hidden column.
- 1
Credential
Who is asking comes from the verified token or key. A request body can't claim to be someone else.
- 2
Access mode
Each key is fixed to governed or explore. The client can't switch it.
- 3
Metric and field grants
The key sees only the metrics and fields you granted it.
- 4
Row rules
Row-level security filters every read before SQL is written, so tenants never see each other's rows.
- 5
Cost ceiling
Row caps and cost limits per workspace stop one runaway caller from hurting the rest.
Then the SQL goes to your runner, bound and parameterized.
Credentials and audit
Keys you can hand out and take back
Runner keys, not passwords
We store a key for your runner. On its own it can't open your warehouse.
Agents sign in with OAuth
Short-lived, scoped tokens. No long-lived secret sits in a config file.
One owner, one mode per key
Revoke or rotate any key without downtime.
Every query is metered
Each query records what it scanned, so you can total the cost by team or customer.
Give agents answers, not access
Open the console, or read how the runner keeps the password on your side.