Minhas permissões — API
Três rotas de autoatendimento para o próprio usuário autenticado consultar suas permissões
efetivas, sem precisar de nenhuma permissão RBAC além de estar autenticado. Não exigem
tenantId/unitId na URL — o usuário é sempre o dono do access token (sub do JWT).
Funcionamento
GET /me/permissions: devolve as permissões decodificadas em nomes legíveis (exam:read,report:writeetc.), agrupadas emglobal(união de tudo),tenants[](por tenant) eunits[](por unidade). Se o usuário forplatformAdmin,globalcontém todo o catálogo de permissões etenants/unitsvêm vazios — o administrador de plataforma não tem escopo por tenant, tem tudo.GET /authorization/my-permissions: devolve o mesmo tipo de informação em formato cru (bitmask decimal porscope_id, maisplatform_admin,role_idse arevisionatual). É o formato pensado para um client que já sabe decodificar bitmasks e quer decidir localmente sem round-trip a cada checagem, e para alimentar o polling demy-permissions/changed.GET /authorization/my-permissions/changed: recebe a últimarevisionque o client observou e devolvechanged: true/falsemais arevisionatual. É a forma barata de saber se vale a pena chamarmy-permissionsde novo, sem decodificar nada — cada mutação relevante (papel atribuído/revogado, permissões de um papel alteradas, atribuição expirada recalculada) incrementa esse contador (authorization_version) para o usuário afetado.
As duas primeiras rotas não aceitam nenhum parâmetro: o usuário-alvo é sempre extraído do próprio
token (accessToken.subject), nunca de um path ou query parameter — não há como consultar a
permissão de outro usuário por aqui (para isso, ver
Atribuição de papéis ou
Inspeção de autorização).
Endpoints
| Método | Rota | Descrição |
|---|---|---|
| GET | /v1/me/permissions | Permissões efetivas do usuário autenticado, por nome, agrupadas por tenant/unidade |
| GET | /v1/authorization/my-permissions | Bitmask efetivo do usuário autenticado, por escopo, com revision |
| GET | /v1/authorization/my-permissions/changed | Compara uma revision conhecida com a atual |
Versão: v1
Swagger: readIdentityOwnPermissions · Identity effective permissions · Rota (Dev): http://localhost:3000/v1/authorization/my-permissions
Permissões
| Rota | Guards | Permissão RBAC exigida |
|---|---|---|
GET /me/permissions | IdentityOAuthAccessTokenGuard | Nenhuma — só autenticação |
GET /authorization/my-permissions | IdentityOAuthAccessTokenGuard | Nenhuma — só autenticação |
GET /authorization/my-permissions/changed | IdentityOAuthAccessTokenGuard | Nenhuma — só autenticação |
Nenhuma das três rotas usa AuthorizationGuard/@Authorize — a única checagem é "existe um
access token válido", porque o recurso consultado é sempre o do próprio ator.
Headers
| Header | Obrigatório | Descrição |
|---|---|---|
Authorization | Sim | Bearer <access_token> |
Path parameters
Nenhum.
Query parameters
GET /authorization/my-permissions/changed — IdentityAuthorizationRevisionRequest:
| Nome | Tipo | Obrigatório | Validação |
|---|---|---|---|
revision | string numérica | Sim | @Matches(/^\d+$/) — string de dígitos, não um número JSON |
Body
Nenhum (todas as rotas são GET).
Response
GET /me/permissions — 200 (EffectiveIdentityPermissionsResponse):
json{"data": {"isPlatformAdmin": false,"global": ["exam:read", "report:read"],"tenants": [ { "scopeId": "1f2a...uuid", "permissions": ["exam:read", "report:read"] } ],"units": [ { "scopeId": "9b3c...uuid", "permissions": ["exam:read"] } ]}}
GET /authorization/my-permissions — 200 (IdentityOwnPermissionsEnvelopeResponse):
json{"data": {"platform_admin": false,"role_ids": ["0198f1a2-...uuid"],"tenants": [ { "scope_id": "1f2a...uuid", "mask": "17" } ],"units": [ { "scope_id": "9b3c...uuid", "mask": "1" } ],"revision": "12"}}
GET /authorization/my-permissions/changed — 200:
json{ "data": { "changed": true, "revision": "13" } }
Mapa de campos
| Campo | Tipo | Onde aparece | Descrição |
|---|---|---|---|
global | string[] | /me/permissions | União de todas as permissões do usuário, em todo escopo; catálogo completo se platformAdmin |
tenants[].scopeId / scope_id | uuid | ambas | ID do tenant |
units[].scopeId / scope_id | uuid | ambas | ID da unidade |
mask | string (bigint) | /authorization/my-permissions | Bitmask decimal daquele escopo — decodificável com o catálogo de bits |
revision | string numérica | /authorization/my-permissions e .../changed | Contador de versão da autorização do usuário; muda a cada mutação relevante de papel/atribuição |
role_ids | uuid[] | /authorization/my-permissions | IDs dos papéis ativos atribuídos ao usuário (qualquer escopo) |
Erros
| Classe de erro | errorCode | Status | Quando ocorre |
|---|---|---|---|
| (validação de query) | BAD_REQUEST | 400 | revision ausente ou não numérica em .../changed |
UnauthenticatedError | IDENTITY_INVALID_OAUTH_ACCESS_TOKEN | 401 | access token ausente/inválido |
ForbiddenAction | AUTHORIZATION_CLAIM_UNAVAILABLE | 403 | usuário sem claim de autorização ativa (/authorization/my-permissions e .../changed) |
GET /me/permissions não lança 403 quando a claim está indisponível — devolve
EffectiveIdentityPermissions.none() (tudo vazio, isPlatformAdmin: false) com 200. Essa é
uma divergência de comportamento confirmada entre as duas rotas irmãs: uma trata "sem claim" como
erro, a outra como "sem permissão nenhuma".
Regras de negócio
| ID | Regra | Comportamento esperado |
|---|---|---|
| RN-01 | O usuário-alvo é sempre o dono do token | nenhuma das três rotas aceita consultar outro usuário |
| RN-02 | platformAdmin vê o catálogo inteiro em global, sem tenants/units | reflete que um admin de plataforma não está escopado a tenant/unidade |
| RN-03 | /me/permissions nunca falha por falta de claim | devolve o "estado vazio" com 200, ao contrário de /authorization/my-permissions |
| RN-04 | revision é o mecanismo de invalidação de cache do client | qualquer mutação de papel/atribuição/política que afete o usuário incrementa a revision; o client deve rechamar my-permissions quando changed: true |
Compliance
Não se aplica. Rotas de leitura do próprio usuário, sem exigência regulatória adicional além da
autenticação já aplicada por IdentityOAuthAccessTokenGuard.
Variáveis de ambiente
Nenhuma variável de ambiente é consumida diretamente por estas rotas.
Tempo médio de resposta
A confirmar — responsável: time de Identity; data: 24/09/2026. Sem medição publicada.
Requisitos não funcionais
| Requisito | Definição |
|---|---|
| Idempotência | Sim (leitura pura) |
| Paginação | Não se aplica |
| Rate limit | Não identificado |
| Cache | A claim subjacente usa cache distribuído com fallback ao Postgres (ver visão geral do módulo); estas rotas não têm cache HTTP próprio |
| Auditoria | Não — rotas de leitura, sem evento de auditoria |
Relacionado
- 📂 Módulo: Authorization
- 🔁 Ver também: Atribuição de papéis (quem concede o que está sendo lido aqui) e Inspeção de autorização (a mesma informação, mas consultável sobre outro usuário, por um administrador)