defineApplicationRole() (see The default function role below).
src/roles/restricted-company-role.ts
Row-level security
Object and field permissions decide which objects and fields a role can touch. Row-level permission predicates go further and decide which records a role can see and act on — for example, a self-service role where each external user sees only their own records. Declare predicates withrowLevelPermissionPredicates on the role. Like the rest of the manifest,
each predicate carries its own universalIdentifier, and references an object and a field by their
universalIdentifier, an operand, and (optionally) a workspaceMember field whose value is injected
at query time — so you can express “the record’s owner relation is the current workspace member”:
src/roles/partner-role.ts
Combining predicates with groups
By default a role’s predicates are combined withAND. To combine some of them with OR (or to
nest logic), declare a rowLevelPermissionPredicateGroups entry and point each predicate at it via
predicateGroupUniversalIdentifier. This role lets a partner see an Opportunity it either owns
or is the point of contact for:
src/roles/partner-opportunities-role.ts
- Give every predicate and group a stable
universalIdentifier(any uuid) — it keys the entity across upgrades, and predicates reference groups by it. - Predicates can reference objects and fields owned by your app or by Twenty’s standard objects.
- Row-level security is enforced for workspaces on plans that include it; the predicates still sync on other plans, they are simply not enforced.
The default function role
When you scaffold a new app, the CLI creates a default role file declared withdefineApplicationRole():
src/roles/default-role.ts
defineApplicationRole() is a thin wrapper around defineRole() that flags the role used as your application’s default at install time. Validation is identical to defineRole, but the build pipeline auto-wires its universalIdentifier into the application manifest’s defaultRoleUniversalIdentifier — so you do not need to reference it from defineApplication yourself.
Notes:
- Exactly one
defineApplicationRole(...)is allowed per app — the manifest build will fail if it finds more than one. - Use
defineRole()(notdefineApplicationRole()) for any additional roles your app ships. - Setting
defaultRoleUniversalIdentifierexplicitly ondefineApplication()is still supported for backward compatibility, but is deprecated in favor ofdefineApplicationRole().
Best practices
- Start from the scaffolded role, then progressively restrict it — the default grants broad read access, which is rarely what you want in production.
- Replace
objectPermissionsandfieldPermissionswith the exact objects and fields your functions actually need. permissionFlagUniversalIdentifierscontrol access to platform-level capabilities. Keep them minimal.- See a working example:
hello-world/src/roles/function-role.ts.