Role hierarchy, permissions, and how they gate API endpoints.
Reten implements hierarchical Role-Based Access Control (RBAC) with granular permissions grouped by domain. The tables below list every permission, grouped by the same domains the API uses; a user with several roles holds the permissions of all of them.
Permissions and roles are written as the value the API sends and receives: activity:view, admin. That is the value you send in the permissions of POST /api/api-keys and in the roles of POST /api/auth/register, and the one the API returns in a 403 — Required permissions: activity:view.
Each role has its own explicit list of permissions: a higher role does not automatically hold every permission of the roles below it (for example, supervisor has activity:force-retry-dispatch and fde does not). The hierarchy governs user management: a user can only manage users whose role is strictly lower than their own.
View AGCs and their lifecycle pillars (incl. per-pillar configHashes)
super_admin, admin
activity-generation-config:create
Create an AGC with its 3 lifecycle pillars
super_admin, admin
activity-generation-config:update
Update AGC metadata, replace lifecycle pillars in place, publish and pause
super_admin, admin
activity-generation-config:delete
Archive an AGC (cascades to its lifecycle configs)
super_admin, admin
lifecycle-config:view
View the read-only lifecycle configs (activation / engagement / resurrection)
super_admin, admin
lifecycle-config:delete
Internal — gates lifecycle archive/restore in the trash cascade
super_admin, admin
Lifecycle configs have no standalone create/edit/delete permissions: a lifecycle config is created and edited only through the AGC flow, gated by activity-generation-config:create / activity-generation-config:update.
Edit the channel definitions of a dispatch provider: recommended payload mapping and settings, and whether a mapping is required (PATCH /api/dispatch-providers/:providerId/channel-definitions/:definitionId)
View archived records in the trash and restore them (/api/trash). Viewing a record's detail or cascade preview and restoring it also require the permission that deletes that kind of record (for example, commerce:delete). Permanently deleting a record from the trash is limited to super_admin
super_admin, admin, fde
trash:manage-settings
View and change the tenant's trash retention settings (GET and PATCH /api/trash/settings)
super_admin, admin
commerce:delete
Delete commerces, which moves them to the trash (DELETE /api/commerces/:id)
super_admin, admin, fde
operator:delete
Delete operators, which moves them to the trash (DELETE /api/operators/:id)
super_admin, admin, fde
route:delete
Delete routes, which moves them to the trash (DELETE /api/routes/:id)
super_admin, admin, fde
supervisor:delete
Delete supervisors, which moves them to the trash (DELETE /api/supervisors/:id)
The retention engine that computes commerce lifecycle states reads AGCs programmatically. It uses an API key (no new auth mechanism) carrying activity-generation-config:view. With that permission it calls GET /api/activity-generation-configs and GET /api/activity-generation-configs/:id to read each pillar and its configHashes (to cheaply detect when a config changed), then writes the computed states back via commerce lifecycle snapshots. Both AGC endpoints are project-scoped: with a tenant key, every call sends x-project-id (without it the API responds 400 — Falta el header obligatorio x-project-id.), and a project key only reads the AGCs of its own project — see Key scope.
JWT auth and tenant keys: provide the x-project-id header with the project UUID. On project-optional endpoints the header is optional and narrows the request to that project
Project keys: the key always works in its own project, so the header is not needed (see Key scope)