Ir al contenido

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).

GET/api/v1/orgs/{orgUlid}/roles

Cualquier 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:

CampoNotas
ulidIdentificador asignado por el servidor
slugEl identificador estable del rol — lo que referencian los campos role en otros lugares
nameNombre para mostrar
descriptionOpcional, o null
isSystemtrue para uno de los cuatro roles fijos
isDefaulttrue para el rol predeterminado de la organización (ver más abajo)
permissionsLos nombres de permiso efectivos del rol
memberCountCantidad 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:

CampoNotas
customRolesEnabledSi 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
POST/api/v1/orgs/{orgUlid}/roles

Requiere 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.

CampoRequeridoNotas
slugsíMinúsculas, dígitos y guiones, 1–63 caracteres. No puede ser owner, admin, member ni viewer
namesí1–80 caracteres
descriptionnoHasta 500 caracteres
permissionssíArreglo de nombres de permiso del catálogo — puede estar vacío
isDefaultnoConvierte 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.º.

PATCH/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.

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.

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.

DELETE/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.