You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/integrations/database-access-control/trino-integration.mdx
+101-3Lines changed: 101 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -134,7 +134,7 @@ For more information, see the [Trino documentation](https://trino.io/docs/curren
134
134
135
135
### Row-level Filtering
136
136
137
-
Row filters let you attach SQL predicates that Trino appends as `WHERE` clauses based on a user’s permissions:
137
+
Row filters let you attach SQL predicates that Trino appends as `WHERE` clauses based on a user's permissions:
138
138
139
139
```4:16:trino-authz-example/trino-authz.yaml
140
140
rowFilters:
@@ -157,6 +157,48 @@ You can review the [Audit Logs](https://app.permit.io/audit-log) to see the Perm
157
157
158
158
For more information, see the [Trino documentation](https://trino.io/docs/current/security/opa-access-control.html#row-filtering).
159
159
160
+
#### User-Specific Filtering with `current_user`
161
+
162
+
Filter expressions can reference Trino's [`current_user`](https://trino.io/docs/current/functions/session.html) function, enabling user-specific data access. The key pattern:
163
+
164
+
-**Permit** determines **which filter** applies (based on the user's role/permissions).
165
+
-**The SQL expression** determines **which rows** using `current_user`.
166
+
167
+
```yaml
168
+
rowFilters:
169
+
# Ensure users have only ONE of `view_all` or `view_own`, not both.
170
+
# If a user has both actions, Trino combines them with AND, resulting in `1=1 AND
171
+
# owner_id = current_user` - which only returns owned records, not all records.
172
+
trino_table_postgresql_public_orders:
173
+
- action: view_all
174
+
expression: "1=1"# Admins see everything
175
+
- action: view_own
176
+
expression: "owner_id = current_user"# Users see only their records
177
+
```
178
+
179
+
Assign `view_all` to admin roles and `view_own` to regular users in Permit. When a user queries the table, the appropriate filter is applied based on their permissions.
180
+
181
+
:::tip
182
+
For `current_user` to return the correct identity, configure [Trino authentication](#trino-authentication) (e.g., JWT) to pass the user identifier.
183
+
:::
184
+
185
+
#### Subqueries in Filter Expressions
186
+
187
+
Filters can include subqueries for more complex scoping:
188
+
189
+
```yaml
190
+
rowFilters:
191
+
trino_table_postgresql_public_documents:
192
+
- action: view_team_data
193
+
expression: "team_id IN (SELECT team_id FROM team_members WHERE user_id = current_user)"
194
+
```
195
+
196
+
This resolves team membership at query time, allowing users to see data for all teams they belong to.
197
+
198
+
:::warning
199
+
When a user has multiple filter actions, Trino chains them with `AND` (intersection). Design role assignments so users typically have one filter action per table.
200
+
:::
201
+
160
202
## Reference
161
203
162
204
### Architecture
@@ -339,9 +381,38 @@ Using that, you can combine Permit authorization for application users, and Trin
339
381
340
382
### Trino authentication
341
383
342
-
You can use Trino's several Authentication mechanisms to identify the user, like [JWT](https://trino.io/docs/current/security/jwt.html) or [OAuth2](https://trino.io/docs/current/security/oauth2.html).
384
+
You can use Trino's authentication mechanisms to identify the user, like [JWT](https://trino.io/docs/current/security/jwt.html) or [OAuth2](https://trino.io/docs/current/security/oauth2.html).
385
+
386
+
Using it, you can pass-through the user's identity to Trino, so the PDP can check against the application user's identity and permissions. This is essential for row filters that use `current_user`.
387
+
388
+
#### JWT Authentication Setup
389
+
390
+
JWT authentication allows your application to pass user identity to Trino via tokens. The user identifier extracted from the JWT becomes the value of `current_user` in Trino queries.
343
391
344
-
Using it, you can pass-through the user's identity to Trino, so the PDP can check against the application user's identity and permissions.
392
+
1. Configure Trino's JWT authentication in `/etc/trino/config.properties`:
The `principal-field` setting determines which JWT claim becomes `current_user`. Common options:
401
+
-`sub` (subject) - standard JWT claim for user identity
402
+
-`user_id` - if your tokens use a custom claim
403
+
-`email` - if using email as the user identifier
404
+
405
+
2. When your application queries Trino, include the JWT in the Authorization header:
406
+
407
+
```http
408
+
Authorization: Bearer <jwt-token>
409
+
```
410
+
411
+
3. The user identifier from the JWT is then available as `current_user` in row filter expressions.
412
+
413
+
:::tip
414
+
Make sure the user identifier in your JWT matches the format used in your row filter expressions. For example, if your `employee_id` column contains UUIDs, configure `principal-field` to extract the UUID claim from your JWT.
415
+
:::
345
416
346
417
For more information, see the [Trino authentication documentation](https://trino.io/docs/current/security/authentication-types.html).
347
418
@@ -365,3 +436,30 @@ We recommend the following performance optimizations:
365
436
- Scale the PDP cluster horizontally to handle the load.
366
437
367
438
For more information, see the [Permit PDP Deployment Models](/concepts/pdp/overview#production-deployment-models) documentation.
439
+
440
+
## FAQ
441
+
442
+
### Can I combine RBAC/ABAC with row-level filtering?
443
+
444
+
Yes. Permit's policy model (RBAC/ABAC) determines **which filter action** a user has.
445
+
The row filter SQL expression determines **which rows** they see.
446
+
For example, a "manager" role derived via RBAC could grant a `view_team_data` action that applies a team-scoped filter.
447
+
448
+
### Are row filters dynamic?
449
+
450
+
Filter expressions are static SQL defined in YAML, but they can use Trino's `current_user` function which resolves dynamically at query time. This allows `owner_id = current_user` to return different rows for different users.
451
+
452
+
### How does `current_user` get populated?
453
+
454
+
From Trino's authentication. With JWT, configure `http-server.authentication.jwt.principal-field` to specify which claim becomes `current_user`. See [JWT Authentication Setup](#jwt-authentication-setup).
455
+
456
+
### Can filters access user attributes from Permit?
457
+
458
+
Not directly. Store user-to-group mappings in a database table and use subqueries:
459
+
460
+
```yaml
461
+
rowFilters:
462
+
your_table_resource:
463
+
- action: your_action
464
+
expression: "team_id IN (SELECT team_id FROM team_members WHERE user_id = current_user)"
0 commit comments