Começar
Aparência

Vale na hora e fica lembrada neste navegador.

A plataforma

12 · Identidade e acesso

Toda aplicação com área restrita é autenticada no Keycloak do toolbox e autoriza por permissões que ela mesma declara. Pessoas recebem acesso por perfis, atribuídos por grupos. Outras aplicações recebem acesso por contas de serviço. Tudo isso é declarado no repositório e documentado por aplicação.

O modelo em um diagrama

O modelo de acesso, dentro de um realm (um por população). A pessoa entra num grupo; o grupo recebe um perfil; o perfil, declarado pelo client da aplicação, reúne permissões; o código confere as permissões. Ninguém recebe papel direto no usuário. Quando toda a população tem o mesmo acesso, o perfil vai para os default roles do realm. O login pode vir de um IdP externo, como o Google. Outra aplicação recebe permissões api pela sua conta de serviço. realm · um por populaçãopessoasatendimento-gestoresgrupoclient da aplicaçãoperfil:gestorperfil (composto)chamado:lerchamado:atendercatalogo:editarcatalogo:publicarpermissõesentra emrecebeo códigoconferepapel direto no usuário: nuncadefault rolestodo usuário do realmperfil padrãoGoogleIdP externo,opcionallogin porconta de serviçode outra aplicaçãoapi:chamado:ler
ConceitoNo KeycloakQuem criaQuem atribui
RealmNo Keycloak: realmQuem cria: toolbox (ADR lá)Quem atribui: —
Client da aplicaçãoNo Keycloak: client confidencialQuem cria: eng/auth/provision.sh da stackQuem atribui: —
Permissão <recurso>:<ação>No Keycloak: client role do client da aplicaçãoQuem cria: provision.shQuem atribui: só via perfil
Perfil perfil:<nome>No Keycloak: client role compostoQuem cria: provision.shQuem atribui: via grupo
Grupo <produto>-<perfil-plural>No Keycloak: grupo do realmQuem cria: provision.shQuem atribui: administrador do realm põe as pessoas
Perfil padrãoNo Keycloak: default-roles-<realm> inclui o perfilQuem cria: provision.shQuem atribui: automático, todo usuário do realm
Conta de serviçoNo Keycloak: service account de outro clientQuem cria: provision.sh da aplicação consumidoraQuem atribui: recebe permissões do client provedor

Aplicação pública

Nem toda aplicação tem usuários: um site, uma landing, uma página de documentação podem ser públicos, sem login. Isso é uma decisão declarada, não uma omissão:

Tipo de aplicaçãoIdentidadeO que se declara
RestritaIdentidade: client no Keycloak, <app>:acessar e pelo menos um perfil desde a fundaçãoO que se declara: docs/acesso/<app>.md completo
PúblicaIdentidade: nenhuma; sem client, sem sessãoO que se declara: na ficha e em docs/acesso/<app>.md: "pública", o que ela expõe e o que nunca pode expor (dado de usuário, rota de administração)
MistaIdentidade: client e permissões só para a parte restritaO que se declara: as rotas públicas listadas uma a uma; o resto exige login

Toda aplicação, pública ou não, cumpre o contrato de observabilidade e tem /up.

Regras

  1. Realm por população, não por aplicação. Colaboradores da Hibex em hibex-team; clientes externos em realm de produto (ex.: hibex-enterprise). Colaborador e cliente nunca no mesmo realm (toolbox ADR-0008). Criar realm é decisão do toolbox;
  2. Um client por aplicação, confidencial, Authorization Code com PKCE S256, directAccessGrantsEnabled=false, redirect e post-logout redirect exatos (produção + localhost);
  3. O código confere permissões, nunca perfis. O perfil é organização de pessoas; o código não muda quando um perfil ganha ou perde uma permissão;
  4. Ninguém recebe papel direto no usuário. Perfil vai para grupo (toolbox ADR-0034); quando toda a população tem o mesmo acesso, o perfil vai para os default roles do realm — e isso também é declarado;
  5. A aplicação lê resource_access.<client-id>.roles do access token, sem chamada extra por requisição;
  6. Sem senha nem sessão local. O Keycloak autentica: a aplicação não tem login, senha nem cadastro de usuário próprios. Ela pode, sim, manter uma sessão (um cookie), mas essa sessão guarda só os tokens do Keycloak e expira com eles; nunca é uma conta da aplicação;
  7. Sem acesso de negado mudo. Autenticado sem permissão vê uma página que diz qual perfil (e qual grupo) dá acesso;
  8. Configuração como código. eng/auth/provision.sh <realm> é idempotente: cria o que falta, atualiza o que existe, reexecutar não muda nada; nunca regenera segredo de client (só lê e imprime para guardar no Bitwarden);
  9. IdP externo (Google) por script, com credenciais do ambiente — nunca no export do realm versionado; um OAuth client do Google por realm;
  10. Realms de desenvolvimento versionados em eng/auth/dev-realms/, gerados a partir do provision.sh, com um usuário de exemplo por perfil (senha = primeiro nome) e um usuário sem nenhum perfil, e segredos de client óbvios (dev-secret-<client>).

Ambientes e realms

Uma stack tem dois ambientes: o local, com o Keycloak descartável do Compose e os realms de desenvolvimento da regra 10, e a produção, com os realms reais. O toolbox já criou o hibex-enterprise-dev (a ADR-0039 de lá), um realm na instância real para ambientes implantados de desenvolvimento do produto Hibex Enterprise. Por enquanto, nenhuma stack o usa: um ambiente implantado de desenvolvimento pede ainda um realm para os colaboradores (não há um hibex-team-dev, e o hibex-team nunca serve de bancada de testes), um host, um valor de deployment.environment e um projeto no Bitwarden. A arquitetura o define quando a primeira stack precisar testar implantada. Até lá, o provision.sh já recebe o realm como argumento (regra 8): é o que permite, depois, rodá-lo em outro realm sem mudar o script.

Login, do clique ao acesso

O login em seis quadros: 1, o usuário abre uma rota; 2, a aplicação o manda ao Keycloak, com Authorization Code e PKCE; 3, ele entra — ou pelo Google, se o realm aceita; 4, volta à aplicação com um code; 5, a aplicação troca o code por tokens e lê as permissões; 6, se tem a permissão da rota, vê a página; se não, vê um 403 que diz qual perfil e qual grupo dão acesso. 1abre uma rota2a aplicação o manda ao KeycloakappKeycloak302Authorization Code + PKCE3entra no Keycloak (ou pelo Google)IdP externo, se houver4volta à aplicação com um codeappKeycloakcode5troca o code por tokensaccess tokenresource_access.<client>.rolesvira as permissões6tem a permissão? entra200peça operfil gestorno grupoatendimento-gestores403 que explica

Permissões e perfis: como desenhar

Um exemplo de desenho de acesso: as pessoas entram nos grupos atendimento-gestores, atendimento-analistas e atendimento-financeiro; cada grupo recebe um perfil (gestor, analista, financeiro); o perfil gestor reúne chamado:ler, chamado:atender, catalogo:editar e catalogo:publicar; o analista, chamado:ler e carteira:ler; o financeiro, carteira:ler e carteira:conceder. gruposonde as pessoas entramperfiso que se atribuipermissõeso que o código confereatendimento-gestoresatendimento-analistasatendimento-financeiroperfil:gestorperfil:analistaperfil:financeirochamado:lerchamado:atendercatalogo:editarcatalogo:publicarcarteira:lercarteira:conceder

(Exemplo ilustrativo, no produto fictício de 03. O modelo pede o desenho fino desde o início, mesmo que a primeira versão tenha um perfil com todas as permissões — assim um perfil novo não exige mexer no código.)

Orientações:

  • Permissão nomeia um recurso e uma ação do ponto de vista do negócio: carteira:conceder, não POST /carteiras. Ações típicas: ler, criar, editar, excluir, mais verbos do domínio (publicar, atender, aprovar);
  • Perfil nomeia um papel de trabalho reconhecível pelas pessoas: gestor, analista, financeiro, cliente;
  • O mínimo de toda aplicação com usuários: uma permissão de entrada (<app>:acessar) e um perfil;
  • Permissões de API (para outras aplicações) têm o prefixo api: — ex.: api:chamado:ler —, para nunca se confundirem com permissões de tela.

O documento de acesso de cada aplicação (docs/acesso/<app>.md)

Cada aplicação tem o seu. É o documento que o administrador do realm, o mantenedor e uma equipe de outra aplicação leem para saber "quem pode o quê". Estrutura obrigatória:

Markdown
# Acesso — <app>

## Resumo
| Realm | Client | Endereço | Perfil padrão |
|---|---|---|---|

## Permissões
| Permissão | O que permite | Telas / rotas | Desde (change) |
|---|---|---|---|
| chamado:ler | ver a lista e o detalhe dos chamados | /chamados, /chamados/{id} | identidade |

## Perfis
| Perfil | Para quem | Grupo | Permissões |
|---|---|---|---|
| perfil:gestor | quem conduz os atendimentos | atendimento-gestores | chamado:ler, chamado:atender, … |

## Matriz perfil × permissão
| Permissão \ Perfil | gestor | analista | financeiro |
|---|---|---|---|
| chamado:ler | ✓ | ✓ | |

## Como dar acesso a uma pessoa
1. No realm <realm>, Usuários → a pessoa → Grupos → entrar em <grupo>;
2. A pessoa sai e entra de novo (o token novo traz o perfil).

## Como outra aplicação obtém acesso à API desta
(permissões `api:*`, audiência, exemplo de token — ver seção do guia)

## Usuários de desenvolvimento
| Usuário / senha | Perfil | Serve para |
|---|---|---|
| ana.souza / ana | gestor | caminho feliz da gestão |
| bruno.dias / bruno | nenhum | ver o 403 explicativo |

## Histórico
| Data | Change | O que mudou no acesso |

A seção Matriz é verificada de ponta a ponta pelo agrupamento E2E identidade: um caso por perfil confere o que ele vê e o que não vê.

Acesso entre aplicações

Quando uma aplicação B precisa chamar a API da aplicação A (de outra stack ou da mesma), o padrão é client credentials com a conta de serviço de B recebendo permissões api:* do client de A.

A aplicação B chama a API da aplicação A: 1, B pede um token ao Keycloak com client_credentials, pela sua conta de serviço; 2, recebe um token com audiência a e a permissão api:chamado:ler; 3, chama a API de A com o token; 4, A confere o emissor, a assinatura, a audiência e a permissão, e responde 200. No Keycloak, o client a declara a permissão, a conta de serviço de b a recebe e um mapper põe a na audiência. aplicação Bclient b, comconta de serviçoKeycloakclient a declara api:chamado:lera conta de serviço de b a recebemapper: aud inclui "a"aplicação Aresource serveremissorassinaturaaud contém "a"api:chamado:ler200client_credentials12token: aud=[a]roles=[api:chamado:ler]GET /api/chamados + Bearer34token de usuário nunca é repassado entre aplicações

Quem faz o quê:

PassoRepositório
Declarar a permissão api:chamado:ler no client aRepositório: stack de A (eng/auth/provision.sh)
Documentar a permissão na seção "Como outra aplicação obtém acesso"Repositório: stack de A (docs/acesso/a.md)
Criar o client b com conta de serviço, dar a ela api:chamado:ler de a, e o mapper de audiênciaRepositório: stack de B (eng/auth/provision.sh)
Validar o token como resource server (emissor, aud, permissão)Repositório: stack de A (código + teste de integração)

Regras: a aplicação provedora nunca confia num token sem aud próprio; tokens de usuário não são repassados entre aplicações (cada chamada de serviço usa a conta de serviço de quem chama).

eng/auth/: identidade como código

Identidade como código em eng/auth: o provision.sh é a fonte normativa e idempotente. O mantenedor o roda contra o Keycloak real. O dev-realms.sh o roda dentro de um Keycloak descartável e exporta os realms de desenvolvimento, com um usuário por perfil e segredos óbvios; o Compose e os testes importam esses exports. O Google local é opcional e fica fora do Git. O README diz o que cada aplicação precisa. provision.shfonte normativa, idempotenteREADME.mdo que cada app precisaKeycloak realsó o mantenedor rodaAdmin RESTdev-realms.shnum Keycloak descartáveldev-realms/*.jsonum usuário por perfil, dev-secret-*Keycloak localcompose.yamlKeycloak dos testesem containerimportagoogle-dev.localfora do Git, opcional
ArquivoPapel
README.mdPapel: Tabela, por aplicação, de client, redirects, permissões, perfis, grupos, IdPs — legível sem acesso ao Keycloak
provision.shPapel: Cria/atualiza client, permissões, perfis (compostos), grupos, vínculos, default roles, mappers de audiência, IdP (se houver credenciais). Imprime o segredo do client uma vez, para o Bitwarden
dev-realms.shPapel: Sobe um Keycloak descartável, cria os realms, roda o provision.sh, cria os usuários de exemplo, fixa os segredos de dev e exporta
dev-realms/*.jsonPapel: Os exports, importados pelo Compose e pelos testes
google-dev.sh + google-dev.localPapel: IdP Google local, opcional

Mudou acesso? A change mexe no provision.sh, roda o dev-realms.sh, confere o diff dos JSON, atualiza docs/acesso/<app>.md e os casos do agrupamento identidade.

Em produção (guia docs/guias/identidade.md)

Roteiro que o mantenedor segue; o agente só o escreve.

Em produção, o mantenedor segue sete passos: confere que o realm existe no toolbox; exporta a URL e o usuário de administração (a senha vem por prompt); traz do Bitwarden as credenciais do IdP, se houver; roda o provision.sh; guarda no Bitwarden o segredo do client que ele imprime; põe as pessoas nos grupos; faz o deploy e testa o login com cada perfil. o mantenedor roda; o agente só escreve o guiao realm existe no toolbox?senão: ADR e provisionamento lá1export KEYCLOAK_URL,KC_ADMIN_USERa senha vem por prompt2credenciais do IdPdo Bitwarden, se houver3eng/auth/provision.sh<realm>idempotente4guardar o segredo do clientno Bitwarden5pôr as pessoas nos grupos6deploye login com cada perfil7

Funcionalidades de identidade que se repetem

Oferecidas como guia (não obrigatórias):

FuncionalidadeComo
Portão de primeiro acesso (preferências obrigatórias antes de usar)Como: filtro após a autorização, preservando o deep link
Edição de nome pelo próprio usuárioComo: Account API do Keycloak com o token do usuário (aud: account), sem conta administrativa
Entrada direta no IdP a partir de uma landingComo: kc_idp_hint num ponto de entrada público
Logout completoComo: RP-initiated logout com post-logout redirect para uma página pública
Diretório interno de usuáriosComo: registro próprio com id interno, sincronizado a cada login (nunca o sub como chave de negócio)