> For the complete documentation index, see [llms.txt](https://docs.toucanai.cloud/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.toucanai.cloud/build/security-and-governance/column-level-security-cls.md).

# Column-Level Security (CLS)

{% hint style="info" %}
**Target Audience**: Non technical users & Developers
{% endhint %}

#### TL;DR

Control which columns a user can see by grouping columns into sections and applying include or exclude rules based on User Attributes from authentication tokens.

***

#### When to use it

Use CLS when you need to restrict column visibility without duplicating dashboards or charts, such as:

* **PII protection**: Hiding personal identifiers (e.g., email, phone) from most users.
* **Compensation data**: Exposing salary or bonus columns only to HR or finance roles.
* **Admin-only fields**: Showing internal metadata columns only when a role attribute matches a privileged value.
* **Compliance**: Enforcing least-privilege access at the column level alongside row filters.

***

#### Core Functionality

The CLS engine evaluates column visibility at query time and injects a `select` step so only authorized columns are returned. It supports:

* **Column sections**: Group specific columns and assign an include or exclude effect.
* **Catch-all column section**: Covers every column not claimed by another sections, including columns added to the table later.
* **Conditional rules**: Apply an effect only when a User Attribute satisfies a condition (e.g., `role is equal to HR`).
* **Logic grouping**: Combine conditions with `AND` and `OR` blocks within a section.
* **Runtime enforcement**: Applies to charts, AI answers, and access-rule previews.

Unlike RLS, CLS conditions compare a **User Attribute** (left operand) against a **literal value** (right operand), not a dataset field.

***

#### Prerequisites

* **Connected Database**: An active connection.
* **User Attributes**: Custom attributes defined in **Settings > Embed & access / User Model**(scalar types only: String, Boolean, Integer, Numeric, Date).

***

#### Policy model

Since policies are usually shared among columns, we regrouped them by sections. Each section lists columns, an effect (`included` or `excluded`), and optional conditions.

There's an automatic section listed last, the **catch-all section**, to target all remaining columns and those that'll be added in the future. Like other sections, it also applies an effect (`all` = include, `none` = exclude).

When you add a column to a section, it'll be removed from the section it was in. When removing a column, it'll flow back to the catch-all section, so all columns are always explicitely covered.

When you add conditions to a section, it switches to an **included if…** form: conditions are always evaluated inclusively for simplicity.

***

#### Types and Properties

Operators are filtered based on the **User Attribute** type selected in the condition.

**Operator availability by attribute type**

| **Attribute type** | **Available operators**                                                                                                                                |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| String             | `is equal to`, `is different from`, `is in`, `is not in`                                                                                               |
| Boolean            | `is equal to`, `is different from`, `is in`, `is not in`                                                                                               |
| Integer, Numeric   | `is equal to`, `is different from`, `is greater than`, `is greater than or equal to`, `is less than`, `is less than or equal to`, `is in`, `is not in` |
| Date               | `is after`, `is before`, `is in`, `is not in`                                                                                                          |

***

#### Where to use it

CLS is configured within the **Databases** section of the platform:

1. Navigate to a specific table in your schema.
2. Select the **Access Rules** tab.
3. In the column-level section (above row-level rules), configure the catch-all or add **column sections**.
4. For each section, select columns, set the effect, and optionally add conditions on User Attributes.

***

#### Constraints

* **Scalar attributes only**: Array and date-range token attributes cannot be used in CLS conditions.
* **No existence operators**: Unlike RLS, CLS does not support `is set` or `is not set`.
* **Chart subsets**: CLS applies to the columns requested by a chart; rules only affect columns present in the query.
* **Read-Only**: CLS only impacts data extraction; Toucan.ai never writes back to the source database.

***

#### Relationship with RLS

RLS and CLS are complementary and both apply at query time:

1. **RLS** filters which **rows** a user can access (dataset field vs. User Attribute).
2. **CLS** filters which **columns** are returned (User Attribute vs. literal value).

Configure both on the same **Access Rules** tab. For a step-by-step setup guide, see [Apply CLS to your database](/embed/permissions-and-row-level-security/how-to/apply-cls-to-your-database.md).

For RLS operator details, see [Row-Level Security (RLS) operators](/build/security-and-governance/row-level-security-rls-operators.md).
