Configurar a federação de identidade da carga de trabalho com pipelines de implantação

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

Neste guia, descrevemos como usar a federação de identidade da carga de trabalho para permitir que os pipelines de implantação sejam autenticados no Google Cloud.

Dependendo do sistema de CI/CD usado, os pipelines de implantação podem ter acesso a credenciais de ambiente específicas para o ambiente. Exemplo:

  • Os fluxos de trabalho do GitHub Actions podem receber um token OIDC do GitHub que identifica exclusivamente o fluxo de trabalho e o repositório dele.
  • O Terraform Cloud pode fornecer um token OIDC para a configuração do Terraform que identifica exclusivamente o espaço de trabalho e o ambiente.

Ao usar a federação de identidade da carga de trabalho, é possível evitar a necessidade de armazenar e gerenciar chaves de conta de serviço e permitir que os pipelines de implantação usem as credenciais específicas do ambiente para acessar as APIs do Google Cloud.

Preparar seu IdP externo

Ações do GitHub

Não é necessário fazer alterações na configuração da sua conta do GitHub.

Depois de configurar um pool de identidades de carga de trabalho para confiar no repositório do GitHub, permita que os fluxos de trabalho nesse repositório usem o token OIDC do GitHub para receber credenciais do Google Cloud de curta duração.

Terraform Cloud

Não é necessário fazer alterações de configuração na sua conta do Terraform Cloud.

Depois de configurar um pool de identidades de carga de trabalho para confiar no Terraform Cloud, é possível ativar a federação de identidade de carga de trabalho para espaços de trabalho individuais.

Configurar a federação de identidade da força de trabalho

Realize essas etapas para cada organização do GitHub ou do Cloud do Terraform.

Para começar a configurar a federação de identidade da carga de trabalho, faça o seguinte:

  1. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  2. É melhor usar um projeto dedicado para gerenciar pools e provedores de identidade da carga de trabalho
  3. Verifique se o faturamento está ativado para seu projeto na nuvem. Saiba como verificar se o faturamento está ativado em um projeto.

  4. Ative as APIs IAM, Resource Manager, Service Account Credentials, and Security Token Service.

    Ative as APIs

Definir um mapeamento e uma condição de atributo

As credenciais específicas do ambiente do pipeline de implantação contêm vários atributos, e você precisa decidir qual atributo quer usar como identificador do assunto (google.subject) no Google Cloud.

Também é possível mapear outros atributos. Consulte esses atributos adicionais ao conceder acesso aos recursos.

Ações do GitHub

Os mapeamentos de atributos podem usar as declarações incorporadas no token do OIDC como atributos de origem, incluindo:

  • sub: contém o nome do repositório e a referência do Git, por exemplo, repo:username/reponame:ref:refs/heads/master.
  • repository: contém o nome do proprietário e do repositório, por exemplo, username/reponame.
  • repository_owner: contém o proprietário, que pode ser um nome de usuário ou o nome de uma organização do GitHub.
  • ref: contém a referência do Git, por exemplo, refs/heads/main.

O mapeamento de atributos a seguir define google.subject na declaração sub do token OIDC do GitHub Actions. Como a declaração sub contém o nome do repositório e a referência do Git, esse mapeamento permite controlar o acesso por repositório e ramificação:

google.subject=assertion.sub

O controle de acesso por repositório e branch pode ser útil se determinados branches (por exemplo, main) precisarem de acesso diferente aos recursos de outros branches, por exemplo, branches de recursos.

Se você não planeja diferenciar o acesso por branch, use o mapeamento de atributo a seguir, que define google.subject como a declaração repository:

google.subject=assertion.repository

Terraform Cloud

Os mapeamentos de atributos podem usar as declarações incorporadas no token do Cloud OIDC do Terraform, incluindo as seguintes:

  • terraform_organization_id: contém o ID exclusivo da organização, por exemplo, org-xxxxxxxxxxxxxxxx.
  • terraform_workspace_id: contém o ID exclusivo do espaço de trabalho, por exemplo, ws-xxxxxxxxxxxxxxxx.
  • terraform_workspace_name: contém o nome de exibição do espaço de trabalho.
  • sub: contém o nome de exibição da organização, do espaço de trabalho e da fase, por exemplo, organization:example-org:workspace:example-workspace:run_phase:apply.

O mapeamento de atributo a seguir define google.subject para a declaração terraform_workspace_id do token OIDC do Terraform Cloud:

google.subject=assertion.terraform_workspace_id

Esse mapeamento permite controlar o acesso aos recursos do Google Cloud por espaço de trabalho.

As condições do atributo são expressões CEL que podem verificar atributos de declaração e atributos de destino. Se a condição do atributo for avaliada como true para uma determinada credencial, a credencial será aceita. Caso contrário, a credencial será rejeitada.

Ações do GitHub

Use a seguinte condição para restringir o acesso a tokens emitidos pela organização do GitHub:

assertion.repository_owner=='ORGANIZATION'

Substitua ORGANIZATION pelo nome da sua organização do GitHub.

Se quiser, estenda a condição do atributo para restringir o acesso a um subconjunto de fluxos de trabalho ou ramificações. Por exemplo, a condição a seguir limita o acesso a fluxos de trabalho que usam a ramificação Git main:

assertion.repository_owner=='ORGANIZATION' && assertion.ref=='refs/heads/main'

Terraform Cloud

Use a condição a seguir para restringir o acesso aos tokens emitidos pela organização do Terraform para o Cloud:

assertion.terraform_organization_id=='ORGANIZATION_ID'

Substitua ORGANIZATION_ID pelo ID exclusivo da sua organização, por exemplo, org-xxxxxxxxxxxxxxxx. Se quiser, estenda a condição do atributo para restringir o acesso a um subconjunto de fluxos de trabalho ou ramificações. Por exemplo, a condição a seguir limita o acesso a um espaço de trabalho específico:

assertion.terraform_organization_id=='ORGANIZATION_ID' && terraform_workspace_id=='WORKSPACE_ID'

Crie um pool de identidades e um provedor de carga de trabalho

Papéis obrigatórios

Para receber as permissões necessárias para configurar a federação de identidade da carga de trabalho, peça ao administrador para conceder a você os seguintes papéis do IAM no projeto:

  • Administrador de pool de Identidade da carga de trabalho (roles/iam.workloadIdentityPoolAdmin)
  • Administrador da conta de serviço (roles/iam.serviceAccountAdmin)

Para mais informações sobre como conceder papéis, consulte Gerenciar o acesso.

Como alternativa, o papel básico de Proprietário do IAM (roles/owner) também inclui permissões para configurar a federação de identidade. Não conceda papéis básicos em um ambiente de produção, recomendamos que você faça isso em um ambiente de desenvolvimento ou teste.

Coletamos todas as informações necessárias para criar um pool de identidades e um provedor de carga de trabalho:

Console

  1. No Console do Google Cloud, acesse a página Novo provedor de carga de trabalho e pool.

    Acessar "Novo provedor de carga de trabalho" e "Pool"

  2. Em Criar um pool de identidades, digite o seguinte:

    • Nome: o nome do pool. O nome também é usado como o ID do pool. Não será possível alterar o ID do pool posteriormente.
    • Descrição: texto que descreve a finalidade do pool.
  3. Clique em Continuar.

  4. Defina as configurações do provedor:

    Ações do GitHub

    • Selecione um provedor: OpenID Connect (OIDC).
    • Nome do provedor: nome do provedor. O nome também é usado como o ID do provedor. Não será possível alterar o ID depois.
    • URL do emissor: https://token.actions.githubusercontent.com/
    • Públicos-alvo: padrão

    Terraform Cloud

    • Selecione um provedor: OpenID Connect (OIDC).
    • Nome do provedor: nome do provedor. O nome também é usado como o ID do provedor. Não será possível alterar o ID depois.
    • URL do emissor: https://app.terraform.io
    • Públicos-alvo: padrão
  5. Clique em Continuar.

  6. Em Configurar atributos do provedor, adicione os mapeamentos de atributos identificados anteriormente.

  7. Em Condições de atributo, digite a condição do atributo que você identificou anteriormente. Deixe o campo em branco se não houver uma condição de atributo.

  8. Clique em Salvar para criar o pool de identidades e o provedor da carga de trabalho.

gcloud

  1. Crie um novo pool de identidades de carga de trabalho:

    gcloud iam workload-identity-pools create POOL_ID \
        --location="global" \
        --description="DESCRIPTION" \
        --display-name="DISPLAY_NAME"
    

    Substitua os seguintes valores:

    • POOL_ID: o ID exclusivo do pool.
    • DISPLAY_NAME: o nome do pool.
    • DESCRIPTION: a descrição do pool Essa descrição aparece ao conceder acesso às identidades do pool.
  2. Adicione um provedor de pool de identidades de carga de trabalho:

    Ações do GitHub

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="https://token.actions.githubusercontent.com/" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    Substitua os seguintes valores:

    Terraform Cloud

    gcloud iam workload-identity-pools providers create-oidc PROVIDER_ID \
        --location="global" \
        --workload-identity-pool="POOL_ID" \
        --issuer-uri="https://app.terraform.io" \
        --attribute-mapping="MAPPINGS" \
        --attribute-condition="CONDITIONS"
    

    Substitua os seguintes valores:

Autenticar um pipeline de implantação

Realize essas etapas para cada fluxo de trabalho do GitHub Actions ou do espaço de trabalho do Terraform Cloud.

Criar uma conta de serviço para o pipeline de implantação

  1. Ative as APIs IAM, Security Token Service, and Service Account Credentials.

    Ative as APIs

  2. Crie uma conta de serviço que represente a carga de trabalho. Recomendamos que você use uma conta de serviço dedicada para cada pipeline de implantação.

    A conta de serviço não precisa estar no mesmo projeto que o pool de identidades da carga de trabalho.

  3. Conceda à conta de serviço acesso a recursos que você quer que as identidades externas acessem.

Permitir que o pipeline de implantação represente a conta de serviço

Para permitir que identidades externas personifiquem uma conta de serviço, você precisa conceder a elas o papel de usuário de identidade da carga de trabalho (roles/iam.workloadIdentityUser) na conta de serviço. É possível conceder o papel a uma identidade externa específica ou a várias identidades externas:

  • Para uma identidade externa específica, escreva uma condição de atributo que verifique o atributo google.subject.
  • Para um grupo de identidades externas, escreva uma condição de atributo que verifique o atributo google.groups ou um atributo personalizado attribute.NAME.
  • Para todas as identidades externas no pool de identidades da carga de trabalho, você não usa uma condição de atributo.

Console

Para permitir que identidades externas representem uma conta de serviço usando o console do Google Cloud, faça o seguinte:

  1. No Console do Google Cloud, acesse a página Pools de Identidades da carga de trabalho.

    Acesse Pools de identidade da carga de trabalho

  2. Encontre o pool de identidades da carga de trabalho que você quer atualizar e selecione-o.

  3. Para conceder acesso ao pool de identidades da carga de trabalho selecionado, clique em Conceder acesso.

  4. Na lista Conta de serviço, selecione a conta de serviço para as identidades externas a serem personificadas.

  5. Para escolher quais identidades no pool podem representar a conta de serviço, execute uma das seguintes ações:

    • Para permitir que apenas identidades específicas do pool de identidades de carga de trabalho personifiquem a conta de serviço, selecione Somente identidades correspondentes ao filtro.

      Na lista Nome do atributo, selecione o atributo que você quer filtrar.

      No campo Valor do atributo, insira o valor esperado do atributo. Por exemplo, se você usar um mapeamento de atributo google.subject=assertion.sub, defina o nome do Atributo como subject e o Valor do atributo para o valor da declaração sub em tokens emitidos pelo seu provedor de identidade externo.

    • Para permitir que todas as identidades externas do pool de identidades de carga de trabalho personifiquem a conta de serviço, selecione Todas as identidades no pool.

  6. Para salvar a configuração, clique em Salvar e em Dispensar.

gcloud

Para permitir que identidades externas representem uma conta de serviço usando a CLI gcloud, faça o seguinte:

  1. Para ver o número do projeto, execute o seguinte comando:

    gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\)
    
  2. Para conceder o papel de usuário da Identidade da carga de trabalho (roles/iam.workloadIdentityUser) a identidades externas que atendam a um determinado critério:

    Por assunto

    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"
    

    Por grupo

    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/group/GROUP"
    

    Por atributo

    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.ATTRIBUTE_NAME/ATTRIBUTE_VALUE"
    

    Todas as identidades externas

    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/*"
    

    Substitua:

    • SERVICE_ACCOUNT_EMAIL: o endereço de e-mail da conta de serviço.
    • PROJECT_NUMBER: o número do projeto que contém o pool de identidade da carga de trabalho
    • POOL_ID: o ID do pool de identidade da carga de trabalho
    • SUBJECT: o valor esperado do atributo mapeado para google.subject
    • GROUP: o valor esperado do atributo mapeado para google.groups
    • ATTRIBUTE_NAME: o nome de um atributo personalizado no seu mapeamento de atributos

Configurar o pipeline de implantação

Agora você já pode usar a federação de identidade da carga de trabalho no pipeline de implantação.

Ações do GitHub

A ação google-github-actions/auth permite gerar automaticamente um arquivo de configuração de credenciais durante a execução do fluxo de trabalho. As ferramentas e bibliotecas de cliente, como terraform, podem usar esse arquivo de configuração de credenciais para receber credenciais do Google automaticamente.

Edite o arquivo YAML do GitHub Actions e adicione o seguinte:

  • Permita que o job busque um token de ID do GitHub adicionando a seguinte configuração:

    permissions:
      id-token: write
      contents: read
    
  • Adicione uma etapa para criar um arquivo de configuração de credenciais:

    - id: 'auth'
      name: 'Authenticate to Google Cloud'
      uses: 'google-github-actions/auth@v0'
      with:
        create_credentials_file: true
        workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID'
        service_account: 'SERVICE_ACCOUNT_EMAIL'
    

Substitua os seguintes valores:

  • PROJECT_NUMBER: o número do projeto que contém o pool de identidade da carga de trabalho
  • POOL_ID: o ID do pool de identidade da carga de trabalho
  • PROVIDER_ID: o ID do provedor do pool de identidade da carga de trabalho
  • SERVICE_ACCOUNT_EMAIL: o endereço de e-mail da conta de serviço.

Exemplo:

jobs:
  build:
    # Allow the job to fetch a GitHub ID token
    permissions:
      id-token: write
      contents: read

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - id: 'auth'
        name: 'Authenticate to Google Cloud'
        uses: 'google-github-actions/auth@v0'
        with:
          create_credentials_file: true
          workload_identity_provider: 'projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID'
          service_account: 'SERVICE_ACCOUNT_EMAIL'

Para mais detalhes sobre o uso da ação google-github-actions/auth, consulte Como configurar a federação de identidade da carga de trabalho.

Terraform Cloud

Defina seu espaço de trabalho para que a configuração possa receber um token do OIDC do Terraform:

  1. No Terraform Cloud, abra seu espaço de trabalho e acesse Variáveis.

  2. Clique em Adicionar variável e inclua o seguinte:

    • Categoria da variável: variável de ambiente
    • Chave: TFC_WORKLOAD_IDENTITY_AUDIENCE
    • Valor:
      https://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID

    Substitua os seguintes valores:

    • PROJECT_NUMBER: o número do projeto que contém o pool de identidade da carga de trabalho
    • POOL_ID: o ID do pool de identidade da carga de trabalho
    • PROVIDER_ID: o ID do provedor do pool de identidade da carga de trabalho
  3. Clique em Salvar variável.

Atualize a configuração do Terraform para usar credenciais fornecidas e um script de shell para ler o token OIDC da variável de ambiente TFC_WORKLOAD_IDENTITY_AUDIENCE e usá-lo para a federação de identidade da carga de trabalho:

  1. No Terraform Cloud, na configuração do espaço de trabalho, adicione mais duas variáveis:

    Categoria variável Chave Valor
    Variável de ambiente GOOGLE_APPLICATION_CREDENTIALS .google-cloud/workload-identity.json
    Variável de ambiente GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES 1

    Essas variáveis instruem terraform e as bibliotecas de cliente a usar credenciais originárias de executáveis e a configuração armazenada no arquivo .google-cloud/workload-identity.json.

  2. No repositório do código-fonte, crie o arquivo .google-cloud/workload-identity.json e copie a seguinte configuração:

    {
      "type": "external_account",
      "audience": "//iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID",
      "subject_token_type": "urn:ietf:params:oauth:token-type:jwt",
      "token_url": "https://sts.googleapis.com/v1/token",
      "credential_source": {
        "executable": {
          "command": "/bin/bash .google-cloud/workload-token.sh",
          "timeout_millis": 5000
        }
      },
      "service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/SERVICE_ACCOUNT_EMAIL:generateAccessToken"
    }
    

    Substitua os seguintes valores:

    • PROJECT_NUMBER: o número do projeto que contém o pool de identidade da carga de trabalho
    • POOL_ID: o ID do pool de identidade da carga de trabalho
    • PROVIDER_ID: o ID do provedor do pool de identidade da carga de trabalho
    • SERVICE_ACCOUNT_EMAIL: o endereço de e-mail da conta de serviço.

    Essa configuração instrui as bibliotecas de cliente a executar um script, .google-cloud/workload-token.sh, para receber um token do OIDC do Terraform Cloud.

  3. No repositório do código-fonte, crie outro arquivo, .google-cloud/workload-token.sh, e copie o script a seguir:

    #!/bin/sh
    if [ -z $TFC_WORKLOAD_IDENTITY_TOKEN ]
    then
        echo '{"version": 1, "success": false, "code": "missing-variable", "message": "TFC_WORKLOAD_IDENTITY_TOKEN not defined in workspace."}'
    else
        echo '{"version": 1, "success": true, "token_type": "urn:ietf:params:oauth:token-type:id_token", "id_token": "'"$TFC_WORKLOAD_IDENTITY_TOKEN"'"}'
    fi
    

    Esse script lê o token OIDC do Terraform da variável de ambiente TFC_WORKLOAD_IDENTITY_TOKEN e retorna o token no formato esperado pelas bibliotecas de cliente.

  4. Verifique se a configuração do Terraform usa a versão 4.48.0 ou mais recente do provedor do Google Cloud e atualize, se necessário, da seguinte maneira:

    terraform {
      required_providers {
        google = {
          source  = "hashicorp/google"
          version = "~> 4.48.0"
        }
      }
    }
    
  5. Envie as alterações para seu repositório de código-fonte.

A seguir