Como acessar recursos de um provedor de identidade OIDC

Este documento mostra como usar a federação de identidades para acessar recursos do Google Cloud a partir de um provedor de identidade compatível com o OpenID Connect (OIDC).

Os aplicativos executados fora do Google Cloud costumavam usar chaves de conta de serviço para acessar os recursos do Google Cloud. Com a federação de identidade, é possível permitir que uma identidade externa personifique uma conta de serviço. Isso possibilita que a carga de trabalho acesse os recursos do Google Cloud diretamente, usando um token de acesso de curta duração, e elimina a sobrecarga de manutenção e segurança associada às chaves de conta de serviço.

Antes de começar

  1. Verifique se você tem o papel Administrador de pool de Identidade da carga de trabalho (roles/iam.workloadIdentityPoolAdmin).

    Os papéis primários Proprietário do IAM (roles/owner) e Editor (roles/editor) também concedem permissão para configurar a federação de identidade. No entanto, recomendamos usar o papel Administrador de pool de Identidade da carga de trabalho para evitar a concessão de acesso desnecessário aos recursos do Google Cloud.

  2. Crie uma conta de serviço do Google Cloud.

  3. Conceda à conta de serviço acesso para chamar as APIs do Google Cloud necessárias à carga de trabalho.

Como criar um pool de identidades de carga de trabalho

Um pool de identidade de carga de trabalho é um contêiner para uma coleção de identidades externas. Os pools de identidade de carga de trabalho são isolados uns dos outros, mas um único pool pode representar qualquer número de contas de serviço. Em geral, recomendamos a criação de um novo pool para cada um dos ambientes, como desenvolvimento, preparação ou produção.

Para criar um novo pool de identidades de carga de trabalho, você precisa fornecer um ID. Também é possível fornecer uma description e um nome de exibição opcionais.

Comando gcloud

Execute o comando gcloud beta iam workload-identity-pools create para criar um pool de identidades de carga de trabalho:

gcloud beta iam workload-identity-pools create pool-id \
    --location="global" \
    --description="description" \
    --display-name="display-name"

API REST

O método projects.locations.workloadIdentityPools.create cria um pool de identidades de carga de trabalho.

Método HTTP e URL:

POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools?workloadIdentityPoolId=pool-id

Corpo JSON da solicitação:

{
  "description": "description",
  "display-name": "display-name"
}

Para enviar a solicitação, expanda uma destas opções:

 

Como adicionar um provedor de identidade OIDC

Para configurar um provedor de identidade OIDC para seu pool de identidades de carga de trabalho, forneça pelo menos:

  • Um ID do provedor.

  • O ID do pool de identidades de carga de trabalho da seção anterior deste documento.

  • O URI do emissor do provedor. Ele normalmente tem o formato https://example.com. Consulte a documentação do seu provedor sobre a integração de OIDC para encontrar o URI.

Também é possível especificar vários parâmetros opcionais:

  • Um nome de exibição e uma descrição.

  • Uma lista de mapeamentos de atributo, que mapeiam as declarações em um token externo para os atributos em um token do Google. Use assertion para referenciar a credencial externa, google para atributos do Google e attribute para atributos personalizados.

    Há dois atributos do Google: google.subject e google.groups. É possível referenciar esses atributos nas vinculações do IAM. google.subject também aparece nas entradas de registro do Cloud Logging.

    Em geral, recomendamos mapear assertion.sub para google.subject. Isso fornece um identificador estável para uso em vinculações do IAM. O mapeamento é semelhante a este:

    google.subject=assertion.sub
    

    Para declarações mais complexas, use a Common Expression Language. Por exemplo, se o pool de identidades de carga de trabalho tiver vários provedores de identidade, será possível acrescentar um prefixo para diferenciá-los:

    google.subject="provider-a::" + assertion.sub
    

    O campo google.subject não pode exceder 127 caracteres.

    Também é possível especificar atributos personalizados. Por exemplo, o comando a seguir mapeia assertion.foo para attribute.bar:

    attribute.bar=assertion.foo
    

    Consulte a documentação do seu provedor sobre tokens de acesso para ver uma lista completa das declarações que você pode usar como referência.

    Para referir-se a uma parte específica de uma declaração em uma expressão, use a função extract() CEL, que extrai um valor de uma declaração com base em um modelo fornecido por você. Para saber mais sobre extract(), consulte Como extrair valores de atributos.

    Para verificar se uma credencial contém uma declaração, use a função has().

  • Uma condição de atributo que especifica os atributos que o principal precisa apresentar. A condição pode ser aplicada a declarações da credencial externa ou a atributos da credencial do Google. Qualquer solicitação que não atenda à condição será rejeitada.

    As condições do atributo são formatadas como uma expressão CEL que retorna um booleano. Por exemplo, o comando a seguir rejeita solicitações de qualquer identidade que não seja membro de um grupo específico:

    group in assertion.groups
    

    Se o provedor de identidade estiver disponível para o público em geral, é recomendável usar condições de atributos. Para saber mais sobre casos de uso comuns de condições de atributos, consulte a visão geral da federação de identidades de carga de trabalho.

  • Uma lista de públicos permitidos especificando quais valores o campo aud da credencial externa pode conter. É possível configurar no máximo 10 públicos, cada um com até 256 caracteres. Consulte a documentação do provedor para mais informações sobre os valores padrão de aud.

    Como alternativa, caso seu provedor de identidade permita que você configure um valor personalizado para aud, deixe o parâmetro de público permitido em branco e defina o valor de aud como o nome de recurso completo do seu provedor de identidade de carga de trabalho. O prefixo HTTP é opcional. Por exemplo:

    //iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id
    https://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/providers/provider-id
    

    Em ambos os casos, todas as solicitações de troca de token que não contiverem um dos valores permitidos serão rejeitadas.

No exemplo a seguir, veja como adicionar um provedor de identidade:

Comando gcloud

Execute o comando gcloud beta iam workload-identity-pools providers create-oidc para adicionar um provedor de identidade:

gcloud beta iam workload-identity-pools providers create-oidc provider-id \
    --workload-identity-pool="pool-id" \
    --issuer-uri="issuer-uri" \
    --location="global"

API REST

O método projects.locations.workloadIdentityPools.providers.create adiciona um provedor de identidade OIDC.

Método HTTP e URL:

POST https://iam.googleapis.com/v1beta/projects/project-id/locations/global/workloadIdentityPools/pool-id/providers?workloadIdentityPoolProviderId=provider-id

Corpo JSON da solicitação:

{
  "issuerUrl": "issuer-uri"
}

Para enviar a solicitação, expanda uma destas opções:

 

Como personificar uma conta de serviço

É possível conceder pools de identidades de carga de trabalho e identidades federadas com base nos próprios provedores e papéis nos recursos usando o IAM. O papel Usuário de identidade da carga de trabalho (roles/iam.workloadIdentityUser) concede permissão para personificar uma conta de serviço, o que permite que identidades externas acessem os recursos do Google Cloud.

Para adicionar essa vinculação a uma identidade específica, use o valor mapeado para google.subject:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
  --role roles/iam.workloadIdentityUser \
  --member "principal://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/subject/subject"

Para adicionar essa vinculação a todos os membros de um grupo:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
    --role roles/iam.workloadIdentityUser \
    --member "principalSet://iam.googleapis.com/project/project-number/workloadIdentityPools/pool-id/groups/group-name"

Também é possível conceder acesso com base em atributos personalizados. Por exemplo:

gcloud iam service-accounts add-iam-policy-binding service-account-email \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/project-number/locations/global/workloadIdentityPools/pool-id/attribute.custom-attribute-name/custom-attribute-value"

Para revogar o acesso, substitua add-iam-policy-binding por remove-iam-policy-binding.

Também é possível adicionar ou revogar vinculações usando a API REST ou bibliotecas de cliente. Para saber mais, consulte Como conceder, alterar e revogar o acesso a recursos.

Como trocar um token externo por um token do Google

Depois que sua identidade externa conseguir personificar uma conta de serviço, troque as credenciais dela por credenciais do Google.

Para trocar credenciais:

  1. Consiga um token de ID do OIDC do seu provedor de identidade (consulte a documentação do seu provedor de identidade para ver instruções detalhadas).

  2. Envie o token de ID do OIDC para o método token() do Security Token Service para receber um token de acesso federado:

    API REST

    O método token troca um token de terceiros por um do Google.

    Antes de usar os dados da solicitação abaixo, faça as substituições a seguir:

    • project-id: o ID do projeto do Google Cloud.
    • pool-id: o ID do pool de identidades de carga de trabalho que você já criou neste tutorial.
    • provider-id: o ID do provedor de identidade que você já configurou neste tutorial.

    Método HTTP e URL:

    POST https://sts.googleapis.com/v1beta/token

    Corpo JSON da solicitação:

    {
      "audience": "https://iam.googleapis.com/projects/project-id/locations/global/workloadIdentityPools/pool-id/providers/provider-id",
      "grant_type": "urn:ietf:params:oauth:grant-type:token-exchange",
      "requested_token_type": "urn:ietf:params:oauth:token-type:access_token",
      "scope": "https://www.googleapis.com/auth/cloud-platform",
      "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
      "subject_token": "oidc-id-token"
    }
    

    Para enviar a solicitação, expanda uma destas opções:

     

    O método retorna um token federado.

  3. Troque o token federado por um token de acesso do OAuth 2.0 chamando generateAccessToken():

    API REST

    curl -X POST -H "Authorization: Bearer federated-token \
      https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/service-account-email:generateAccessToken
    

Quando você tiver um token de acesso para uma conta de serviço, poderá usá-lo para chamar as APIs do Google Cloud incluindo o token no cabeçalho Authorization das suas solicitações:

Authorization: Bearer service-account-access-token

A solicitação está autorizada como a conta de serviço.

A seguir