Обзор
Роль — это набор разрешений: какие объекты приложение может читать или изменять, какие поля оно может видеть и какие возможности платформенного уровня оно может использовать. Функции логики и фронтенд‑компоненты каждого приложения наследуют разрешения роли, помеченной с помощьюdefineApplicationRole() (см. раздел Роль функции по умолчанию ниже).
src/roles/restricted-company-role.ts
SystemPermissionFlag.USER_APPS и SystemPermissionFlag.WORKSPACE_APPS
доступны в twenty-sdk начиная с версии 2.54; в более ранних версиях они называются
CONNECTED_ACCOUNTS и APPLICATIONS. Старые имена являются устаревшими псевдонимами
для тех же флагов, и роль содержит каждый флаг только один раз. Перечисление
SystemPermissionFlag, например с помощью Object.keys, по-прежнему включает старые
имена. API также сообщает об этих флагах под их старыми ключами, например в
currentUserWorkspace.permissionFlags.Безопасность на уровне строк
Для разрешений на уровне строк требуется план Organization или выше — см. тарифы. Что происходит при использовании плана без соответствующего права, описано в примечаниях в конце этого раздела. Разрешения на объекты и поля определяют, к каким объектам и полям у роли есть доступ. Предикаты прав доступа на уровне строк заходят дальше и определяют, какие записи роль может видеть и с которыми может работать — например, для роли самообслуживания, где каждый внешний пользователь видит только свои собственные записи. Объявляйте предикаты с помощьюrowLevelPermissionPredicates в роли. Как и остальная часть манифеста, каждый предикат имеет свой собственный universalIdentifier и ссылается на объект и поле по их universalIdentifier, operand, а также (необязательно) поле workspaceMember, значение которого подставляется во время выполнения запроса — чтобы вы могли выразить: “отношение владельца записи является текущим участником рабочей области”:
src/roles/partner-role.ts
Комбинирование предикатов с группами
По умолчанию предикаты роли комбинируются с помощьюAND. Чтобы комбинировать некоторые из них с помощью OR (или
вкладывать логику), объявите запись rowLevelPermissionPredicateGroups и укажите на неё каждый предикат через
predicateGroupUniversalIdentifier. Эта роль позволяет партнёру видеть сделку, которая либо принадлежит ему,
либо по которой он является контактным лицом:
src/roles/partner-opportunities-role.ts
- Присвойте каждому предикату и группе стабильный
universalIdentifier(любой uuid) — он служит ключом сущности между обновлениями, а предикаты ссылаются на группы по нему. - Предикаты могут ссылаться на объекты и поля, принадлежащие вашему приложению, или на стандартные объекты и поля Twenty.
- Безопасность на уровне строк применяется к рабочим пространствам на плане Organization или выше. В других планах предикаты, объявленные в манифесте приложения, по-прежнему синхронизируются, но не применяются.
- API метаданных здесь ведёт себя иначе, чем манифест: без соответствующего права
upsertRowLevelPermissionPredicatesотклоняется с ошибкойROW_LEVEL_PERMISSION_FEATURE_DISABLEDвместо синхронизации. Следовательно, рабочее пространство на плане, который не включает безопасность на уровне строк, не может создавать предикаты вне манифеста приложения, даже несмотря на то, что полеrowLevelPermissionPredicatesприсутствует в типеRoleпри интроспекции схемы.
Роль функции по умолчанию
Когда вы создаёте новое приложение с помощью шаблона, CLI создаёт файл роли по умолчанию, объявленный с помощьюdefineApplicationRole():
src/roles/default-role.ts
defineApplicationRole() — это тонкая обёртка вокруг defineRole(), которая помечает ту роль, которая используется как роль приложения по умолчанию во время установки. Проверка идентична defineRole, но конвейер сборки автоматически подключает его universalIdentifier к полю defaultRoleUniversalIdentifier манифеста приложения — поэтому вам не нужно ссылаться на него из defineApplication самостоятельно.
Заметки:
- Допускается ровно один вызов
defineApplicationRole(...)на приложение — сборка манифеста завершится с ошибкой, если будет найдено более одного. - Используйте
defineRole()(а неdefineApplicationRole()) для любых дополнительных ролей, которые ставятся вместе с вашим приложением. - Явная установка
defaultRoleUniversalIdentifierвdefineApplication()всё ещё поддерживается для обратной совместимости, но считается устаревшей по сравнению сdefineApplicationRole(). Он также может указывать роль, которую ваше приложение не определяет, например встроенную роль по умолчанию пользовательского приложения рабочего пространства, сохраняемую командойtwenty app pull; в таком случае сборка не может проверить эту роль, поэтому она должна существовать в целевом рабочем пространстве. - Роль, которую можно назначать участникам рабочего пространства или ключам API (
canBeAssignedToUsersилиcanBeAssignedToApiKeys, оба значенияtrue, если они не указаны), является пользовательской ролью и требует план Organization или выше: на других планах установка отклоняется. Оставьте оба значенияfalseдля ролей, от имени которых работают только ваше приложение и его агенты.
Роли агентов
Роль приложения — это то, что рабочее пространство проверяет при установке вашего приложения, поэтому она должна охватывать всё, что может делать само приложение. Любая роль, которую вы назначаете агенту черезroleUniversalIdentifier в defineAgent(), не должна предоставлять больше прав, чем роль приложения: никаких действий с объектами, доступа к полям, флагов разрешений или областей действия на уровне строк, которых нет у роли приложения. Если это не так, сборка завершается с ошибкой, в которой перечислены избыточные предоставленные права. Роли, которые ваше приложение предоставляет для участников рабочего пространства или ключей API, не подпадают под это правило, поскольку приложение никогда не запускается с ними. Для проверки необходима роль приложения в исходном коде вашего приложения, поэтому она пропускается, когда роль по умолчанию определена в другом месте.
Лучшие практики
- Начните с сгенерированной роли и постепенно ограничивайте её — роль по умолчанию предоставляет широкий доступ на чтение, что редко подходит для продакшена.
- Замените
objectPermissionsиfieldPermissionsна точные объекты и поля, которые действительно нужны вашим функциям. permissionFlagUniversalIdentifiersуправляют доступом к возможностям на уровне платформы. Сведите их к минимуму.- Флаг разрешения, объявляемый вашим приложением с помощью
definePermissionFlag(), имеетpermissionType:'tool'(по умолчанию) для возможности, которая может быть предоставлена агенту или пользователю, и'settings'для флага, открывающего область настроек. - Смотрите рабочий пример:
examples/hello-world/src/roles/default-role.ts.