Resource Grants
Vincent Depassier · 30 de agosto de 2026
Los row filters responden "qué filas puede ver esta persona". Los resource grants responden otra pregunta: ¿puede esta persona participar de esa cosa?
Un canal de chat. Un tablero. Una llamada. Un hilo de documento. Son objetos que inventó tu app, y la plataforma no tiene idea de qué son — pero igual tiene que controlar el acceso, porque el Event Bus y las llamadas necesitan saber quién puede entrar.
Por qué existe esto
La alternativa se probó y falló de una forma instructiva.
El hub de tiempo real respondía "¿puede este usuario final entrar a este canal?" leyendo tres tablas concretas de una app concreta. Eso significaba que el primitivo de tiempo real supuestamente genérico funcionaba para exactamente un producto, y negaba en silencio toda suscripción de todos los demás.
Praxsuite es la plataforma; una app construida sobre ella es un tenant. Los nombres de tabla de un tenant no tienen nada que hacer dentro de la plataforma. Los resource grants son el arreglo: tu app declara quién puede alcanzar sus objetos, y la plataforma hace cumplir esa declaración sin enterarse nunca de qué es un "canal".
Por eso resourceType es un string libre que elegís vos — "channel", "board", "dm-thread" — y no un enum que mantenemos nosotros. La plataforma nunca debería necesitar un cambio de código para aprender un tipo nuevo de objeto.
La forma de un grant
resourceType + resourceId → beneficiario → nivel de acceso
"channel" 9f2c8ab1… una persona participateParte | Notas |
| El nombre que tu app le da a este tipo de objeto. Se compara sin distinguir mayúsculas, así que |
| El objeto puntual — un UUID que apunta a una fila de tu propia tabla. Sin foreign key, a propósito. |
Beneficiario |
|
Nivel de acceso |
|
any significa todos los usuarios finales autenticados de tu app, dicho explícitamente. No es lo mismo que no tener ningún grant: la ausencia de grants significa denegado, nunca público.
La API
POST /{workspaceId}/resources/{resourceType}/{resourceId}/grants declarar uno
PUT /{workspaceId}/resources/{resourceType}/{resourceId}/grants reemplazar toda la lista
DELETE /{workspaceId}/resources/{resourceType}/{resourceId}/grants revocar uno, o todos
GET /{workspaceId}/resources/{resourceType}/{resourceId}/grants leer la listaPOST https://gateway.praxsuite.com/{workspaceId}/resources/channel/9f2c8ab1-.../grants
Authorization: Bearer sk_live_xxxxxxxx
{ "grantee": "endUser", "endUserId": "…", "accessLevel": "participate" }Las cuatro requieren una API key. Un token de usuario final se rechaza aunque autentique perfectamente — si no, cualquier persona logueada podría otorgarse a sí misma un recurso, y toda la lista de acceso sería decorativa. Declarar acceso es un acto administrativo, así que toma una credencial administrativa.
La lectura es solo con key por la misma razón: la lista de miembros de un canal privado no es algo que un miembro deba poder enumerar.
Preferí PUT
POST es idempotente por beneficiario, así que volver a declarar un grant existente no lo duplica. Pero PUT reemplaza toda la lista en una llamada, y eso es casi siempre lo que realmente querés.
La razón vale decirla: cuando cambia el acceso, volver a declarar la membresía completa del recurso es mucho más fácil de hacer bien que calcular qué grants agregar y quitar. Un diff calculado por cada app es un diff que cada app puede equivocar — y equivocarlo significa que alguien conserva un acceso que debería haber perdido.
Entonces: cuando cambia la membresía de un canal, mandá la membresía nueva. No calcules el delta.
Dónde se aplican
El Event Bus, para tópicos en modo Per bus: el segmento de instancia de la clave del bus es el resourceId, y entrar requiere read mientras que publicar requiere participate. Un recurso que declarás una vez queda alcanzable por todos los transportes, sin declarar nada dos veces.
El permiso se vuelve a verificar en cada publicación, no solo al entrar — así que revocar un grant expulsa a los peers que ya no califican en vez de dejar que un socket abierto sobreviva al chequeo que lo admitió.
Desde una automatización
La mayoría de las apps no llaman a esta API a mano. El nodo de automatización Manage Resource Grants lo hace como parte del mismo flujo que crea el objeto, que es el lugar correcto: el momento en que existe un canal es el momento en que se conoce su membresía.
Recomendaciones
Declará los grants cuando creás el recurso, en la misma automatización. Un recurso que existe sin grants es un recurso que nadie puede alcanzar — incluida la persona que acaba de crearlo.
Otorgá a roles cuando puedas. "Todos los que tengan el rol Soporte" sobrevive a los cambios de equipo; una lista de personas sueltas no.
Reafirmá, no calcules diferencias.
PUTcon la lista completa en cada cambio.Acordate de que `manage` no es gratis. Es el nivel que le permite a un beneficiario cambiar la propia lista de acceso.
Siguiente
Event Bus — donde el modo Per bus usa estos grants.
Roles de Gateway — los roles que un grant puede nombrar.