Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Acesso seguro ao Google Cloud em pipelines do GitLab com Workload Identity Federation

By Chimbu ChinnaduraiSep 1, 20236 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

Secure-access-to-GCP-services-in-GitLab-Pipelines-with-Workload-Identity-Federation-DoiT-International

Tradicionalmente, ao usar serviços como o Google Cloud em um ambiente fora do GCP (por exemplo, um ambiente de CI/CD como pipelines do GitLab), os desenvolvedores precisavam usar chaves de service account ou outras credenciais de longa duração para autenticar nos serviços do Google Cloud. Mas essa abordagem traz alguns riscos de segurança:

  • Exposição prolongada de credenciais: chaves de service account são credenciais de longa duração, normalmente válidas até serem revogadas ou rotacionadas manualmente. Guardar essas chaves em repositórios de código-fonte, arquivos de configuração ou ambientes de CI/CD aumenta o risco de acesso não autorizado se esses repositórios ou ambientes forem comprometidos.
  • Escalonamento de privilégios: chaves de service account costumam ter permissões amplas, pensadas para executar diversas tarefas no Google Cloud. Se um invasor conseguir acesso a uma dessas chaves, ele pode chegar a uma vasta gama de recursos, indo muito além do necessário para uma aplicação ou workload específica.
  • Gerenciamento de credenciais: rotacionar chaves de service account com frequência é fundamental para seguir boas práticas de segurança. Só que a rotação manual é trabalhosa e propensa a erros, abrindo brechas de segurança.
  • Auditoria e rastreabilidade limitadas: ao usar chaves de service account, é difícil atribuir ações específicas a usuários ou serviços individuais. Essa falta de granularidade prejudica a auditoria e dificulta rastrear ações até a origem.

O workload identity federation do GCP resolve essas preocupações de segurança e permite usar seu provedor de identidade (IdP) atual para autenticar no Google Cloud Platform (GCP). Isso é especialmente útil em pipelines do GitLab, já que dá para usar suas credenciais do GitLab para autenticar no GCP sem ter que gerenciar service accounts ou credenciais separadas.

Os principais componentes do workload identity federation do GCP:

  • Provedor de identidade (IdP): é o sistema que autentica os usuários e emite credenciais para eles. O GCP é compatível com vários provedores de identidade, como Active Directory Federation Services (ADFS), Okta, Azure Active Directory ou qualquer provedor que suporte OpenID Connect (OIDC) ou SAML 2.0.
  • Workload identity pool: uma entidade que permite gerenciar identidades externas. Recomendamos criar um novo pool para cada ambiente fora do Google Cloud que precise acessar recursos do Google Cloud.
  • Service account: no GCP, service accounts representam workloads. Para acessar recursos, as identidades do pool precisam receber acesso a uma service account. Depois disso, essas identidades passam a ter permissão para usar todos os serviços do Google Cloud aos quais a service account tem acesso.
  • Token federado: é um token emitido pelo IdP e trocado por um token de service account. O token federado permite que o workload se autentique no GCP como se fosse a service account.

Neste artigo, vamos mostrar como configurar o workload identity federation no GCP e acessar com segurança os serviços do GCP usando tokens de curta duração em pipelines do GitLab.

Pré-requisitos

  • Confirme que você tem as funções Workload Identity Pool Admin (roles/iam.workloadIdentityPoolAdmin) e Service Account Admin (roles/iam.serviceAccountAdmin) no projeto.
  • Habilite as APIs abaixo.
#Update $GCP_PROJECT_ID value
gcloud services enable cloudresourcemanager.googleapis.com \
iam.googleapis.com \
iamcredentials.googleapis.com \
sts.googleapis.com \
--project $GCP_PROJECT_ID
  • Uma conta no GitLab. Crie uma nova conta se ainda não tiver.

Configurando o Workload Identity Federation

  • Passo 1: crie um Workload Identity Pool.
#Update $GCP_PROJECT_ID value
gcloud iam workload-identity-pools create gitlab-demo-wip \
--location="global" \
--description="Gitlab demo workload Identity pool" \
--display-name="gitlab-demo-wip"
--project=$GCP_PROJECT_ID

gitlab-ci-cd

workload identity pool

gitlab

configuração do workload identity pool

  • Passo 2: adicione um provedor de workload identity pool para o GitLab e use condições de atributos para restringir quais identidades podem se autenticar via workload identity pool.
  • A configuração do mapeamento de atributos é uma parte essencial do workload identity federation. Ela permite mapear atributos das credenciais de autenticação emitidas por um provedor de identidade externo para atributos do Google Cloud, como subject e email. Alguns provedores de identidade chamam esses atributos de claims.
  • Cada provedor de identidade externo pode expor atributos diferentes. Para a AWS, o Google fornece mapeamentos padrão que cobrem a maioria dos cenários comuns. Você também pode definir mapeamentos personalizados.
  • Para provedores OIDC como o GitLab, o mapeamento fica por sua conta. Para construí-lo, consulte a documentação do provedor com a lista de atributos disponíveis nas credenciais. No caso do GitLab, veja o payload do ID Token com os claims incluídos em cada ID token do GitLab.

A condição de atributo abaixo restringe as identidades apenas ao meu namespace pessoal do GitLab. Consulte a documentação de namespace do GitLab para saber se você está visualizando um namespace de grupo ou pessoal.

#Update GITLAB_NAMESPACE_PATH value
gcloud iam workload-identity-pools providers create-oidc gitlab-identity-provider --location="global" \
--workload-identity-pool="gitlab-demo-wip" \
--issuer-uri="https://gitlab.com" \
--allowed-audiences=https://gitlab.com \
--attribute-mapping="google.subject=assertion.sub,attribute.aud=assertion.aud,attribute.project_path=assertion.project_path,attribute.project_id=assertion.project_id,attribute.namespace_id=assertion.namespace_id,attribute.namespace_path=assertion.namespace_path,attribute.user_email=assertion.user_email,attribute.ref=assertion.ref,attribute.ref_type=assertion.ref_type" \
--attribute-condition="assertion.namespace_path.startsWith(\"$GITLAB_NAMESPACE_PATH\")" \
--project=$GCP_PROJECT_ID

ci

exemplo de saída do comando gcloud

pipeline

provedor do GitLab adicionado ao workload identity pool

gitlab

configuração do provedor de identidade do GitLab

  • Neste ponto, você já consegue autenticar a partir de um job de CI/CD do GitLab no Google Cloud. Mas ainda não tem permissões no Google Cloud (autorização).
  • Passo 3: crie uma service account que a identidade externa do GitLab possa personificar.
#Create a service account
gcloud iam service-accounts create gitlab-wif-demo --project=$GCP_PROJECT_ID
#Add sample permissions to the Service account
gcloud projects add-iam-policy-binding $GCP_PROJECT_ID \
--member=serviceAccount:gitlab-wif-demo@${GCP_PROJECT_ID}.iam.gserviceaccount.com \
--role=roles/storage.admin
  • Passo 4: conceda permissão para a identidade externa do GitLab personificar a service account, permitindo que um job de CI/CD do GitLab autorize o Google Cloud via personificação de service account. Esse passo concede a permissão IAM na própria service account, dando à identidade externa autoridade para agir como aquela service account.

O comando abaixo permite que todas as identidades do pool acessem recursos do GCP via personificação de service account, mas recomendamos restringir a personificação a identidades externas específicas com base em seus atributos.

Consulte https://cloud.google.com/iam/docs/workload-identity-federation#impersonation para cenários comuns de concessão de funções.

PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\) --project $GCP_PROJECT_ID)
gcloud iam service-accounts add-iam-policy-binding gitlab-wif-demo@${GCP_PROJECT_ID}.iam.gserviceaccount.com \
--role=roles/iam.workloadIdentityUser \
--member="principalSet://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/gitlab-demo-wip/*"

gitlab

service account vinculada ao workload identity pool

Testando o Workload Identity Federation em um pipeline do GitLab

Nos passos anteriores, configuramos o workload identity pool para confiar nas identidades do meu namespace pessoal do GitLab. Não é preciso alterar nada na sua conta do GitLab — você pode habilitar o workload identity federation por job de CI/CD. E dá para personalizar a configuração conforme sua necessidade.

  • Passo 5: crie um projeto vazio no GitLab ou use um projeto existente.

gitlab

repositório do GitLab

  • Passo 6: crie um arquivo chamado .gitlab-ci.yml e configure um pipeline do GitLab com o template abaixo. Veja CI/CD pipelines para saber mais sobre pipelines do GitLab.
#Update the $GCP_PROJECT_NAME and $GCP_PROJECT_NUMBER values
variables:
GCP_PROJECT_NAME: $GCP_PROJECT_NAME
GCP_WORKLOAD_IDENTITY_PROVIDER: "projects/$GCP_PROJECT_NUMBER/locations/global/workloadIdentityPools/gitlab-demo-wip/providers/gitlab-identity-provider"
SERVICE_ACCOUNT_EMAIL: "gitlab-wif-demo@$GCP_PROJECT_NAME.iam.gserviceaccount.com"
stages:
- gcp_wif_demo
.gcp_wif_auth: &gcp_wif_auth
#id_tokens to create JSON web tokens (JWT) to authenticate with third party services.This replaces the CI_JOB_JWT_V2
id_tokens:
GITLAB_OIDC_TOKEN:
aud: https://gitlab.com
before_script:
- apt-get update && apt-get install -yq jq
#Get temporary credentials using the ID token
- |
PAYLOAD=$(cat <<EOF
{
"audience": "//iam.googleapis.com/${GCP_WORKLOAD_IDENTITY_PROVIDER}",
"grantType": "urn:ietf:params:oauth:grant-type:token-exchange",
"requestedTokenType": "urn:ietf:params:oauth:token-type:access_token",
"scope": "https://www.googleapis.com/auth/cloud-platform",
"subjectTokenType": "urn:ietf:params:oauth:token-type:jwt",
"subjectToken": "${GITLAB_OIDC_TOKEN}"
}
EOF
)
- |
FEDERATED_TOKEN=$(curl -s -X POST "https://sts.googleapis.com/v1/token" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "${PAYLOAD}" \
| jq -r '.access_token'
)
#Use the federated token to impersonate the service account linked to workload identity pool
#The resulting access token is stored in CLOUDSDK_AUTH_ACCESS_TOKEN environment variable and this will be passed to the gcloud CLI
- |
export CLOUDSDK_AUTH_ACCESS_TOKEN=$(curl -s -X POST "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${SERVICE_ACCOUNT_EMAIL}:generateAccessToken" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Authorization: Bearer ${FEDERATED_TOKEN}" \
--data '{"scope": ["https://www.googleapis.com/auth/cloud-platform"]}' \
| jq -r '.accessToken'
)
gcloud_test:
<<: *gcp_wif_auth
stage: gcp_wif_demo
image: gcr.io/google.com/cloudsdktool/google-cloud-cli:441.0.0
script:
- gcloud config set project ${GCP_PROJECT_NAME}
- gcloud storage ls

workload

.gitlab-ci.yml

  • POR PADRÃO, os pipelines de CI/CD do GitLab rodam automaticamente sempre que novos commits são enviados. Confira a saída do pipeline em Build -> Pipelines.

gcp

status do disparo do pipeline do GitLab

workload

exemplo de log do job do GitLab

Os logs do job mostram que a autenticação e a autorização funcionaram como esperado, com o token de curta duração gerado pelo Workload Identity Federation.

No fim das contas, o Workload Identity Federation é um serviço valioso que ajuda a proteger seus pipelines do GitLab e a melhorar sua postura de segurança. Se você ainda não usa, vale muito a pena adotá-lo nos seus pipelines no lugar de chaves de service account.