28. Integração com o diretório
Como a organização entra na plataforma, e um teste que prova.
Duas formas de a organização entrar, e elas não são equivalentes.
Cada tenant tem o seu. O provedor (ou o LDAP) é configurado dentro do tenant, em Diretório e identidade, e vale só para ele: cada empresa entra pelo próprio diretório, e o de uma não serve a outra. Vale para os três sites do tenant — a plataforma, o portal de atendimento e o responder —, e a pessoa volta ao site de onde saiu. O provedor da instalação (o do console da instalação) é outro e não é de cliente nenhum.
OpenID Connect / OAuth 2.0 — a preferida
A senha de rede do usuário nunca chega à plataforma: o navegador vai ao provedor, o provedor fala com o Active Directory, e o GRC recebe apenas o código de autorização. Um comprometimento do GRC não expõe credencial de rede de ninguém.
LDAP direto — a alternativa
Serve quando não há gestor de identidade no meio, e é a inferior das duas: no bind a senha de rede do usuário passa pela plataforma. Por isso a conexão sem ldaps:// é sinalizada — o canal carrega a credencial como ela é.
Configurar o login da empresa (OpenID Connect ou LDAP)
A tela fica em Administração ▸ Diretório e identidade (o título da página é o mesmo do menu), com permissão admin:usuarios. Dois blocos lado a lado: OpenID Connect / OAuth 2.0 e Diretório Ativo por LDAP, cada um com o selo em uso ou inativo.
Para ligar o OpenID Connect:
1. Em Como as pessoas entram, escolha Os dois: login da empresa e senha local (recomendado), Só o login da empresa (OIDC) ou Só senha local. "Só OIDC" deixa todo mundo de fora — inclusive o administrador — se o provedor cair.
2. Preencha Emissor (realm) (ex.: https://auth.exemplo.com/realms/producao), Client ID, Segredo do cliente (em branco para cliente público, só PKCE), Redirect URI, Escopos, Claim do usuário, Claim de grupos e, se o provedor declarar o tenant no token, Claim do tenant. Escolha o Perfil padrão na lista (o recomendado é Solicitante) e, se quiser, monte o mapa Grupo do diretório → perfil (veja Perfis).
3. Clique em Testar conexão e confira os selos emissor confere, PKCE suportado e tenant no token.
4. Clique em Salvar OpenID Connect. Vale na próxima entrada, sem reiniciar: o login lê a configuração do tenant a cada vez. Teste antes de salvar, e mantenha "os dois" até confirmar que o login da empresa funciona — com "só OIDC" e um emissor errado, ninguém deste tenant entra.
Para o LDAP, preencha Servidor (prefira ldaps://), Base DN, Filtro de usuário, Bind DN, Senha de serviço, Base de grupos e Filtro de grupos, escolha o Perfil padrão na lista, marque Usar o LDAP direto e clique em Salvar LDAP.
O LDAP também é do tenant. Servidor, Base DN, Bind DN, Senha de serviço e Base de grupos são só dele: nenhuma variável de ambiente os preenche ou trava, e um tenant que não os salvou não tem LDAP. As variáveis GRC_LDAP_URL, GRC_LDAP_BASE_DN, GRC_LDAP_BIND_DN, GRC_LDAP_BIND_PASSWORD, GRC_LDAP_GROUP_BASE_DN e GRC_LDAP_ENABLED não valem para tenant nenhum — uma variável da instalação valeria para todos de uma vez. Filtro de usuário, Filtro de grupos e Perfil padrão têm o padrão da instalação (grc.ldap.*, ou seja, GRC_LDAP_USER_FILTER, GRC_LDAP_GROUP_FILTER e GRC_LDAP_DEFAULT_ROLE; de fábrica, (sAMAccountName={0}), (member={0}) e Solicitante), que vale onde o tenant deixou o campo em branco.
GRC_LDAP_ALLOW_PLAINTEXT=true continua sendo uma permissão da instalação, e não configuração de diretório: é o que deixa um servidor ldap://, sem TLS, ser usado num ambiente de teste. Sem ela, o login por ldap:// é recusado e o motivo vai para o log do servidor, porque a senha iria em claro pela rede.
Abaixo dos blocos, Como ligar o Keycloak como ponte para o Active Directory traz o passo a passo do lado do provedor, com a URL de retorno desta instalação pronta para copiar:
1. No realm, crie um cliente OpenID Connect com Standard flow (Authorization Code) e PKCE method S256.
2. Em Valid redirect URIs, informe a URL de retorno que a tela mostra.
3. Adicione um mapper de grupos com nome de claim groups (nomes com caminho, como /GRC/Analistas, são aceitos).
4. Preencha os campos da tela, use Testar conexão e só então tente entrar. A Redirect URI é a do endereço deste tenant (ex.: https://empresa.exemplo.com/oidc/callback), e é ela que vai em Valid redirect URIs — cada tenant registra a sua no provedor dele.
5. Em Grupo do diretório → perfil, ligue cada grupo do AD ao perfil da plataforma e salve. Em Perfis de acesso se define o que cada perfil pode fazer — o grupo só escolhe o perfil.
O provedor é do tenant, e só dele
Emissor, client ID, segredo e redirect URI são de cada tenant, e nenhuma variável de ambiente os preenche ou trava: um tenant sem provedor salvo entra só com senha local. GRC_OIDC_SCOPES, GRC_OIDC_USERNAME_CLAIM, GRC_OIDC_ROLE_CLAIM e GRC_OIDC_DEFAULT_ROLE, quando definidas, são só o padrão dos campos que o tenant deixou em branco. GRC_OIDC_ISSUER não liga o login de ninguém: serve para validar tokens de serviço quando a instalação usa GRC_AUTH_MODO=oidc ou ambos. Se o provedor declara o tenant numa claim (Claim do tenant), ela tem de bater com o tenant do endereço — um token de outra empresa não abre sessão aqui.
Quem entra pelo provedor pela primeira vez, sem convite, e não casa com nenhum grupo mapeado recebe o perfil padrão — Solicitante, se o tenant não escolher outro: abre chamado no portal e lê e pergunta sobre documentos, e nada mais. Quem veio por convite entra com o perfil do convite (Colaborador, por padrão), que também responde no /responder. Para dar mais, mapeie o grupo ou troque o perfil da pessoa em Usuários; a troca manual fica, a menos que um grupo mapeado diga outra coisa na próxima entrada.
Conta local com o mesmo login
A entrada pelo provedor acha a pessoa pelo login que o token traz, e só entra em conta de origem externa — a que o próprio provedor criou na primeira entrada, ou a que nasceu de um convite aceito pelo diretório. Nunca entra em conta local, a que tem senha guardada na plataforma, nem quando a pessoa chega com um convite. Há provedor que deixa cada um escolher o próprio nome de usuário, e vincular pelo login entregaria o admin do tenant a quem criasse lá um usuário admin. (Origem não é o Tipo da tela de Usuários: uma conta local pode ser do tipo Interno ou Externo.)
Quando o login do provedor coincide com uma conta local, a entrada é recusada. A pessoa lê que já existe uma conta local com aquele login e que o administrador da organização precisa resolver; o log do servidor registra o tenant, o login e a conta. A conta local não é alterada.
A plataforma não tem ação que transforme conta local em externa, nem que troque o login de uma conta. Para resolver:
• A pessoa continua na conta local: entra com login e senha, como antes. Desativar a conta local não libera o login para o provedor — ela continua existindo.
• A pessoa passa a entrar pelo provedor: faça o provedor mandar um login que não colida — outro nome de usuário para ela no provedor, ou a Claim do usuário apontando para uma claim única, como o e-mail (essa troca vale para todo o tenant). Na primeira entrada nasce a conta externa; dê a ela o perfil e os grupos em Usuários e desative a conta local antiga.
• O login precisa continuar o mesmo: quem administra a instalação, com acesso ao banco, renomeia o login da conta local (iam.usuario.login, por exemplo admin para admin.local); a próxima entrada pelo provedor cria a conta externa com o login que ficou livre.
O segredo do cliente e a senha de serviço nunca saem do servidor. A tela mostra se eles existem, nunca o valor, e o campo em branco mantém o que já está gravado: segredo que a tela desenha é segredo que vaza pelo print, pelo log do navegador e pela captura do suporte.
No banco, os dois ficam cifrados (AES-GCM, com o prefixo v1:), e não em claro: quem lê o banco ou um backup não vê as credenciais dos diretórios. A chave é a da instalação — GRC_CONSOLE_CHAVE, senão GRC_INTEGRACAO_CHAVE, senão uma chave sorteada e guardada no banco na primeira vez. Trocar a chave (ou restaurar a base noutra instalação) faz o segredo guardado deixar de abrir: ele passa a valer como não configurado, o log do servidor diz por quê, e é preciso informar o segredo do cliente e a senha de serviço de novo nesta tela. Trate a chave como parte do backup da instalação.
O que a entrada pelo provedor confere
O id_token que volta do provedor é conferido como ele pede: a assinatura, pelas chaves que o provedor publica no jwks_uri do documento de descoberta; o emissor; a audiência, que tem de ser o client ID deste tenant; e a validade, com um minuto de folga de relógio. Token de outro emissor, emitido para outro cliente ou vencido não abre sessão, e a razão fica escrita. O provedor precisa publicar jwks_uri: sem as chaves, a assinatura não tem como ser conferida, e a entrada é recusada. O Testar conexão não olha esse campo; se a entrada falhar dizendo isso, confira o documento de descoberta do provedor.
A ida ao provedor fica no banco (core.entrada_oidc_pendente, por dez minutos), e não na memória de uma instância: com várias instâncias atrás do balanceador, a volta pode cair em qualquer uma. A tabela tem RLS por tenant, então a volta só acha o pedido pelo endereço do mesmo tenant de onde a pessoa saiu. A chave da linha é o hash do state, e não o state.
O teste de conexão
Busca o documento de descoberta do emissor, e é o que separa três coisas que a tela de login mostra como o mesmo erro:
Sintoma | O que é |
|---|---|
HTTP 404 | realm errado no emissor |
responde, emissor diverge | o realm existe e não é o que se pensava |
não responde | rede bloqueada, ou provedor fora |
Ele também confere duas coisas que só aparecem depois:
• PKCE, que é o que protege o código de autorização em cliente público.
• O claim do tenant, se houver. O tenant vem do endereço por onde a pessoa entrou, e o provedor é o daquele tenant. A claim é uma conferência a mais, opcional: preenchida, um token que declara outro tenant não abre sessão aqui; em branco, vale só o endereço.
Perfis
O mapa Grupo do diretório → perfil, no bloco OIDC, é do tenant: cada empresa tem os próprios grupos. Cada linha liga um grupo (com caminho, como /GRC/Analistas, ou só o nome) a um perfil escolhido na lista — os de fábrica e os que o tenant criou em Perfis de acesso. + Grupo acrescenta uma linha, Tirar remove, e o mapa vale a partir da próxima entrada de cada pessoa, quando é salvo com Salvar OpenID Connect. Enquanto o tenant não grava o próprio mapa, a tela mostra o padrão da instalação e diz que é esse o caso. Um perfil que não existe no tenant é recusado na gravação, e o mapa aceita até 200 grupos.
Um grupo mapeado para um perfil com escrita dá escrita a todo mundo do grupo: revise antes de salvar. Quem autentica e não casa com grupo nenhum fica com o perfil padrão — de fábrica, o Solicitante, que só usa o portal e não consome licença: autenticar no diretório não deve, por si, conceder escrita sobre auditoria.
O Mapeamento por grupo do LDAP continua declarado na configuração da implantação (grc.ldap.role-mappings) e aparece só à vista.
No LDAP, sem nenhum mapeamento o mapeamento por grupo fica desligado e todos entram com o perfil padrão — mesmo com a base de grupos preenchida. A tela avisa quando é esse o caso.