Autorizando Pods a Acessar Recursos Não OCI Usando a Descoberta do OpenID Connect (OIDC)

Saiba mais sobre o uso da Descoberta do OpenID Connect (OIDC) para autenticar pods de aplicativos em execução em clusters criados com o Container Engine for Kubernetes (OKE), para que os pods possam chamar APIs de serviço em provedores de nuvem externos.

Talvez você queira que os pods de aplicativos sejam executados em um cluster do Kubernetes que você criou com o Kubernetes Engine se comuniquem com APIs de serviço de nuvem hospedadas em provedores de nuvem externos (como GCP, AWS e Azure). Para garantir a segurança dos recursos hospedados por um provedor de nuvem externo, o aplicativo em execução no cluster deve autenticar e gerenciar a identidade. No entanto, gerenciar credenciais diretamente pode ser um processo complicado para aplicativos, e a rotação de chaves é um processo manual com sobrecarga considerável.

O OpenID Connect (OIDC) é um padrão do setor para tornar essas integrações mais simples. O OpenID Connect é uma camada de identidade criada com base em OAuth 2.0. O OpenID Connect suporta um protocolo de descoberta (geralmente chamado de "Descoberta OIDC") que usa um documento de Configuração do Provedor OpenID (conhecido como "documento de descoberta") para autenticar aplicativos.

O Kubernetes Engine fornece suporte para a Descoberta do OIDC, permitindo que você crie aplicativos que interajam com outros serviços de nuvem sem a necessidade de código rígido e rotacionar manualmente as chaves de autenticação da API. Opcionalmente, você pode ativar a Descoberta do OIDC ao criar ou atualizar um cluster aprimorado com o Kubernetes Engine.

Em alto nível, quando você ativa a Descoberta do OIDC para um cluster, o token da conta de serviço do aplicativo é autenticado e (se válido) trocado por um token de acesso. O token de acesso é usado para autenticar o aplicativo com a API no provedor de nuvem externo.

Para obter mais informações, consulte Descoberta do emissor da conta de serviço na documentação do Kubernetes.

Descoberta do OIDC com mais detalhes

O Kubernetes fornece uma conta de serviço a cada pod de aplicativo em execução em um cluster e cria um token de conta de serviço para cada conta de serviço. O Kubernetes gerencia o ciclo de vida dos tokens da conta de serviço. O token da conta de serviço é um token portador que o aplicativo anexa a solicitações de API e é estruturado como um JWT (JSON Web Token).

Quando você ativa a Descoberta do OIDC para um cluster, o Kubernetes Engine expõe um Emissor do OIDC e adiciona o URL do Emissor do OIDC ao token da conta de serviço como o valor da reivindicação iss.

A localização de um documento de descoberta do OIDC é relativa ao URL do Emissor do OIDC e é um ponto final conhecido acessível publicamente e não autenticado. O documento de descoberta do OIDC inclui o local acessível publicamente e não autenticado de um JWKS (JSON Web Key Set) que contém as chaves públicas para verificar o token da conta de serviço. O provedor de identidades do provedor de nuvem externo usa o documento de descoberta do OIDC para localizar o JWKS e usa o JWKS para verificar o token da conta de serviço.

Para obter segurança adicional, a API do serviço de nuvem chamada por um pod de aplicativo pode exigir que um público-alvo específico esteja presente no token da conta de serviço que o Kubernetes cria. Se a API do serviço de nuvem exigir um público-alvo específico, você poderá especificar esse público-alvo definindo a propriedade audience de um volume projetado no manifesto de pod. O público-alvo especificado é incluído como o valor da reivindicação aud no token da conta de serviço e pode ser verificado pelo provedor de nuvem externo. Você também pode especificar um período de validade para o token da conta de serviço definindo o valor da propriedade expirationSeconds do volume projetado no manifesto de pod. Para obter mais informações, consulte ServiceAccount projeção de volume de token na documentação do Kubernetes.

Se o provedor de identidades do provedor de nuvem externo verificar com sucesso o token da conta de serviço usando o JWKS, o provedor de identidades trocará o token da conta de serviço por um token de acesso. O token de acesso é usado para autenticar o aplicativo e autorizar o aplicativo a usar a API no provedor de nuvem externo.

Processo de troca de token do OIDC Discovery

Quando você ativa a Descoberta do OIDC para um cluster para que um pod de aplicativo possa fazer uma solicitação a uma API externa, o Kubernetes Engine expõe:
  • Um emissor do OIDC. O emissor do OIDC é exposto por HTTPS com um certificado TLS/SSL publicamente confiável.
  • Um JWKS (JSON Web Key Set), contendo as chaves públicas usadas para verificar o token da conta de serviço. O JWKS é armazenado em um bucket acessível publicamente e não autenticado no serviço Object Storage. Consulte Exemplo de JWKS.
  • Um documento de descoberta do OIDC (no formato JSON) que inclui a localização do JWKS. O documento de descoberta é armazenado em um bucket acessível publicamente e não autenticado no serviço Object Storage. Consulte Exemplo de Documento de Descoberta.

Ao definir um pod de aplicativo que envia solicitações para uma API externa, se o provedor de identidades do provedor de nuvem externo esperar um público específico no token da conta de serviço, especifique um serviceAccountToken projetado no manifesto de pod e defina sua propriedade audience de acordo. Consulte Exemplo de Manifesto de Pod.

Veja a seguir uma visão geral do processo de troca de token:

  1. Quando você cria o pod do aplicativo no cluster, o Kubernetes fornece ao pod um token de conta de serviço. O token da conta de serviço inclui o URL do Emissor OIDC do Kubernetes Engine como o valor da reivindicação iss no JWT. Se você especificou um público-alvo no manifesto de pod, o público-alvo será incluído no JWT como o valor da reivindicação aud. Consulte Exemplo de Token de Conta de Serviço.

  2. O pod do aplicativo faz uma solicitação a uma API em um provedor de nuvem externo e apresenta o token da conta de serviço codificado ao provedor de nuvem externo no cabeçalho de Autorização da solicitação de API.
  3. O provedor de identidades do provedor de nuvem externo decodifica o token da conta de serviço, extrai o URL do Emissor do OIDC do Kubernetes Engine da reivindicação iss, anexa /.well-known/openid-configuration ao URL como o local do documento de descoberta do OIDC e envia uma solicitação a esse URL para obter o documento de descoberta.
  4. O Emissor do OIDC do Kubernetes Engine retorna o documento de descoberta do OIDC, que contém o URL do local do JWKS no campo jwks_uri. Consulte Exemplo de Documento de Descoberta.
  5. O provedor de identidades do provedor de nuvem externo extrai o URL do documento de descoberta do OIDC e envia uma solicitação para esse URL para obter o JWKS. Consulte Exemplo de JWKS.
  6. O provedor de identidades do provedor de nuvem externo usa o JWKS para validar o token da conta de serviço originalmente apresentado pelo pod do aplicativo.
  7. Supondo que o token da conta de serviço seja válido, o provedor de identidades do provedor de nuvem externo retorna um token de acesso ao pod do aplicativo.
  8. O pod do aplicativo apresenta o token de acesso à API no provedor de nuvem externo para provar sua identidade e faz solicitações de API com sucesso.

O processo de troca de token é mostrado no seguinte diagrama:

Esta imagem mostra o processo de troca de token descrito no texto ao redor.

Observações sobre a Descoberta do OIDC

Observe os seguintes pontos ao usar a Descoberta do OIDC:

  • A Descoberta do OIDC é suportada em clusters que executam o Kubernetes versão 1.21 ou posterior.
  • A Descoberta do OIDC só é suportada em clusters nativos da VCN (clusters com pontos finais da API do Kubernetes em uma sub-rede em sua própria VCN). Consulte Migrando para Clusters Nativos de VCN.
  • A Descoberta do OIDC é suportada em nós gerenciados, nós virtuais e nós autogerenciados.
  • A Descoberta do OIDC é suportada em clusters aprimorados (mas não em clusters básicos).

Exemplo de Manifesto de Pod, Token de Conta de Serviço, Documento de Descoberta e JWKS para Descoberta do OIDC

Exemplo de Manifesto do Pod

Um exemplo de manifesto para um pod de aplicativo que chama uma API do serviço de nuvem. Neste exemplo, o provedor de identidades do provedor de nuvem externo espera que o token da conta de serviço especifique um público-alvo chamado vault:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /var/run/secrets/tokens
      name: vault-token
  serviceAccountName: build-robot
  volumes:
  - name: vault-token
    projected:
      sources:
      - serviceAccountToken:
          path: vault-token
          expirationSeconds: 7200
          audience: vault

Exemplo de Token de Conta de Serviço

Um exemplo de token de conta de serviço que o Kubernetes pode criar para o pod no Exemplo de Manifesto de Pod:

{
  "aud": [
    "vault"
  ],
  "exp": 1731613413,
  "iat": 1700077413,
  "iss": "https://objectstorage.us-ashburn-1.oci.customer-oci.com/n/okecustprod/b/oidc/o/{discoveryUUID}",
  "kubernetes.io": {
    "namespace": "kube-system",
    "node": {
      "name": "127.0.0.1",
      "uid": "58456cb0-dd00-45ed-b797-5578fdceaced"
    },
    "pod": {
      "name": "build-robot-69cbfb9798-jv9gn",
      "uid": "778a530c-b3f4-47c0-9cd5-ab018fb64f33"
    },
    "serviceaccount": {
      "name": "build-robot",
      "uid": "a087d5a0-e1dd-43ec-93ac-f13d89cd13af"
    },
    "warnafter": 1700081020
  },
  "nbf": 1700077413,
  "sub": "system:serviceaccount:kube-system:build-robot"
}

Exemplo de Documento de Descoberta

Um exemplo de documento de descoberta que o Kubernetes Engine pode emitir, incluindo o local do JWKS especificado pelo campo jwks_uri:

{
    "issuer": "https://objectstorage.us-ashburn-1.oci.customer-oci.com/n/okecustprod/b/oidc/o/{discoveryUUID}",
    "jwks_uri": "https://objectstorage.us-ashburn-1.oci.customer-oci.com/n/okecustprod/b/oidc/o/{discoveryUUID}/jwks",
    "response_types_supported": [
        "id_token"
    ],
    "subject_types_supported": [
        "public"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ]
}

Exemplo de JWKS

Um exemplo de JWKS para autenticar o token da conta de serviço:

{
"keys": [
    {
        "kty": "RSA",
        "kid": "42148Kf",
        "use": "sig",
        "alg": "RS256",
        "n": "iGaLqP6y-SJCCBq5Hv6pGDbG_SQ______asdf3sC",
        "e": "AQAB"
    },
    {
        "kty": "RSA",
        "kid": "bEaunmA",
        "use": "sig",
        "alg": "RS256",
        "n": "BISvILNyn-lUu4goZSXBD9ackM9______RpUlq2w",
        "e": "AQAB"
    }
]
}

Ativando um Cluster para Descoberta do OIDC

Para ativar pods de aplicativos em execução em um cluster que você cria com o Kubernetes Engine para autenticação usando a Descoberta do OIDC ao acessar APIs hospedadas em um provedor de nuvem externo, defina a propriedade Ativar Descoberta do OIDC do cluster.

Usando a Console para Ativar um Cluster para Descoberta do OIDC

Criando um novo cluster ativado para Descoberta do OIDC

Para criar um cluster e permitir que os pods de aplicativos em execução no cluster sejam autenticados usando a Descoberta do OIDC ao acessar APIs hospedadas em um provedor de nuvem externo:

  1. Siga as instruções para criar um cluster usando o workflow 'Criação Personalizada'. Consulte Usando a Console para criar um Cluster com Definições Configuradas Explicitamente no workflow 'Criação Personalizada'.
  2. Na páginaCriar cluster, aceite os detalhes de configuração padrão do novo cluster ou especifique alternativas conforme a seguir:

    • Nome: O nome do novo cluster. Aceite o nome padrão ou digite um nome à sua escolha. Evite fornecer informações confidenciais.
    • Compartimento: O compartimento no qual o novo cluster será criado.
    • versão do Kubernetes: A versão do Kubernetes a ser executada nos nós do plano da cluster. Aceite a versão padrão ou selecione uma versão à sua escolha. Entre outras coisas, a versão do Kubernetes selecionada determina o conjunto padrão de controladores de admissão que são ativados no cluster criado (consulte Controladores de Admissão Suportados).
  3. Selecione Mostrar opções avançadas e no painel Descoberta do OpenID Connect (OIDC), selecione a opção Ativar Descoberta do OIDC.

  4. Informe outros detalhes de configuração para o novo cluster conforme descrito em Usando a Console para criar um Cluster com Definições Configuradas Explicitamente no workflow 'Criação Personalizada'.
  5. Selecione Criar cluster para criar o novo cluster agora.

Editando um cluster existente para ativar a Descoberta do OIDC

Para atualizar um cluster existente para permitir que os pods de aplicativos em execução no cluster sejam autenticados usando a Descoberta do OIDC ao acessar APIs hospedadas em um provedor de nuvem externo:

  1. Siga as instruções para atualizar um cluster existente usando a Console. Consulte Atualizando um Cluster.
  2. Na página Detalhes do Cluster, selecione Editar.

  3. Na janela Editar cluster, no painel Descoberta do OIDC (OpenID Connect), selecione a opção Ativar Descoberta do OIDC.

  4. Selecione Salvar para salvar as alterações.

Usando a CLI para Ativar um Cluster para Descoberta do OIDC

Para obter informações sobre como usar a CLI, consulte Interface de Linha de Comando (CLI). Para obter uma lista completa de flags e opções disponíveis para comandos da CLI, consulte a Referência da Linha de Comando.

Criando um Cluster e Ativando a Descoberta do OIDC

Para usar a CLI para criar um cluster aprimorado que use a Descoberta do OIDC para autenticar pods de aplicativos ao acessar APIs hospedadas em um provedor de nuvem externo, inclua o parâmetro --open-id-connect-discovery-enabled no comando oci ce cluster create.

Por exemplo:

oci ce cluster create \
--compartment-id ocid1.compartment.oc1..aaaaaaaa______n5q \
--name sales \
--vcn-id ocid1.vcn.oc1.phx.aaaaaaaa______lhq \
--type ENHANCED_CLUSTER \
--kubernetes-version v1.25.4 \
--service-lb-subnet-ids "[\"ocid1.subnet.oc1.phx.aaaaaaaa______g7q"]" \
--endpoint-subnet-id ocid1.subnet.oc1.phx.aaaaaaaa______sna \
--endpoint-public-ip-enabled true \
--endpoint-nsg-ids "[\"ocid1.networksecuritygroup.oc1.phx.aaaaaaaa______5qq\"]" \
--cluster-pod-network-options '[{"cniType":"OCI_VCN_IP_NATIVE"}]' \
--open-id-connect-discovery-enabled true

Editando um Cluster para Ativar a Descoberta do OIDC

Para usar a CLI para atualizar um cluster aprimorado a fim de usar a Descoberta do OIDC para autenticar pods de aplicativos ao acessar APIs hospedadas em um provedor de nuvem externo, defina o atributo isOpenIdConnectDiscoveryEnabled como verdadeiro:

  1. Em um editor adequado, crie um arquivo JSON com um nome de sua escolha (essas instruções supõem que o arquivo seja chamado de cluster-enable-oidc.json) contendo o seguinte:
    {
      "options": {
        "openIdConnectDiscovery": {
          "isOpenIdConnectDiscoveryEnabled": true
        }
      }
    }
  2. Salvar e fechar o arquivo cluster-enable-oidc.json.
  3. Atualize o cluster digitando:

    oci ce cluster update --cluster-id <cluster-ocid> --from-json file://<path-to-file>

    em que:

    • --cluster-id <cluster-ocid> é o OCID do cluster no qual você deseja ativar a Descoberta do OIDC.
    • --from-json file://<path-to-file> especifica o local do arquivo a ser usado ao atualizar o cluster.

    Por exemplo:

    oci ce cluster update --cluster-id ocid1.cluster.oc1.iad.aaaaaaaaaf______jrd --from-json file://./cluster-enable-oidc.json

Usando a API para Ativar um Cluster para Descoberta do OIDC

Execute a operação CreateCluster para criar um cluster ou a operação UpdateCluster para editar um cluster e especifique true como o valor do atributo isOpenIdConnectDiscoveryEnabled do recurso CreateClusterOptions ou do recurso UpdateClusterOptionsDetails, respectivamente.