Login no NKP com o Microsoft Entra ID: do app registration ao acesso por grupo

Publicado
Leitura
16 min

Testado emNKP 2.19Kubernetes 1.36.2Microsoft Entra ID FreeLab em Em outra versão, confira a matriz de compatibilidade e as release notes antes de aplicar.

Read in English

Capa do post: Login no NKP com o Microsoft Entra ID, acesso por grupo no painel e no kubectl

Resumo: o NKP 2.19 do lab passou a aceitar o login com as contas do Microsoft Entra ID, e as políticas de login do Entra, como o MFA, passaram a valer também para o painel e para o kubectl. Do Identity Provider salvo ao primeiro login pelo Entra foram 12 minutos. O acesso é dado a grupos, nunca a pessoas: três grupos do Entra viraram três perfis no NKP, testados com usuários reais. A Ana administra toda a plataforma, o Bruno opera só o cluster do workspace dele e a Carla trabalha só no namespace do projeto. Uma quarta conta, sem grupo, autentica e não vê nada. Tudo funcionou com o Entra ID na licença gratuita. O post mostra a configuração dos dois lados, os papéis certos para cada perfil e as boas práticas que deixaram cada um pronto.

O resultado em uma tabela

Usuário (grupo no Entra)Papéis no NKPNo painelNo kubectl (cluster de serviços)
Ana (nkp-plataforma-admins)Global: Cluster Admin Role + dkp-kommander-adminTudo: 4 workspaces, 2 clusters, Administrationcan-i '*' '*' = yes; vê os 6 nós
Bruno (nkp-servicos-operadores)Workspace: role customizada “Operador do Cluster (full)” + Kommander Workspace AdminSó o workspace de serviços e o cluster delecreate deployments em todos os namespaces = yes
Carla (nkp-servicos-devs)Global: dkp-kommander-view · Workspace: Kommander Workspace View · Projeto: App Deployer + Kommander Project EditSó o workspace de serviços e o projeto delayes no namespace do projeto, no no default, nós proibidos
Eva (sem grupo)NenhumAutentica no Entra e recebe “Not Authorized”—
Admin local do NKPSenha localPainel completo o tempo todoKubeconfig de certificado

O admin local e os kubeconfigs de certificado continuaram funcionando durante toda a configuração. É o acesso de emergência (break-glass) caso o login pelo Entra fique indisponível.


Como a identidade funciona no NKP

O NKP usa o Dex, um provedor OpenID Connect que roda uma vez só, no cluster de management. Os clusters de workload não têm Dex próprio: cada um recebe um kube-oidc-proxy (para o kubectl) e um traefik-forward-auth (para as interfaces web), que confiam no Dex central.

Três consequências práticas:

  1. O Entra cuida da autenticação (senha, MFA, bloqueio da conta). O NKP cuida da autorização (o que cada grupo pode fazer).
  2. Os API servers não mudam. Conferi no lab: nenhum tem flags --oidc-*. O OIDC entra pelo kube-oidc-proxy, então não há reinício do control plane.
  3. No NKP, permissão é dada a grupo. A própria tela de bindings avisa: “Both groups and roles must be defined before setting up cluster role bindings”. A ordem é sempre: grupo do Entra → grupo do NKP → papel → binding.

Edições do NKP

O login pelo Dex (RBAC e single sign-on) está em todas as edições: Starter, Pro e Ultimate. Workspaces e projetos, usados nos cenários do Bruno e da Carla, são do NKP Ultimate, a licença do lab. No Pro e no Starter, o mesmo resultado sai com RBAC nativo do Kubernetes, aplicando os bindings cluster a cluster.


O que preparar antes

ItemPor quêComo conferi no lab
Um tenant do Entra IDO NKP conversa com um tenantEntra ID Free: app registration, grupos e Security Defaults (MFA) estão incluídos
Domínio verificado (opcional)Logins com o domínio da empresalab.leimar.dev verificado com um registro TXT
Usuários com o atributo Email preenchidoO NKP usa o e-mail como nome do usuário; sem ele, o login não concluiPerfil de cada usuário → Contact information → Email
Grupos de Segurança no EntraO token carrega os grupos4 grupos, um por perfil
Saída do management para login.microsoftonline.com e graph.microsoft.com (443)É o pod do Dex que chama a Microsoft, não o navegadorPod de teste no namespace kommander: 20 de 20 respostas HTTP 200
Acesso de emergênciaSe o login pelo Entra falhar, você não fica sem acessoAdmin local do NKP + kubeconfig de certificado nos dois clusters
Relógio sincronizado (NTP)Tokens têm validade; relógio errado faz o token ser rejeitadoBastion e API servers no mesmo segundo

Visão geral do tenant de testes no Entra ID, com a licença Microsoft Entra ID Free

Propriedades do tenant com os Padrões de segurança (Security Defaults) habilitados, que trazem o MFA na licença gratuita

Faça antes: teste a saída do management

Um pod temporário no namespace kommander com curl para https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration responde em segundos se a rede está certa. Faça isso antes de abrir o formulário do NKP: um bloqueio de DNS ou proxy aparece aqui, e não no meio do primeiro login.


1. O app no Entra ID

O NKP precisa de um app registration no Entra, que vira o “cliente” OIDC do Dex.

  1. App registrations → New registration: nome nkp-dex, Accounts in this organizational directory only.
  2. Redirect URI (Web): https://<endereço-do-nkp>/dex/callback. No lab, https://nkp.lab.exemplo.local/dex/callback. O navegador resolve o nome interno; o Entra só exige https.

Registro do app nkp-dex no Entra ID, com locatário único e Redirect URI terminando em /dex/callback

  1. Token configuration:
    • Add groups claim → Security groups, formato Group ID no ID token;
    • Add optional claim (ID token) → email e upn.

Configuração de token do app: claims email, groups e upn

  1. API permissions → Microsoft Graph, permissões delegadas: openid, profile, email, offline_access, User.Read e GroupMember.Read.All. Depois, Grant admin consent.

As seis permissões delegadas do Microsoft Graph com o consentimento do administrador concedido

  1. Certificates & secrets → New client secret. Anote a data de validade e crie um lembrete 30 dias antes.

Client secret do app com a data de expiração e o valor oculto

Boa prática: conceda o consentimento do administrador

Sem o admin consent, cada usuário vê, no primeiro login, uma tela da Microsoft pedindo permissão para “perfil básico” e “acesso contínuo”. Com o consentimento concedido em nome da organização, essa tela some para todos.

Boa prática: copie o “Valor” do segredo, não o “ID secreto”

A tela de Certificates & secrets mostra duas colunas parecidas. O NKP precisa do Valor, que só aparece uma vez, logo depois de criar o segredo. Guarde-o direto no cofre de senhas. Se o login voltar com AADSTS7000215 invalid client secret, a causa quase sempre é essa.

Anote três valores para o próximo passo: o Tenant ID, o Client ID do app e o Object ID de cada grupo. O Entra manda no token o ID do grupo, não o nome.

Os quatro grupos de segurança do Entra ID, com os Object IDs ocultos


2. O Entra ID como Identity Provider no NKP

No Kommander, logado como admin local: Identity Providers → Add Identity Provider → OIDC.

CampoValorDetalhe
NameEntra IDVira o texto do botão na tela de login
Issuer URLhttps://login.microsoftonline.com/<tenant-id>/v2.0
Client IDo Client ID do app
Client Secreto Valor do segredo
Username KeyemailO usuário aparece no NKP pelo e-mail
Get User Infomarcado
Insecure Enable GroupsmarcadoSem ele, o Dex descarta o claim groups
Insecure Skip Email VerifiedmarcadoO Entra não envia o claim email_verified
Workspacestodos

Formulário OIDC do Identity Provider no NKP preenchido, com os identificadores ocultos

Neste print, o campo Client Secret recebeu o ID secreto do Entra, e não o Valor: é o detalhe da dica do passo 1. No lab, a correção foi pelo Edit do Identity Provider, que deixa os campos de Client ID e Client Secret vazios para preservar os valores anteriores.

Antes de salvar, confira o Redirect URI que o formulário mostra: ele tem de ser exatamente o cadastrado no app do Entra. Se o NKP mostrar um IP e o Entra tiver o nome, o login volta com AADSTS50011.

Identity Provider Entra ID cadastrado no NKP, do tipo OIDC e habilitado

O cadastro completo no Kommander, em 31 segundos (vídeo sem áudio, com os identificadores ocultos):

Vídeo: cadastro do Entra ID como Identity Provider OIDC no Kommander

O painel do NKP fica em /dkp/kommander/dashboard. Nele, a tela de login ganha o botão Log in with Entra ID, ao lado do login local:

AntesDepois
Tela de login do NKP só com usuário e senha locaisTela de login do NKP com o botão Log in with Entra ID

O primeiro teste é com a Eva, que não está em nenhum grupo. Ela entra com e-mail e senha no Entra e volta para o NKP com “Not Authorized”. É o resultado esperado e prova a separação: autenticada não é autorizada. Esse teste também valida o segredo, o redirect e o issuer de uma vez.

Eva autenticada pelo Entra ID e recebendo Not Authorized no NKP

Boa prática: um usuário por janela anônima

A sessão anônima do navegador vale enquanto houver qualquer janela anônima aberta. Antes de testar outro usuário, feche todas e abra uma nova. Na tela “Continuar conectado?” do Entra, responda Não. Sem isso, o teste do próximo usuário reaproveita a sessão do anterior.


3. Os grupos do NKP: oidc: + Object ID

Identity Providers → Groups → Create Group. Para cada grupo do Entra, um grupo no NKP, com o mesmo nome (fica legível) e, em Identity Provider Groups, o valor oidc:<Object ID do grupo>. O prefixo oidc: é o que o NKP acrescenta aos grupos que chegam pelo conector OIDC, e a própria tela orienta isso.

Formulário de grupo do NKP com a orientação para prefixar o grupo com oidc:

Os três grupos do NKP mapeados para os grupos do Entra ID

Um grupo do NKP sozinho não dá permissão nenhuma. O acesso vem do binding, em um de três níveis: global (todos os clusters), workspace (os clusters de um time) ou projeto (um namespace distribuído aos clusters do workspace).


4. Admin da plataforma: a Ana

Access Control global → Cluster Role Bindings → grupo nkp-plataforma-admins:

  • Cluster Admin Role: admin em todos os clusters gerenciados;
  • dkp-kommander-admin: admin do painel do Kommander.

Binding global do grupo nkp-plataforma-admins com Cluster Admin Role e dkp-kommander-admin

As duas fazem par. Com só o dkp-kommander-admin, a Ana passou da autorização do painel, mas a tela ficou em branco: o painel consulta os clusters com as permissões de quem está logado, e faltava o papel nos clusters. Com as duas, o painel completo apareceu em menos de 5 minutos, o tempo de o NKP federar o papel para os clusters.

Só dkp-kommander-adminCluster Admin Role + dkp-kommander-admin
Ana logada só com o papel do painel: tela em brancoAna logada com os dois papéis: painel completo com workspaces, clusters e Administration

O login da Ana pelo Entra ID, do botão ao painel completo (vídeo sem áudio, com os nomes internos ocultos):

Vídeo: login da administradora da plataforma pelo Entra ID

5. Operador do workspace: o Bruno

O Bruno opera o cluster do workspace de serviços e não deve ver o resto da plataforma. O binding é no workspace: seletor de workspace → Access Control → Cluster Role Bindings → grupo nkp-servicos-operadores. A primeira escolha foi a Workspace Cluster Admin Role + Kommander Workspace Admin Role:

Primeiro binding do grupo de operadores no workspace: Kommander Workspace Admin Role e Workspace Cluster Admin Role

O binding no painel, com essa primeira escolha de papéis:

Vídeo: papéis do grupo de operadores no workspace de serviços

No painel, o resultado foi o esperado já na primeira configuração: o seletor de workspace do Bruno lista só o workspace de serviços, sem o Global e sem os outros.

Bruno logado: o seletor mostra só o workspace de serviços e um cluster

O login do Bruno, que cai direto no workspace dele:

Vídeo: login do operador pelo Entra ID, só no workspace de serviços

No kubectl, a escolha do papel faz diferença. A lista de papéis do workspace tem cerca de 30 nomes parecidos. No NKP 2.19, a Workspace Cluster Admin Role padrão é uma role agregada: ela não tem regras próprias e recebe as das roles marcadas com aggregate-to-cluster-admin. No cluster, isso resultou em acesso aos recursos do Cluster API e às URLs do painel, mas não aos recursos do núcleo do Kubernetes: can-i create deployments deu no e get nodes deu Forbidden. O papel de admin global da Ana, ao contrário, tem regras * explícitas.

Com essa role padrão, o Bruno autentica pelo Entra, mas o kubectl responde no e Forbidden (vídeo gravado antes da correção; os comandos de kubeconfig, que contêm o token, foram cortados):

Vídeo: kubectl do operador com a Workspace Cluster Admin Role padrão, recebendo Forbidden

A solução foi uma Workspace Role customizada, criada pelo painel (Access Control → Roles → Create Role), do tipo Cluster Role, com duas regras: todos os recursos e verbos, e todas as nonResourceURLs.

Workspace Role customizada Operador do Cluster (full) com duas regras explícitas

O binding final do grupo trocou a Workspace Cluster Admin Role por essa role e manteve a Kommander Workspace Admin Role (o painel do workspace). O NKP federou a role nova para o cluster em menos de 1 minuto:

Terminal window
# nomes dos nós e Object ID anonimizados
$ kubectl auth whoami
ATTRIBUTE VALUE
Groups [oidc:<object-id-do-grupo> system:authenticated]
$ kubectl auth can-i create deployments --all-namespaces
yes
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
cluster-servicos-control-plane-1 Ready control-plane 3d2h v1.36.2
cluster-servicos-control-plane-2 Ready control-plane 3d2h v1.36.2
cluster-servicos-control-plane-3 Ready control-plane 3d2h v1.36.2
cluster-servicos-worker-1 Ready <none> 3d2h v1.36.2
cluster-servicos-worker-2 Ready <none> 3d2h v1.36.2
cluster-servicos-worker-3 Ready <none> 3d2h v1.36.2

Boa prática: teste o papel antes de entregar o acesso

Como admin, pergunte ao cluster fingindo ser o grupo: kubectl auth can-i create deployments -A --as=teste --as-group='oidc:<object-id>'. Foi assim que a role agregada apareceu em segundos, sem depender do login do usuário.


6. Dev do projeto: a Carla

A Carla trabalha só no namespace de um projeto. No workspace de serviços: Projects → Create Project (app-demo, colocado só no cluster de serviços). O NKP cria o namespace app-demo-mkgxc no cluster. No projeto, o grupo nkp-servicos-devs recebe App Deployer (cria e altera workloads) + Kommander Project Edit (o projeto no painel).

Binding do grupo de devs no projeto app-demo com App Deployer e Kommander Project Edit

Para um dev só de projeto usar o painel, são três bindings, um em cada nível:

NívelPapelO que libera
Globaldkp-kommander-viewA “porta”: a URL do painel (/dkp/kommander/dashboard)
WorkspaceKommander Workspace ViewLer o workspace e a lista de projetos
ProjetoApp Deployer + Kommander Project EditTrabalhar no namespace do projeto

Os papéis de workspace já trazem a “porta” embutida; os de projeto não. Por isso, só com o binding do projeto a Carla recebeu “Not Authorized”; com a porta e sem a leitura do workspace, a tela ficou em branco. Com os três, ela vê o workspace de serviços e o projeto dela:

Carla logada vendo o workspace de serviços e o projeto app-demo

Terminal window
$ kubectl auth can-i create deployments -n app-demo-mkgxc
yes
$ kubectl auth can-i create deployments -n default
no
$ kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "[email protected]" cannot list resource "nodes" in API group "" at the cluster scope
$ kubectl create deployment podinfo --image=ghcr.io/stefanprodan/podinfo:6.7.1 -n app-demo-mkgxc
deployment.apps/podinfo created
$ kubectl get pods -n app-demo-mkgxc
NAME READY STATUS RESTARTS AGE
podinfo-7f5848f5f6-7ztzk 1/1 Running 0 1s

Boa prática: privilégio mínimo na “porta”

O dkp-kommander-view libera leitura em /dkp/*. Para um perfil de dev mais restrito, crie uma NKP Role só com /dkp/kommander/dashboard* e use-a no lugar dele.


7. kubectl com o login do Entra

No painel, o menu do usuário tem Generate Token: escolha o cluster e copie os comandos que montam o kubeconfig. O token é emitido pelo Dex com os grupos do Entra e vale 24 horas (no token da Ana, exp − iat = 86.400 s). O kubeconfig aponta para o kube-oidc-proxy do cluster escolhido.

Claims do token emitido pelo Dex: grupos com o Object ID do Entra, issuer do Dex e validade de 24 horas

kubectl auth whoami e can-i da Ana com o token do Entra ID

O fluxo inteiro da Ana, do Generate Token ao kubectl get nodes (os comandos de kubeconfig, que contêm o token, foram cortados):

Vídeo: Generate Token e kubectl como administradora da plataforma

Boa prática: um arquivo de kubeconfig por usuário

Os comandos do Generate Token gravam no kubeconfig ativo. Antes de colar, rode export KUBECONFIG=~/.kube/<usuario>.conf. Assim o seu ~/.kube/config de administrador continua intacto.


Os números

MedidaValor
Do Identity Provider salvo ao primeiro login pelo Entra12 min
Licença do Entra ID usadaFree (MFA por Security Defaults)
Saída do management para a Microsoft (pod de teste)20 de 20 HTTP 200; DNS em 3–10 ms
Permissões delegadas do Graph no app6, com consentimento do administrador
Papéis de workspace disponíveis no painel~30
Federação de um papel global para os clusters< 5 min
Federação da Workspace Role customizada< 1 min
Validade do token do Generate Token24 h
Bindings para um dev só de projeto usar o painel3 (global, workspace, projeto)

O que aprendi

  1. Autenticação e autorização ficam em lugares diferentes. O Entra diz quem é a pessoa (com MFA); o NKP diz o que o grupo dela pode fazer. A Eva prova isso no primeiro teste.
  2. Grupos, sempre. O token traz o Object ID; o NKP usa oidc:<ID>. Entrar ou sair de um grupo no Entra muda o acesso a partir do próximo token, sem tocar no NKP.
  3. Papel de painel e papel de cluster andam juntos. O painel consulta os clusters com as permissões de quem está logado.
  4. Confira o que um papel concede antes de usá-lo. No NKP 2.19, a Workspace Cluster Admin Role padrão é agregada; para um operador com acesso total ao cluster, use uma Workspace Role customizada.
  5. Dev de projeto precisa de três níveis. Porta global, leitura do workspace e trabalho no projeto.
  6. Mantenha o acesso de emergência. Admin local e kubeconfig de certificado, guardados num cofre, antes de mexer no login.

Checklist: login no NKP com o Entra ID

  • Kubeconfig de certificado e senha do admin local guardados no cofre (break-glass)
  • Saída do management para login.microsoftonline.com e graph.microsoft.com testada de um pod
  • Usuários do Entra com o atributo Email preenchido
  • Grupos de segurança no Entra, um por perfil, com os Object IDs anotados
  • App registration com Redirect URI igual ao do formulário do NKP
  • Groups claim (Group ID) e optional claims email e upn
  • Permissões delegadas com GroupMember.Read.All e consentimento do administrador
  • Valor do client secret no cofre e lembrete 30 dias antes da validade
  • Identity Provider OIDC com Username Key email, Insecure Enable Groups e Insecure Skip Email Verified
  • Teste com uma conta sem grupo: autentica e recebe “Not Authorized”
  • Grupos do NKP com oidc:<Object ID>
  • Bindings testados com kubectl auth can-i --as-group antes de liberar
  • Um kubeconfig por usuário (export KUBECONFIG) ao usar o Generate Token

O que ainda não testei

  • Acesso só pelo kubectl, sem o painel, para um usuário do Entra que não deve entrar no Kommander (o grupo k8s-servicos-kubectl já existe no Entra do lab). Para exceções, o acesso por certificado do próprio cluster, preso a um namespace, está em Times no NKP com RBAC nativo e quotas.
  • Desligamento de um usuário: quanto tempo o acesso continua depois de desativar a conta no Entra, com o token de 24 horas.
  • MFA em todo login com Acesso Condicional (Entra ID P1). Com Security Defaults, o Entra pede MFA conforme a avaliação de risco, não a cada login.
  • Os mesmos perfis num cluster com licença Pro ou Starter. A receita com RBAC nativo do Kubernetes (namespace, RoleBinding para o grupo e quota), que não depende de workspaces nem de projetos, foi testada no lab e está em Times no NKP com RBAC nativo e quotas.
  • A troca do client secret antes da validade, sem interromper os logins.

Referências

Nutanix

Microsoft

Projetos e comunidade

Comentários

Os comentários usam o GitHub Discussions; é preciso ter uma conta no GitHub.