Table access rules
Control which database tables users can query by allowing or blocking access with patterns and conditions.
Table access rules determine which tables users can query on a data source. You define rules using exact table names or glob patterns, and optionally restrict them to users who match specific conditions.
Rules are evaluated in the table_rules list within your
policy YAML. When no rule matches a
table, the default_allow_tables setting decides whether
access is granted or denied.
Basic usage
Each rule specifies a table_name and whether access is
allowed:
version: "1.0"
default_allow_tables: true
table_rules:
- table_name: audit_logs
allowed: false
- table_name: public_stats
allowed: trueWith this policy, queries against audit_logs are blocked
while public_stats is explicitly allowed. All other tables
fall through to default_allow_tables: true, so they remain
accessible.
Before and after
Given the policy above, here is how a query is affected:
SELECT * FROM orders JOIN audit_logs ON orders.id = audit_logs.order_id-- Query blocked: access to table "audit_logs" is deniedBecause audit_logs is blocked, the entire query fails —
Kaelio doesn't silently remove the blocked table and return
partial results.
When a query references a blocked table, the entire query is rejected. This applies even if the blocked table is only used in a JOIN, subquery, or CTE. Kaelio never returns partial results from queries that touch restricted tables.
Glob patterns
Use glob patterns to match multiple tables with a single rule. This is useful when your database follows a naming convention.
version: "1.0"
default_allow_tables: true
table_rules:
- table_name: internal_*
allowed: false
- table_name: "*_pii"
allowed: false
- table_name: tmp_*
allowed: falseThis blocks all tables starting with internal_, ending
with _pii, or starting with tmp_.
| Pattern | Matches | Doesn't match |
|---|---|---|
* | All tables | — |
analytics_* | analytics_events, analytics_sessions | raw_analytics |
*_logs | audit_logs, access_logs | logs_archive |
internal_* | internal_users, internal_config | users_internal |
Rules are evaluated in order: exact names match first, then
more specific glob patterns, then the * wildcard. See the
Policy YAML Reference for full details
on matching precedence.
Conditional access
Add a condition to a rule so it only applies when the
user's security properties match. This lets you grant
different access levels based on department, role, or any
other user attribute.
version: "1.0"
default_allow_tables: false
table_rules:
- table_name: compensation
allowed: true
condition:
department: "hr"
- table_name: compensation
allowed: true
condition:
department: "finance"
- table_name: sales_pipeline
allowed: true
condition:
department: ["sales", "marketing"]In this example:
- The
compensationtable is only accessible to users whosedepartmentproperty ishrorfinance - The
sales_pipelinetable is accessible to users insalesormarketing - All other tables are blocked because
default_allow_tablesisfalse
When a condition has multiple keys, all keys must match (AND logic). If a user doesn't have a required property set, the condition fails and the rule is skipped.
table_rules:
- table_name: payroll
allowed: true
condition:
department: "hr"
role: "manager"This rule only applies to users who have department set to
hr and role set to manager.
If a conditional rule doesn't match and no other rule covers
the table, default_allow_tables determines access. Set
user security properties in each user's profile under the
Security tab.
Common patterns
Block sensitive tables
Keep the default open and block specific tables that contain sensitive data:
version: "1.0"
default_allow_tables: true
table_rules:
- table_name: audit_logs
allowed: false
- table_name: "*_pii"
allowed: false
- table_name: internal_*
allowed: falseAllowlist mode
Block everything by default and explicitly allow only the tables users need:
version: "1.0"
default_allow_tables: false
table_rules:
- table_name: products
allowed: true
- table_name: orders
allowed: true
- table_name: customers
allowed: trueDepartment-based access
Combine conditions with a default-deny policy to scope access per team:
version: "1.0"
default_allow_tables: false
table_rules:
- table_name: revenue_*
allowed: true
condition:
department: "finance"
- table_name: campaign_*
allowed: true
condition:
department: "marketing"
- table_name: company_directory
allowed: trueFinance users can query any table starting with revenue_,
marketing users can query tables starting with campaign_,
and company_directory is available to everyone.
Related
- Policy YAML Reference — full schema for glob patterns, conditions, and all policy fields
- Column Filtering Rules — hide sensitive columns from query results
- Row Filter Rules — restrict which rows users can see
Docs