Autenticação e RBAC

Como o backend autentica, resolve tenant e acesso, aplica o RBAC declarado e publica o catálogo de perfis — e o que o frontend faz (e não faz) com isso.

Plataforma

Na plataforma, o backend:

  1. verifica o token no escopo do App;
  2. resolve tenant e acesso junto à Central de Ativações;
  3. aplica a política local de RBAC declarada em central.app.json;
  4. cria req.accessContext.

O frontend usa permissões somente para experiência; o backend autoriza cada operação.

Login

Sem sessão, o App mostra a própria tela de login (/login?redirect=…), que autentica pela Central — inclusive quando alguém abre a URL do ambiente direto ou a sessão expira (0.7.37). Para manter o login centralizado em outro lugar, como no Meus Apps, declare a URL em auth.loginUrl no defineOonApp; api.meusAppsUrl é só o endereço do Meus Apps e não é usado como login.

defineOonApp({
  // ...
  auth: { loginUrl: "https://meus-apps.exemplo.com/login" }, // opcional: login externo
});

Abertura pelo Meus Apps

A abertura por oon_launch (vinda do Meus Apps) valida a nova sessão antes de persistir token e tenant; seleção anterior não acompanha o handshake e logout/login posterior cancelam a troca pendente. Desde 0.7.10, login e launch validam o token sem header de tenant anterior.

Declarando o RBAC

{
  "rbac": {
    "permissions": ["pedidos.read", "pedidos.write", "pedidos.approve"],
    "roles": [
      { "code": "admin", "name": "Administrador", "admin": true, "permissions": ["*"] },
      { "code": "comprador", "name": "Comprador", "description": "Cria e acompanha pedidos.", "permissions": ["pedidos.read", "pedidos.write"] },
      { "code": "aprovador", "name": "Aprovador", "permissions": ["pedidos.read", "pedidos.approve"] },
      { "code": "viewer", "name": "Consulta", "permissions": ["pedidos.read"] }
    ]
  }
}

Regras de validação em Manifesto do App. Em resumo: permissões no formato recurso.acao, ao menos um perfil administrativo, e "*" só em perfis admin: true.

Aplicando no backend

Onde Como
CRUD crud.permissions: { read, write } em defineModel
Rota privada router.private.post(path, { permission }, handler)
Composição Express middleware requirePermission(permission)
Avaliação programática rbacPolicy, roleByCode, permissionGranted, CORE_PERMISSIONS

Refletindo no frontend

<Can permission="pedidos.approve"><button>Aprovar</button></Can>

Rotas (permissions), itens de menu (permissions), colunas, abas e ações também aceitam permissões — sempre como experiência.

Catálogo público de perfis

Todo App com RBAC expõe:

GET /core/role-catalog
{
  "schemaVersion": 1,
  "appCode": "central-compras",
  "enabled": true,
  "roles": [
    { "code": "viewer", "name": "Consulta", "description": "Somente leitura.", "admin": false, "commercialPermissions": ["pedidos.read"] }
  ]
}
  • Serve à descoberta e seleção de perfis pelo Control Plane; não concede acesso.
  • Cache público de cinco minutos.
  • Desde 0.7.1, commercialPermissions publica permissões funcionais explícitas. Wildcards são expandidos somente pelas permissões declaradas; "*" literal e os namespaces tenant, publications, homologation, production, apps, users e roles são excluídos.
  • Comandos comerciais de concessão, convite e aceite falham fechado com APP_ROLE_CATALOG_UNAVAILABLE quando o catálogo está ausente.

Não mantenha códigos de perfil paralelos no frontend ou no Control Plane.

Token de integração

O principal com integrationAccess validado pela Central recebe as permissões do perfil do RBAC do App, sem perfis administrativos nem permissões de gestão. Um token de integração com perfil administrativo só é aceito quando a Central o marca como admin, o ambiente é desenvolvimento ou homologacao, coincide com APP_ENVIRONMENT e a validade é de no máximo 24 horas; caso contrário, INTEGRATION_ROLE_NOT_ALLOWED.

Regras para extensões

  • use { permission } em rotas customizadas;
  • derive filtros de req.accessContext;
  • nunca autorize por header/body de perfil ou tenant;
  • não implemente verifyToken em Centrais member/portal;
  • não persista bearer no frontend;
  • não trate simulação local como identidade operacional;
  • não decodifique claims no navegador para autorizar acesso.