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 does not 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 | Does Not 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 does not 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 does not 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