Pinniped: Autenticação Federada para Clusters Kubernetes
Gerir quem acede aos clusters Kubernetes é um dos maiores desafios de segurança em infraestruturas modernas. O Pinniped, projecto CNCF mantido pela VMware/Tanzu, resolve este problema ao federar a autenticação com Fornecedores de Identidade existentes — Entra ID, Okta, Kanidm ou LDAP — eliminando certificados de cliente longevos e trazendo SSO com códigos de acesso de curta duração ao kubectl.
ℹ Para quem é este artigo: Administradores Kubernetes e equipas de segurança em PMEs que precisam de integrar clusters com identidade corporativa (Entra ID, Okta, Kanidm) sem gerir certificados de cliente manualmente.
Neste artigo
- 1. Introdução — O problema de acesso ao Kubernetes
- 2. O que é o Pinniped
- 3. Arquitectura e Componentes
- 4. Configuração com Entra ID
- 5. Configuração com Kanidm/LDAP
- 6. Boas Práticas de Segurança
- 7. Conclusão
1. Introdução — O problema de acesso ao Kubernetes
O modelo de autenticação nativo do Kubernetes baseia-se em certificados de cliente X.509 emitidos pelo cluster. Cada utilizador ou serviço que precise de aceder ao API server recebe um certificado assinado pela CA do cluster. Este modelo tem três problemas fundamentais para PMEs:
Certificados longevos sem revogação. O Kubernetes não implementa revogação de certificados (CRL/OCSP). Um certificado de cliente válido até 2028 continua a funcionar mesmo depois de o utilizador deixar a empresa, a menos que se recrie a CA inteira — operação disruptiva.
Gestão manual descentralizada. Cada cluster mantém a sua própria lista de certificados. Numa PME com 3 clusters de desenvolvimento, pré-produção e produção, um administrador que saia da empresa exige revogação manual em cada cluster — frequentemente esquecida.
Ausência de SSO. O kubectl não integra nativamente com Entra ID, Okta ou qualquer IdP baseado em OIDC. As equipas acabam por partilhar kubeconfig files com credenciais embutidas, violando princípios básicos de segregação de acesso.
O Pinniped resolve estes três problemas ao funcionar como intermediário entre o kubectl e o IdP corporativo, emitindo códigos de acesso de curta duração (tipicamente 5-15 minutos) que se renovam automaticamente a partir de uma sessão SSO válida.
2. O que é o Pinniped
O Pinniped é um serviço de autenticação federada de código aberto para Kubernetes, mantido pela VMware (Tanzu) e aceite como projecto CNCF em estágio sandbox. O nome provém do inglês para “pinípede” (focas, leões-marinhos), criaturas conhecidas pela sua capacidade de autenticação mútua — uma analogia à federação de identidade.
| Característica | Descrição |
|---|---|
| Projecto CNCF | Sandbox, mantido por VMware/Tanzu |
| Licença | Apache 2.0 |
| IdPs suportados | Entra ID (Azure AD), Okta, Kanidm, LDAP, qualquer IdP OIDC |
| Modelo de códigos | JWT de curta duração (5-15 min), renovável via refresh |
| Instalação | Helm chart ou kubectl apply, sem dependências externas |
| Cliente | Plugin kubectl (pinniped-cli), sem alterações ao kubectl |
A vantagem principal para PMEs é a reutilização da identidade corporativa. Em vez de criar utilizadores Kubernetes independentes, o Pinniped delega a autenticação no IdP que a empresa já usa. Quando um colaborador é desactivado no Entra ID ou Kanidm, perde automaticamente acesso a todos os clusters federados — sem necessidade de revogar certificados manualmente.
O Pinniped suporta dois tipos de IdP: OIDC (Entra ID, Okta, qualquer fornecedor OAuth 2.0/OIDC) e LDAP (directório tradicional, Kanidm em modo LDAP). A configuração é feita via Custom Resource Definitions (CRDs) no cluster, sem necessidade de recompilar ou modificar o Kubernetes.
3. Arquitectura e Componentes
O Pinniped tem uma arquitectura de três componentes que funcionam em conjunto para fornecer autenticação federada:
3.1 Supervisor
O Pinniped Supervisor é o componente central. Corre dentro do cluster Kubernetes como Deployment e expõe um endpoint de autenticação. É responsável por:
- Comunicar com o IdP externo (Entra ID, Okta, LDAP) via OIDC ou LDAP bind
- Validar as credenciais do utilizador contra o IdP
- Emitir códigos de acesso JWT de curta duração assinados pela sua própria chave
- Renovar códigos de acesso expirados via refresh, sem nova autenticação do utilizador
3.2 Concierge
O Pinniped Concierge é o componente que corre em cada cluster alvo (onde os utilizadores querem executar kubectl). Funciona como webhook de autenticação no API server do Kubernetes. Quando o kubectl envia um pedido com um código de acesso do Supervisor, o Concierge valida a assinatura JWT e informa o API server da identidade do utilizador.
3.3 Pinniped CLI
O pinniped-cli é um plugin de kubectl que o utilizador instala na sua máquina. Gere o fluxo de autenticação: abre o navegador para iniciar sessão no IdP, recebe o código de autorização, troca-o por um código de acesso do Supervisor, e configura o kubeconfig para usar o Concierge como webhook de autenticação.
ℹ O fluxo de autenticação é transparente para o utilizador: após executar pinniped login uma vez, o kubectl funciona normalmente. Os códigos de acesso são renovados em background sem intervenção do utilizador, enquanto a sessão SSO for válida.
O diagrama seguinte ilustra o fluxo de autenticação completo:
Utilizador Pinniped CLI Supervisor IdP (Entra ID) Concierge K8s API
| | | | | |
| kubectl get pods| | | | |
|--------------->| | | | |
| | sem código válido | | | |
| |----------------->| | | |
| | | redirect OIDC | | |
| |<-----------------| | | |
| abrir navegador| | | | |
|<---------------| | | | |
| login (user+MFA) | | | |
|----------------------------------------------------->| | |
| código autorização | | | |
|<-----------------------------------------------------| | |
| | exchange code | | | |
| |----------------->| | | |
| | | token OIDC | | |
| | |----------------->| | |
| | |<-----------------| | |
| | código acesso JWT | | | |
| |<-----------------| | | |
| | request + JWT | | | |
| |------------------------------------------------->| |
| | | | | valida JWT |
| | | | |------------->|
| | | | | 200 OK |
| |<-------------------------------------------------| |
| pods list | | | | |
|<---------------| | | | |
4. Configuração com Entra ID
A configuração com Microsoft Entra ID (antigo Azure AD) é o cenário mais comum em PMEs que já usam Microsoft 365. O processo envolve três passos: registar uma aplicação no Entra ID, instalar o Pinniped no cluster, e configurar o Supervisor com as credenciais da aplicação.
4.1 Registo da aplicação no Entra ID
No portal do Entra ID (entra.microsoft.com), criar um novo registo de aplicação com:
- Nome: Pinniped Kubernetes Auth
- Tipo de conta: Contas neste directório organizacional apenas
- URI de redireccionamento:
https://<supervisor-endpoint>/callback
Anotar o Application (client) ID e o Directory (tenant) ID. Criar um secret de cliente e anotar o valor. Estes três valores são necessários para configurar o Supervisor.
4.2 Instalação do Pinniped no cluster
Instalar o Pinniped via Helm (recomendado) ou kubectl apply directo:
# Adicionar repositório Helm do Pinniped
helm repo add pinniped https://projects.pinniped.dev/helm-charts/
helm repo update
# Instalar Supervisor e Concierge no cluster
helm install pinniped-supervisor pinniped/pinniped-supervisor \
--namespace pinniped-supervisor \
--create-namespace
helm install pinniped-concierge pinniped/pinniped-concierge \
--namespace pinniped-concierge \
--create-namespace
# Instalar o CLI localmente
brew install pinniped-cli # macOS
# ou: download directo de https://pinniped.dev/releases/
4.3 Configuração do Supervisor com Entra ID
Criar um Secret com as credenciais do Entra ID e uma FederationDomain que referencia o IdP OIDC:
# Secret com client ID e client secret do Entra ID
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: entra-id-client-credentials
namespace: pinniped-supervisor
type: secrets.pinniped.dev/oidc-client
stringData:
clientID: "11111111-2222-3333-4444-555555555555"
clientSecret: "client-secret-value-here"
EOF
# Configurar o IdP OIDC no Supervisor
cat <<EOF | kubectl apply -f -
apiVersion: idp.supervisor.pinniped.dev/v1alpha1
kind: OIDCIdentityProvider
metadata:
name: entra-id
namespace: pinniped-supervisor
spec:
issuer: "https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/v2.0"
authorizationConfig:
additionalScopes: ["offline_access", "groups"]
claims:
groups: "groups"
username: "preferred_username"
client:
secretName: entra-id-client-credentials
EOF
# Criar FederationDomain (expõe o endpoint do Supervisor)
cat <<EOF | kubectl apply -f -
apiVersion: config.supervisor.pinniped.dev/v1alpha1
kind: FederationDomain
metadata:
name: kbase-federation
namespace: pinniped-supervisor
spec:
issuer: "https://pinniped-supervisor.kbase.pt"
identityProviders:
- displayName: "Entra ID Corporativo"
objectRef:
apiGroup: idp.supervisor.pinniped.dev
kind: OIDCIdentityProvider
name: entra-id
EOF
⚠ O issuer do FederationDomain deve corresponder ao URL onde o Supervisor está acessível. Se o cluster estiver atrás de um ingress ou load balancer, garantir que o TLS está configurado correctamente — o Pinniped exige HTTPS para o endpoint do Supervisor.
4.4 Configuração do Concierge e kubeconfig
Após o Supervisor estar configurado, ligar o Concierge ao Supervisor e gerar o kubeconfig para os utilizadores:
# Configurar o Concierge para confiar no Supervisor
cat <<EOF | kubectl apply -f -
apiVersion: authentication.concierge.pinniped.dev/v1alpha1
kind: JWTAuthenticator
metadata:
name: pinniped-supervisor
spec:
issuer: "https://pinniped-supervisor.kbase.pt"
audience: "kbase-k8s"
tls:
certificateAuthorityData: "$(kubectl get secret -n pinniped-supervisor \
pinniped-supervisor-tls -o jsonpath='{.data.ca\.crt}' | base64 -d | base64 -w0)"
EOF
# Gerar kubeconfig para os utilizadores utilizarem
pinniped get kubeconfig \\
--kubeconfig ~/.kube/config-prod \\
> pinniped-kubeconfig.yaml
# Distribuir pinniped-kubeconfig.yaml aos utilizadores.
# Cada utilizador executa:
KUBECONFIG=pinniped-kubeconfig.yaml kubectl get pods
# Isto abre o navegador para login no Entra ID.
A partir deste momento, o kubectl usa o Pinniped para autenticar. O utilizador inicia sessão uma vez no navegador, recebe um código de acesso JWT de curta duração, e o Pinniped renova-o automaticamente enquanto a sessão for válida.
5. Configuração com Kanidm/LDAP
Para PMEs que não usam Entra ID — tipicamente infraestruturas auto-alojadas com Kanidm ou LDAP tradicional — o Pinniped suporta autenticação via LDAP bind. Esta secção cobre a configuração com Kanidm em modo LDAP, que é o cenário mais comum em PMEs que preferem soluções de código aberto auto-alojadas.
5.1 Configuração LDAP com Kanidm
O Kanidm expõe uma interface LDAP compatível na porta 3636 (TLS). Criar um LDAPIdentityProvider no Supervisor:
# Secret com bind credentials para pesquisa LDAP no Kanidm
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
name: kanidm-bind-credentials
namespace: pinniped-supervisor
type: secrets.pinniped.dev/ldap-client
stringData:
username: "[email protected],ou=service_accounts,dc=kbase,dc=pt"
password: "bind-password-here"
EOF
# Configurar LDAPIdentityProvider
cat <<EOF | kubectl apply -f -
apiVersion: idp.supervisor.pinniped.dev/v1alpha1
kind: LDAPIdentityProvider
metadata:
name: kanidm-ldap
namespace: pinniped-supervisor
spec:
host: "kanidm.kbase.pt:3636"
tls:
caData: "$(base64 -w0 < kanidm-ca.crt)"
bind:
secretName: kanidm-bind-credentials
userSearch:
base: "ou=people,dc=kbase,dc=pt"
filter: "(objectClass=person)"
attributes:
username: "mail"
uid: "entryuuid"
groupSearch:
base: "ou=groups,dc=kbase,dc=pt"
filter: "(objectClass=group)"
attributes:
groupName: "cn"
groupMembership: "member"
EOF
ℹ O Kanidm suporta também OIDC nativo. Se preferir usar OIDC em vez de LDAP, configure um OIDCIdentityProvider com o issuer do Kanidm (https://kanidm.kbase.pt/oauth2/openid/pinniped). O OIDC oferece melhor rastreabilidade de sessões e suporte a MFA nativo.
5.2 Mapeamento de grupos
O Pinniped mapeia automaticamente os grupos do IdP para grupos Kubernetes. Isto permite usar RoleBindings e ClusterRoleBindings baseados em grupos do directório, em vez de utilizadores individuais:
# RoleBinding baseado em grupo do Kanidm/Entra ID
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: k8s-admins
subjects:
- kind: Group
name: "k8s-admins" # grupo no Kanidm ou Entra ID
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
EOF
Quando um utilizador do grupo k8s-admins no Kanidm inicia sessão via Pinniped, o código de acesso JWT inclui o grupo, e o Kubernetes aplica automaticamente as permissões definidas no ClusterRoleBinding.
6. Boas Práticas de Segurança
A implementação do Pinniped deve seguir boas práticas de segurança para garantir que a federação de identidade não introduz novos vectores de ataque:
| Prática | Recomendação | Risco se ignorada |
|---|---|---|
| Duração dos códigos | Configurar 5-15 min no Supervisor | Códigos longos aumentam janela de ataque |
| MFA no IdP | Activar MFA obrigatório no Entra ID/Kanidm | Password comprometida dá acesso ao cluster |
| TLS no Supervisor | Usar certificados válidos, não self-signed | MITM intercepta códigos de acesso |
| RBAC por grupos | Usar grupos do IdP, não utilizadores | Permissões não acompanham saída da empresa |
| Isolamento do Supervisor | Namespace dedicado, NetworkPolicy restrictiva | Comprometimento do Supervisor afecta todos os clusters |
| Registos de auditoria | Activar audit logging no Concierge e Supervisor | Sem rastreabilidade de quem acedeu ao cluster |
6.1 Duração dos tokens e credenciais (fixa, não configurável)
As durações de todos os tokens e credenciais do Pinniped são fixas no código do Supervisor e não são configuráveis — nenhum campo do FederationDomain as altera. Para um login inicial, a cadeia é: código de autorização válido 10 minutos, ID token e access token 2 minutos cada, e a credencial de cluster (certificado cliente mTLS emitido pelo Concierge) 5 minutos — cerca de 19 minutos no total para consumir o login. O refresh token tem 9 horas de validade a partir da autenticação inicial e é ele que sustenta as sessões contínuas do kubectl.
A única excepção à regra: clientes OIDC personalizados (CRD OIDCClient) podem definir spec.tokenLifetimes.idTokenSeconds para ajustar a duração dos ID tokens emitidos a esse cliente — disponível desde a v0.30.0, e não aplicável ao pinniped-cli, que usa sempre o cliente pinniped-cli fixo. Verificar a duração corrente nos logs do Supervisor ou nos eventos do cluster; planejar o sizing de sessões à volta dos valores fixos acima (documentação oficial de tokens e credenciais).
6.2 NetworkPolicy para isolamento
Aplicar uma NetworkPolicy para restringir o tráfego de e para o Supervisor, permitindo apenas ligações do API server e do IdP:
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: pinniped-supervisor-isolation
namespace: pinniped-supervisor
spec:
podSelector:
matchLabels:
app: pinniped-supervisor
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: pinniped-concierge
ports:
- protocol: TCP
port: 8443
egress:
- to: [] # IdP externo (Entra ID, Kanidm)
ports:
- protocol: TCP
port: 443
- to: [] # DNS
ports:
- protocol: UDP
port: 53
EOF
7. Conclusão
O Pinniped resolve um problema real e doloroso na gestão de clusters Kubernetes: a autenticação de utilizadores com certificados de cliente longevos e sem revogação. Ao federar a autenticação com IdPs corporativos (Entra ID, Okta, Kanidm, LDAP), as PMEs obtêm três benefícios concretos: códigos de acesso de curta duração que expiram automaticamente, SSO que elimina credenciais redundantes, e revogação centralizada — quando um utilizador é desactivado no IdP, perde acesso a todos os clusters federados.
A implementação é relativamente simples — três componentes (Supervisor, Concierge, CLI) configurados via CRDs — e não requer alterações ao código do Kubernetes ou ao kubectl. Para PMEs que já usam Entra ID ou Kanidm, o Pinniped é a forma mais directa de aplicar políticas de identidade corporativa ao acesso Kubernetes, alinhando-se com princípios Zero Trust sem custo de licenciamento.
Artigos relacionados:
- Cilium e eBPF: Rede e Segurança no Kubernetes para PME
- Kanidm: Identity Provider Moderno Self-Hosted para PME
- Zero Trust para PMEs em 2026: Como Implementar os 5 Pilares NIST
- Federação SAML — Entra ID com Aplicações Externas (Keycloak, SSO)
- OpenBao: Gestão de Segredos Open-Source após o Vault
Fontes oficiais: pinniped.dev · GitHub: vmware-tanzu/pinniped · Documentação Pinniped