API de roles de organización
Los roles de una organización determinan qué puede hacer cada miembro. Toda organización tiene siempre
cuatro roles de sistema — owner, admin, member, viewer — cuyos conjuntos de permisos vienen
con el producto y no pueden modificarse. Una organización en un plan que incluye roles personalizados
también puede definir sus propios roles personalizados, cada uno con su propio nombre y conjunto de
permisos, y asignarlos a los miembros de la misma forma en que asigna un rol de sistema.
El campo role de un rol en la API siempre es una cadena de texto simple (slug): los cuatro roles de
sistema usan sus nombres fijos (owner, admin, member, viewer); el slug de un rol personalizado
se elige al crearlo y no puede cambiarse después (ver Renombrar un rol más abajo).
Los conjuntos de sistema los fija el producto: viewer no tiene ningún permiso del catálogo —
todos los endpoints de escritura de la API se lo niegan con 403 forbidden, mientras que su acceso de
lectura no cambia porque las lecturas se autorizan por acceso al proyecto, no por rol. member tiene
el conjunto de lectura/escritura para el trabajo de prueba del día a día; admin y owner tienen el
conjunto completo, incluidos los permisos que controlan la gestión a nivel de organización y de proyecto
(por ejemplo projects.manage, que exige POST /api/v1/projects — un member no puede crear un proyecto).
Listar roles
Sección titulada «Listar roles»/api/v1/orgs/{orgUlid}/rolesCualquier miembro de la organización puede llamar a este endpoint — leer la lista solo requiere ser
miembro, no ningún permiso en particular ni una característica del plan, porque un cliente lo necesita
para mostrar un selector de roles. La respuesta es una única página sin paginar (una organización tiene
como máximo 54 roles: cuatro roles de sistema más un tope de 50 roles personalizados) que contiene un
arreglo items con todos los roles, de sistema y personalizados, cada uno con:
| Campo | Notas |
|---|---|
ulid | Identificador asignado por el servidor |
slug | El identificador estable del rol — lo que referencian los campos role en otros lugares |
name | Nombre para mostrar |
description | Opcional, o null |
isSystem | true para uno de los cuatro roles fijos |
isDefault | true para el rol predeterminado de la organización (ver más abajo) |
permissions | Los nombres de permiso efectivos del rol |
memberCount | Cantidad de membresías aceptadas que actualmente tienen el slug de este rol (las invitaciones pendientes no se cuentan) |
Junto a items, el sobre de la respuesta también incluye:
| Campo | Notas |
|---|---|
customRolesEnabled | Si el plan de esta organización incluye roles personalizados — un dato del plan de la propia organización de quien llama, presente en esta lectura sin importar los permisos de quien llama |
Crear un rol
Sección titulada «Crear un rol»/api/v1/orgs/{orgUlid}/rolesRequiere el permiso de gestión de roles de la organización (que tienen owner/admin) y que el
plan de la organización incluya roles personalizados. Ambas condiciones deben cumplirse; ver
Dos condiciones, una sola respuesta de rechazo más abajo.
| Campo | Requerido | Notas |
|---|---|---|
slug | sí | Minúsculas, dígitos y guiones, 1–63 caracteres. No puede ser owner, admin, member ni viewer |
name | sí | 1–80 caracteres |
description | no | Hasta 500 caracteres |
permissions | sí | Arreglo de nombres de permiso del catálogo — puede estar vacío |
isDefault | no | Convierte este rol en el predeterminado de la organización (ver más abajo) |
Un slug duplicado dentro de la organización, o uno de los cuatro slugs reservados, devuelve
409 conflict. Una organización que ya tiene 50 roles personalizados recibe 409 conflict al
intentar crear el 51.º.
Actualizar un rol
Sección titulada «Actualizar un rol»/api/v1/orgs/{orgUlid}/roles/{roleUlid}Misma condición de acceso que crear. Un rol personalizado acepta name, description, permissions
e isDefault. Un rol de sistema acepta únicamente isDefault — cualquier otro campo devuelve
403 forbidden y no cambia nada, porque el conjunto de permisos de un rol de sistema lo fija el
producto, no los datos.
Renombrar un rol
Sección titulada «Renombrar un rol»El slug de un rol no puede cambiarse después de crearlo. Una solicitud que incluya la clave
slug se rechaza con 422 validation_failed, sin importar su valor. Para renombrar un rol, envía su
nuevo name — el nombre para mostrar es el campo al que en realidad se refiere un “renombrado”. Todo
miembro que ya tenga asignado el rol sigue funcionando sin cambios; solo cambia la etiqueta.
El rol predeterminado
Sección titulada «El rol predeterminado»Exactamente un rol de la organización es el predeterminado — el rol que un cliente puede
preseleccionar al invitar a alguien, y el objetivo de reasignación al eliminar un rol sin indicar un
reemplazo (ver más abajo). El predeterminado comienza siendo viewer. Establecer isDefault: true
en otro rol mueve el predeterminado allí de forma atómica; la marca del predeterminado anterior se
borra en la misma solicitud. Borrar el único predeterminado (poner isDefault: false en él sin que
otro rol pase a ser el predeterminado) devuelve 409 conflict — una organización siempre tiene
exactamente un predeterminado.
Eliminar un rol
Sección titulada «Eliminar un rol»/api/v1/orgs/{orgUlid}/roles/{roleUlid}Misma condición de acceso que crear. Solo puede eliminarse un rol personalizado — un rol de sistema, o
el rol predeterminado actual de la organización, devuelven 403/409 respectivamente. La respuesta es
200 con un cuerpo JSON (nunca 204), porque los conteos exactos del cuerpo son lo que permite que
una solicitud reintentada reproduzca la respuesta en lugar de repetir la operación.
{ "reassignedTo": "member", "reassignedMemberCount": 3 }Todo miembro e invitación pendiente que tenga el rol eliminado pasa a reassignTo — indicado
explícitamente en el cuerpo de la solicitud, o el rol predeterminado de la organización si se omite.
Omitir el destino puede rechazar una eliminación que esperabas que funcionara
Sección titulada «Omitir el destino puede rechazar una eliminación que esperabas que funcionara»Omitir reassignTo no siempre se acepta. El respaldo al rol predeterminado de la organización solo
se aplica cuando los permisos de ese predeterminado son un subconjunto de los del rol que se elimina —
mover miembros a un rol “menor” siempre es seguro; moverlos a un rol que otorga algo nuevo no es algo
que la API haga en silencio. Si el predeterminado no califica, la solicitud se rechaza con
422 validation_failed, señalando reassignTo como el campo que debe indicarse explícitamente. Esto
nunca elimina una capacidad: indicar el destino explícitamente en la solicitud siempre funciona, porque
eres tú quien toma la decisión explícita. Solo evita que los miembros de un rol ganen permisos en
silencio porque no se indicó ningún destino.
Dos condiciones, una sola respuesta de rechazo
Sección titulada «Dos condiciones, una sola respuesta de rechazo»Crear, actualizar y eliminar un rol personalizado requieren tanto el permiso de gestión de roles como
que el plan de la organización tenga habilitada esa característica. Un 403 forbidden de cualquiera
de estos tres endpoints nunca revela cuál de las dos condiciones faltó — el permiso o la
característica del plan. Esto es deliberado: una respuesta distinguible permitiría a cualquiera
averiguar qué organizaciones tienen un plan con roles personalizados. Si recibes un 403 aquí y crees
que tienes el rol de organización correcto, consulta con el propietario de tu organización si el plan
incluye roles personalizados antes de asumir que la API está fallando.
Leer la lista de roles (GET) nunca está condicionado por el plan — toda organización, en cualquier
plan, siempre puede ver sus cuatro roles de sistema y cualquier rol personalizado que ya tenga.