Column-Level Security
What this covers
Column-level security restricts which columns a persona can see. It works through data tag restrictions: you tag sensitive columns, then configure a persona to be restricted from specific tags. At query time, the persona gate either blocks the query (if a restricted column is explicitly requested) or silently excludes the column (if it would have been auto-included via SELECT *). This article explains how the mechanism works, how to configure it, and how it composes with row-level security.
How it works
Column-level security is a two-layer system:
- Data tags label columns by sensitivity (e.g.
PII,Financial). See Data Tags. - Persona tag restrictions define which tags a persona cannot access.
When a query arrives under a persona:
- If the query explicitly requests a column tagged with a restricted tag → the query is rejected with a 403 error.
- If the query uses SELECT * and a restricted column would be included → the column is silently dropped from the result set.
Relationship to row-level security
Row security and column security are independent axes that compose:
| Axis | Controls | Mechanism |
|---|---|---|
| Row security | Which rows a user sees | WHERE clause filters injected by the security rule compiler |
| Column security | Which columns a user sees | Column exclusion based on persona tag restrictions |
A persona can have both row rules and column restrictions. They apply simultaneously: first the column gate narrows the visible columns, then the row security filter narrows the visible rows. Neither depends on the other.
Setting restrictions
- Open the persona in the Personas panel (Toolbelt → Personas → click the persona name).
- Scroll to the Column Restrictions section.
- Toggle the data tags that this persona should NOT see. Each toggled tag restricts all columns assigned to it.
- Click Save.
What happens at query time
Explicit column request
If a persona restricted from PII runs:
SELECT customer_name, email, revenue FROM sales
And email is tagged PII, the query is rejected:
403 Forbidden: Column 'email' is restricted by tag 'PII' for persona 'External Partner'.
SELECT * (auto-inclusion)
If the same persona runs:
SELECT * FROM sales
The email column is silently excluded from the result. The persona sees customer_name, revenue, and all other non-restricted columns. No error is raised.
Worked example
Scenario: An "External Partner" persona should not see PII data.
- Create the PII tag: In Data Tags, create a tag named
PII. - Assign columns: Tag
customers.email,customers.phone,orders.shipping_addressasPII. - Create the persona: In Personas, create "External Partner".
- Set restrictions: In the persona's Column Restrictions, toggle
PIIto restricted. - Test: Query as the persona.
SELECT *returns all columns except email, phone, and shipping_address.SELECT email FROM ...returns 403.
Pitfalls
- New columns are visible by default. When you add a column to a table that has tagged columns, the new column is untagged and therefore visible to all personas. Always review new columns after schema changes.
- Calculated measures that depend on restricted columns. If a calculated measure references a restricted column in its expression, the measure will fail for restricted personas. Either remove the dependency or don't restrict the column.
- Tag assignment is model-scoped. Restricting
PIIin one model doesn't affect another model, even if they share the same source tables. Each model's tags and restrictions are independent.