Login no NKP com o Microsoft Entra ID: do app registration ao acesso por grupo
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.

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 NKP | No painel | No kubectl (cluster de serviços) |
|---|---|---|---|
Ana (nkp-plataforma-admins) | Global: Cluster Admin Role + dkp-kommander-admin | Tudo: 4 workspaces, 2 clusters, Administration | can-i '*' '*' = yes; vê os 6 nós |
Bruno (nkp-servicos-operadores) | Workspace: role customizada “Operador do Cluster (full)” + Kommander Workspace Admin | Só o workspace de serviços e o cluster dele | create deployments em todos os namespaces = yes |
Carla (nkp-servicos-devs) | Global: dkp-kommander-view · Workspace: Kommander Workspace View · Projeto: App Deployer + Kommander Project Edit | Só o workspace de serviços e o projeto dela | yes no namespace do projeto, no no default, nós proibidos |
| Eva (sem grupo) | Nenhum | Autentica no Entra e recebe “Not Authorized” | — |
| Admin local do NKP | Senha local | Painel completo o tempo todo | Kubeconfig 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:
- O Entra cuida da autenticação (senha, MFA, bloqueio da conta). O NKP cuida da autorização (o que cada grupo pode fazer).
- 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. - 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
| Item | Por quê | Como conferi no lab |
|---|---|---|
| Um tenant do Entra ID | O NKP conversa com um tenant | Entra ID Free: app registration, grupos e Security Defaults (MFA) estão incluídos |
| Domínio verificado (opcional) | Logins com o domínio da empresa | lab.leimar.dev verificado com um registro TXT |
| Usuários com o atributo Email preenchido | O NKP usa o e-mail como nome do usuário; sem ele, o login não conclui | Perfil de cada usuário → Contact information → Email |
| Grupos de Segurança no Entra | O token carrega os grupos | 4 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 navegador | Pod de teste no namespace kommander: 20 de 20 respostas HTTP 200 |
| Acesso de emergência | Se o login pelo Entra falhar, você não fica sem acesso | Admin local do NKP + kubeconfig de certificado nos dois clusters |
| Relógio sincronizado (NTP) | Tokens têm validade; relógio errado faz o token ser rejeitado | Bastion e API servers no mesmo segundo |


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.
- App registrations → New registration: nome
nkp-dex, Accounts in this organizational directory only. - 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ó exigehttps.

- Token configuration:
- Add groups claim → Security groups, formato Group ID no ID token;
- Add optional claim (ID token) →
emaileupn.

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

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

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.

2. O Entra ID como Identity Provider no NKP
No Kommander, logado como admin local: Identity Providers → Add Identity Provider → OIDC.
| Campo | Valor | Detalhe |
|---|---|---|
| Name | Entra ID | Vira o texto do botão na tela de login |
| Issuer URL | https://login.microsoftonline.com/<tenant-id>/v2.0 | |
| Client ID | o Client ID do app | |
| Client Secret | o Valor do segredo | |
| Username Key | email | O usuário aparece no NKP pelo e-mail |
| Get User Info | marcado | |
| Insecure Enable Groups | marcado | Sem ele, o Dex descarta o claim groups |
| Insecure Skip Email Verified | marcado | O Entra não envia o claim email_verified |
| Workspaces | todos |

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.

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

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:
| Antes | Depois |
|---|---|
![]() | ![]() |
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.

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.


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.

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-admin | Cluster Admin Role + dkp-kommander-admin |
|---|---|
![]() | ![]() |
O login da Ana pelo Entra ID, do botão ao painel completo (vídeo sem áudio, com os nomes internos ocultos):

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:

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

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.

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

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):

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.

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:
# nomes dos nós e Object ID anonimizados$ kubectl auth whoamiATTRIBUTE VALUEUsername [email protected]Groups [oidc:<object-id-do-grupo> system:authenticated]$ kubectl auth can-i create deployments --all-namespacesyes$ kubectl get nodesNAME STATUS ROLES AGE VERSIONcluster-servicos-control-plane-1 Ready control-plane 3d2h v1.36.2cluster-servicos-control-plane-2 Ready control-plane 3d2h v1.36.2cluster-servicos-control-plane-3 Ready control-plane 3d2h v1.36.2cluster-servicos-worker-1 Ready <none> 3d2h v1.36.2cluster-servicos-worker-2 Ready <none> 3d2h v1.36.2cluster-servicos-worker-3 Ready <none> 3d2h v1.36.2Boa 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).

Para um dev só de projeto usar o painel, são três bindings, um em cada nível:
| Nível | Papel | O que libera |
|---|---|---|
| Global | dkp-kommander-view | A “porta”: a URL do painel (/dkp/kommander/dashboard) |
| Workspace | Kommander Workspace View | Ler o workspace e a lista de projetos |
| Projeto | App Deployer + Kommander Project Edit | Trabalhar 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:

$ kubectl auth can-i create deployments -n app-demo-mkgxcyes$ kubectl auth can-i create deployments -n defaultno$ kubectl get nodesError 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-mkgxcdeployment.apps/podinfo created$ kubectl get pods -n app-demo-mkgxcNAME READY STATUS RESTARTS AGEpodinfo-7f5848f5f6-7ztzk 1/1 Running 0 1sBoa 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.


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

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
| Medida | Valor |
|---|---|
| Do Identity Provider salvo ao primeiro login pelo Entra | 12 min |
| Licença do Entra ID usada | Free (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 app | 6, 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 Token | 24 h |
| Bindings para um dev só de projeto usar o painel | 3 (global, workspace, projeto) |
O que aprendi
- 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.
- 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. - Papel de painel e papel de cluster andam juntos. O painel consulta os clusters com as permissões de quem está logado.
- 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.
- Dev de projeto precisa de três níveis. Porta global, leitura do workspace e trabalho no projeto.
- 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.comegraph.microsoft.comtestada 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
emaileupn - Permissões delegadas com
GroupMember.Read.Alle 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-groupantes 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 grupok8s-servicos-kubectljá 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
- Configure NKP single sign-on with Microsoft Entra ID (nutanix.dev)
- Integrating NKP with Microsoft Active Directory via LDAP (nutanix.dev)
- Nutanix Kubernetes Platform: datasheet e edições
- Nutanix Kubernetes Platform Guide 2.19, seções Identity Providers e Access Control (portal Nutanix)
Microsoft
Projetos e comunidade




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