Connection grants
Connection grants
A grant says “principal X can query connection Y, scoped to tables Z, under optional row-level predicates.”
Principals can be:
- A specific user (their UUID).
- A role (
member,admin, etc.). - A workspace (everyone in that workspace).
Create a grant
From a connection row → Grants tab → Add grant.
- Pick the principal (user / role / workspace).
- Set the table allowlist — what they’re allowed to query.
Use globs:
demo.*allows every table in thedemoschema;analytics.fact_*allows all tables whose names start withfact_. - (Optional) Add a scope predicate — a SQL expression injected
into every query. Example for tenant isolation:
Pollenix substitutestenant_id = :user.tenant_id
:user.tenant_idat query time from the requesting user’s identity. - Save.
Allowlist syntax
| Pattern | Matches |
|---|---|
public.users | Exactly that table. |
demo.* | Every table in the demo schema. |
*fact* | Every table whose name contains fact. |
analytics.dim_?ate | dim_date, dim_rate — single-char wildcard. |
Patterns are evaluated case-insensitively.
Scope predicates
Scope predicates are conjunctive — they’re ANDed into every query the
NL→SQL writer generates. Use them for row-level isolation:
-- Per-region carve-outregion = 'NA'
-- Per-tenanttenant_id = :user.tenant_id
-- Per-account (multi-tenant SaaS upstream)account_id IN (SELECT account_id FROM user_accounts WHERE user_id = :user.id)Predicates are validated against the schema catalog when saved — a typo on a column name fails fast instead of erroring at query time.
Resolution order
When a user asks a question:
- Pollenix collects every grant matching their user / role / workspace.
- The allowlist is the union of all matching grants.
- The scope predicate is the union of all predicates (AND’d together at runtime).
So a user in two workspaces sees the union of both workspaces’ tables, subject to both predicates.
Audit
Every grant change emits an audit event (connection.grant_create,
connection.grant_delete, etc.). See Audit.