# Row-access filters > Restrict which rows a user can see using semantic-layer access filters enforced in compiled SQL and by Postgres row-level security *[View this page in the Flax docs](https://flax-analytics.com/docs/modeling/row-access-filters)* Row-access filters restrict which rows a user sees, based on their attributes — so a regional manager only ever queries their own region's data. This page shows how to declare them and how they're enforced. Defining access filters is an admin/modeling task. ## How they work You declare `access_filters` under a model's `flax:` key. Each filter pairs an org-authored SQL expression with a **user attribute**: at query time the compiler keeps only rows where the expression matches one of the caller's server-trusted values for that attribute. ```yaml models: - name: orders flax: access_filters: - sql: ${region} attribute: region ``` If the caller's `region` attribute is `["EMEA"]`, the compiler AND-s a predicate keeping only rows where `region = 'EMEA'` into the query — as a bind parameter, never interpolated text. ## Closed by default Access filters fail safe. If a caller has **no value** for a filter's attribute, the compiler emits a `1=0` predicate, so the query returns **no rows**. There is no way to opt out of a filter by lacking the attribute. > [!IMPORTANT] > Because filters are closed by default, make sure every user who should see data actually has the required attribute set. A missing attribute means an empty result, not full access. Models without any `access_filters` are unaffected — the filter only applies where you declare it. ## Defence in depth Access filters are enforced in two independent layers: - **In compiled SQL.** The predicate is added to every query the semantic layer compiles, on every warehouse dialect. - **By Postgres row-level security.** For the Postgres-backed path, row-level security policies enforce the same restriction at the database, so the boundary holds even outside the normal query path. The attribute values come from the caller's server-trusted principal — they are never taken from the client request, so a user cannot widen their own access. ## Where attributes come from Filters reference **user attributes**, which are managed by admins. See: - [User attributes](/docs/administration/user-attributes) — defining and assigning the attribute values filters read. - [Data entitlements](/docs/administration/data-entitlements) — the broader model for who can access which data. ## Related - [Semantic YAML reference](/docs/modeling/semantic-yaml-reference) — the `access_filters` schema. - [SQL compilation](/docs/modeling/sql-compilation) — how filters enter the query. - [Security](/docs/administration/security).