Files
twenty/packages
Félix Malfait 1cba0cdf49 fix(server): apply row-level security predicates to API key and application principals (#22456)
## What

Row-level security predicates were only resolved for **user**
principals. For API key and application principals, object-level and
field-level permissions were resolved (via
`resolveRolePermissionConfig`), but the row-level predicate role was
left `undefined`, so:

- on the read path, `buildRowLevelPermissionRecordFilter` returned
`null` and no `WHERE` clause was added; and
- on the write path, `validateRLSPredicatesForRecords` returned early
and skipped post-write validation.

The result was that a role carrying row-level predicates constrained
users as intended, but the same role applied to an API key or installed
application was subject only to its object/field permissions — not its
row filters.

## Changes

- Add `resolveRoleIdFromAuthContext`, a single helper that resolves the
effective role id for user, API key, and application principals.
- Use it in `applyRowLevelPermissionPredicates` (read) and
`validateRLSPredicatesForRecords` (write) so row-level predicates are
enforced for all principal types.
- Thread `apiKeyRoleMap` through `WorkspaceInternalContext` (it was
already available on the ORM workspace context).
- Refactor `resolveRolePermissionConfig` to reuse the same helper, so
object-, field-, and row-level checks all resolve the role identically.

`workspaceMember`-relative predicate values are still only bound for
user contexts (API keys/applications have no workspace member), matching
existing behaviour.

## Notes

- Enterprise-gated RLS code paths only.
- Could not run `nx typecheck`/lint in this environment (dependencies
not installed); changes reviewed manually. CI will validate.

https://claude.ai/code/session_01N2RkG8aMwgfFU2jBghMgCQ

---
_Generated by [Claude
Code](https://claude.ai/code/session_01N2RkG8aMwgfFU2jBghMgCQ)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22456?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-02 12:11:04 +00:00
..
2026-07-01 20:56:54 +02:00