Félix Malfait 5d88cf7f2f feat(server): add role management tools for AI chat (#23613)
Adds role management tools to the AI chat so the agent can create and
configure roles, including row-level permissions.

## What

A `RoleToolProvider` in `tool-provider/providers/`, mirroring
`webhook-tool.provider.ts`, registered in `tool-provider.module.ts` and
gated behind `PermissionFlagType.ROLES` via
`PermissionsService.checkRolesPermissions` (same pattern as the
VIEWS/WORKFLOWS gating). Tools:

- `list_roles` — global record permissions, settings access, per-object
overrides, permission flags, assignability; optionally includes
row-level rules
- `create_role`, `update_role`, `delete_role`
- `assign_role_to_workspace_member` — via
`UserRoleService.assignRoleToManyUserWorkspace`, which goes through
role-target
- `upsert_object_permissions` — per-object overrides, e.g. read-only on
a given object
- `upsert_row_level_permission_rules` — reuses
`RowLevelPermissionPredicateService.upsertRowLevelPermissionPredicates`
and the predicate-group service, so the agent can express rules like
"members with this role only see records where the owner field matches
the current user" (a predicate with `workspaceMemberFieldMetadataId`
pointing at the workspaceMember `id` field, resolved to the current user
at query time)

Everything routes through the existing role services and DTOs
(`RoleService`, `ObjectPermissionService`, `UserRoleService`, the
row-level predicate services) rather than reimplementing them. A new
`ToolCategory.ROLE` is added to `twenty-shared`, along with its label in
the exhaustive switch in `build-tool-catalog-section.util.ts`.

## Safeguards

- Any mutation on a role with `isEditable: false` is rejected. That
covers the Admin role, which is created non-editable, and matches what
Settings blocks.
- Deleting the role the caller is currently acting under is rejected,
since deletion would rebind them to the workspace default role.
- Setting `canUpdateAllSettings: false` on the caller's own role is
rejected unless that role keeps an explicit ROLES permission flag.
- Changing your own role via `assign_role_to_workspace_member` is
rejected, checked both by workspace member id and by resolved user
workspace id.

The tool-layer checks are deliberate pre-checks: the migration
validators and services enforce the same rules downstream
(`validate-role-is-editable.util.ts`, default-role deletion, last-admin
unassignment, write-without-read consistency), but catching them early
gives the model a named, actionable message instead of a build failure
report. Where the deeper layer does reject, `formatValidationErrors`
expands the migration exception so the underlying per-entity errors
reach the model rather than a generic summary.

Worth flagging for reviewers: the self-lockout protection currently
lives only at the tool layer. A human admin can still strip settings
access from their own role through Settings/GraphQL. Closing that would
mean changing `RoleService`/`UserRoleService` behavior for the human
path, which felt like a separate decision than what this change is
scoped to.

## Notes

`ToolCategory.ROLE` is intentionally left out of
`WORKFLOW_AGENT_REGISTRY_TOOL_CATEGORIES`, so workflow agents don't get
these tools; only the chat surface and the MCP/tool-index paths that
share the registry do.

## Testing

- 24 unit tests in `providers/__tests__/role-tool.provider.spec.ts`,
covering permission gating, descriptor exposure, each safeguard, the
N+1-free list path, and validation-error surfacing
- 333 tests pass across the tool-provider, role, object-permission and
ai suites
- `npx nx lint:diff-with-main twenty-server` and `npx nx typecheck
twenty-server` are clean


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

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/23613?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-31 11:49:23 +00:00
2026-06-11 11:02:28 +02:00

Twenty logo

The #1 Open-Source CRM

Website · Documentation · Roadmap · Discord · Figma

Twenty banner


Why Twenty

Twenty gives technical teams the building blocks for a custom CRM that meets complex business needs and quickly adapts as the business evolves. Twenty is the CRM you build, ship, and version like the rest of your stack.

Learn more about why we built Twenty


Installation

Cloud

The fastest way to get started. Sign up at twenty.com and spin up a workspace in under a minute, with no infrastructure to manage and always up to date.

Build an app

Scaffold a new app with the Twenty CLI:

npx create-twenty-app my-app

Define objects, fields, and views as code:

import { defineObject, FieldType } from 'twenty-sdk/define';

export default defineObject({
  nameSingular: 'deal',
  namePlural: 'deals',
  labelSingular: 'Deal',
  labelPlural: 'Deals',
  fields: [
    { name: 'name', label: 'Name', type: FieldType.TEXT },
    { name: 'amount', label: 'Amount', type: FieldType.CURRENCY },
    { name: 'closeDate', label: 'Close Date', type: FieldType.DATE_TIME },
  ],
});

Then ship it to your workspace:

npx twenty app:publish --private

See the app development guide for objects, views, agents, and logic functions.

Self-hosting

Run Twenty on your own infrastructure with Docker Compose, or contribute locally via the local setup guide.



Everything you need

Twenty gives you the building blocks of a modern CRM (objects, views, workflows, and agents) and lets you extend them as code. Here's a tour of what's in the box.

Want to go deeper? Read the User Guide for product walkthroughs, or the Documentation for developer reference.

Create your apps

Learn more about apps in doc

Stay on top with version control

Learn more about version control in doc

All the tools you need to build anything

Learn more about primitives in doc

Customize your layouts

Learn more about layouts in doc

AI agents and chats

Learn more about AI in doc

Plus all the tools of a good CRM

Learn more about CRM features in doc


Stack

Thanks

Greptile      Sentry      Crowdin

Thanks to these amazing services that we use and recommend for code review (Greptile), catching bugs (Sentry) and translating (Crowdin).

Join the Community

Star the repo · Discord · Feature requests · Releases · X · LinkedIn · Crowdin · Contribute

S
Description
The open alternative to Salesforce, designed for AI.
Readme AGPL-3.0 1.4 GiB
Languages
TypeScript 79.6%
MDX 17.3%
JavaScript 2.7%
Python 0.2%
SCSS 0.1%