Destino Dev

Blog

GitHub Actions OIDC: deploy sem segredos em AWS, GCP e Azure (setup prático)

Por John Pires · 11 de março de 2026

GitHub Actions OIDC: deploy sem segredos em AWS, GCP e Azure (setup prático)

Contexto e motivacao

Autenticação baseada em tokens temporários elimina o fluxo inseguro de colocar chaves estáticas em repositórios ou GitHub Secrets. OID C (OpenID Connect) integrado ao GitHub Actions permite que runners solicitem tokens de identidade federada assinados por token.actions.githubusercontent.com, que provêem prova de identidade do workflow para provedores de nuvem. Isso reduz a superfície de ataque, facilita rotação e melhora governança.

O objetivo aqui é prático: configurar e usar OIDC para realizar deploys em AWS, GCP e Azure sem armazenar credenciais permanentes no GitHub. Vamos cobrir o funcionamento, a configuração passo a passo, exemplos reais (workflows e infraestrutura-as-código) e padrões de segurança para produção.

Assuma que você já conhece GitHub Actions, conceitos básicos de IAM nas nuvens e tem permissão administrativa para criar roles/service accounts e provedores de identidade nas contas/clusters-alvo.

Por que migrar para OIDC

Chaves de acesso estáticas viciam processos: são difíceis de rotacionar, tendem a proliferar e, se vazarem, permitem acesso de longo prazo. OIDC oferece tokens de curto prazo ligados a um workflow e a um repositório específico. Além disso, o GitHub fornece mecanismos de escopo via claims (repo, actor, ref) que você pode exigir como condição de confiança.

Impacto na operação

Implementar OIDC traz mudanças operacionais: menos manutenção de secrets, processo de criação de roles/upstreams documentado, e necessidade de validar auditoria de tokens. Também exige que automações lidem com credenciais efêmeras — por exemplo, não escrever tokens em logs, não persistir credenciais em discos sem criptografia.

Como funciona por baixo dos panos

GitHub Actions expõe um endpoint OIDC que emite tokens de ID para workflows quando a permissão id-token: write é concedida no job. Esse token tem claims com informações do workflow e do repositório. A nuvem de destino deve confiar no emissor token.actions.githubusercontent.com e aceitar os tokens com um conjunto de condições (audience, subject/sub, repo, ref, etc.).

O fluxo básico é: 1) workflow pede id-token; 2) GitHub retorna JWT assinado; 3) provider da nuvem valida assinatura e claims; 4) provider emite credenciais temporárias (ou permite troca por role/service-account). O resultado é um conjunto de credenciais temporárias aplicadas ao ambiente do runner.

Tokens, claims e audiência

O token JWT contém claims como iss (issuer), aud (audience), sub (subject) e repository. Para segurança, crie políticas que verifiquem aud e o sub. Alguns provedores exigem aud específico (por exemplo, sts.amazonaws.com para AWS e accounts.google.com para GCP). Definir corretamente o audience evita tokens emitidos para um target sendo usados em outro.

Diferenças entre provedores

AWS usa IAM OIDC provider + role trust policy com condição sts:ExternalId ou StringEquals para token.actions.githubusercontent.com:sub. GCP usa Workload Identity Federation: cria-se um workload identity pool e um provider, depois mapeia-se para um service account. Azure usa federated credentials ligados a um service principal (application) no Azure AD com uma relação de confiança baseada no issuer do GitHub.

Implementacao passo a passo

A seguir há três blocos práticos: AWS, GCP e Azure. Cada seção traz o que executar no provedor e o workflow do GitHub Actions. Os exemplos são funcionais; adapte nomes e ARNs para seu ambiente.

AWS: criar OIDC provider e role (exemplo Terraform)

O bloco abaixo cria o provedor OIDC e uma role com política de trust limitada ao repositório e ao ambiente. Antes de aplicar, substitua aws_account_id e owner/repo pelos seus valores.

# Este Terraform cria o provedor OIDC e uma role assumível pelo GitHub Actions.
# Aplicação: o runner vai trocar o token OIDC pelo role AWS e obter credenciais temporárias.

resource "aws_iam_openid_connect_provider" "github" {
  url = "https://token.actions.githubusercontent.com"
  client_id_list = ["sts.amazonaws.com"]
  thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
}

resource "aws_iam_role" "github_actions_role" {
  name = "github-actions-deploy-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect = "Allow"
        Principal = {
          Federated = aws_iam_openid_connect_provider.github.arn
        }
        Action = "sts:AssumeRoleWithWebIdentity"
        Condition = {
          StringLike = {
            "token.actions.githubusercontent.com:sub" = "repo:meu-org/minha-app:ref:refs/heads/main"
          }
        }
      }
    ]
  })
}

# Após aplicar, anexe policies com permissões mínimas para deploy (ex: ECR push, ECS update).

Depois de aplicar esse Terraform, a role estará disponível para ser assumida pelos workflows. A condição StringLike limita o assunto (sub) ao repositório e branch, evitando que tokens de outros repositórios assumam a role.

AWS: workflow GitHub Actions

Este workflow solicita o id-token e usa a action oficial configure-aws-credentials para trocar o token pelo role assumido. Altere role-to-assume e aws-region conforme necessário.

# Workflow GitHub Actions para assumir role AWS via OIDC
# Resultado: runner terá credenciais AWS temporárias e poderá executar comandos AWS CLI/Docker push.

name: deploy-aws-oidc
on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v4

      - name: Configure AWS credentials via OIDC
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy-role
          aws-region: us-east-1

      - name: Deploy: push image to ECR and update ECS
        run: |
          aws ecr get-login-password | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-1.amazonaws.com
          docker build -t minha-app:latest .
          docker tag minha-app:latest 123456789012.dkr.ecr.us-east-1.amazonaws.com/minha-app:latest
          docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/minha-app:latest
          aws ecs update-service --cluster minha-cluster --service minha-service --force-new-deployment

Ao rodar, a action aws-actions/configure-aws-credentials solicita o ID token do GitHub e chama STS AssumeRoleWithWebIdentity. O runner recebe variáveis de ambiente AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY e AWS_SESSION_TOKEN válidas por um curto período.

GCP: criar Workload Identity e Service Account (gcloud)

GCP usa Workload Identity Federation. O procedimento abaixo cria um pool e um provider que confia no issuer do GitHub, e adiciona uma binding entre o provider e o service account. Substitua PROJECT_ID, GCP_SA_NAME e o repo conforme necessário.

# Comandos gcloud para criar workload identity provider e vincular ao service account
# Resultado: o workflow poderá trocar o token OIDC por credenciais do service account do GCP.

PROJECT_ID=my-gcp-project
POOL_ID=github-actions-pool
PROVIDER_ID=github-provider
SA_NAME=github-actions-sa

gcloud iam workload-identity-pools create "$POOL_ID" --project="$PROJECT_ID" --location="global" --display-name="GitHub Actions Pool"

gcloud iam workload-identity-pools providers create-oidc "$PROVIDER_ID" \
  --project="$PROJECT_ID" --location="global" --workload-identity-pool="$POOL_ID" \
  --issuer-uri="https://token.actions.githubusercontent.com" \
  --allowed-audiences="api://github" --display-name="GitHub Actions Provider"

gcloud iam service-accounts create "$SA_NAME" --project="$PROJECT_ID" --display-name="GitHub Actions SA"

# Conceder permissão ao provider para impersonar o service account
gcloud iam service-accounts add-iam-policy-binding "$SA_NAME@$PROJECT_ID.iam.gserviceaccount.com" \
  --project="$PROJECT_ID" \
  --role="roles/iam.workloadIdentityUser" \
  --member="principalSet://iam.googleapis.com/projects/$PROJECT_ID/locations/global/workloadIdentityPools/$POOL_ID/attribute.repository/ORG/REPO"

Na prática, você mapeará a claim repository para uma entrada principalSet específica, ou usará uma condição para limitar ao repo e ao branch. Após configurar isso, o workflow GitHub pode autenticar usando google-github-actions/auth.

GCP: workflow GitHub Actions

O action google-github-actions/auth troca o token OIDC por credenciais impersonando o service account. O campo workload_identity_provider deve apontar para o resource completo do provider criado.

# Workflow para autenticar no GCP via OIDC e deployar um container no Cloud Run
name: deploy-gcp-oidc
on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read

    steps:
      - uses: actions/checkout@v4

      - id: 'auth'
        uses: 'google-github-actions/auth@v1'
        with:
          workload_identity_provider: 'projects/1234567890/locations/global/workloadIdentityPools/github-actions-pool/providers/github-provider'
          service_account: 'github-actions-sa@my-gcp-project.iam.gserviceaccount.com'

      - name: Build and deploy Cloud Run
        run: |
          gcloud builds submit --tag gcr.io/$PROJECT_ID/minha-app:latest
          gcloud run deploy minha-app --image gcr.io/$PROJECT_ID/minha-app:latest --region us-central1 --platform managed

O resultado é que o job terá credenciais temporárias para executar comandos gcloud e fazer deploy, sem armazenar chaves no repositório.

Patterns e boas praticas

Ao adotar OIDC no seu pipeline, prefira padrões que aumentem segurança e auditabilidade. Abaixo estão práticas testadas em produção por times de DevOps experientes.

Least privilege e escopo por repo/env

Crie roles/service accounts com permissões mínimas necessárias e restrinja trust policies por repo e branch. Use nomes e tags que identifiquem claramente o propósito da role (ex: deploy-minha-app-prod). Evite roles genéricas que atendam múltiplos projetos.

Separe ambientes e use roles por pipeline

Tenha roles distintos para deploy em staging e production, e force revisões manuais para o job que usa a role de produção (por exemplo, required reviewers no branch protegida ou ambientes do GitHub Actions com proteção manual).

Auditoria e logging

Ative logging das ações de STS/impersonation na nuvem e configure alertas de uso inesperado. Em AWS, CloudTrail deve registrar calls de AssumeRoleWithWebIdentity; em GCP, verifique logs de audit.

Evite persistir credenciais

Nunca escreva tokens ou credenciais temporárias em artefatos persistentes sem criptografia. Se precisar de armazenamento temporário, criptografe com KMS e defina TTL curto.

Use approvações humanas para trocas que envolvam roles de produção e registre a identidade do ator no pipeline.

Armadilhas comuns e como evitar

Apesar de reduzir riscos, OIDC tem armadilhas práticas. Listo as mais frequentes e como resolver rapidamente.

Permissão id-token não concedida

Erro: workflow apresenta falha ao solicitar o token. Causa: job não tem permission id-token: write. Solução: adicione no job a seção permissions com id-token: write. Sem essa permissão, GitHub não retorna o JWT.

Mismatch no subject (sub) ou audience (aud)

Erro: provider recusa o token. Causa: trust policy usa um pattern de sub que não corresponde ao token real, ou audience esperado difere. Solução: valide o JWT em um ambiente local (curl + jwt.io) ou use uma execução de diagnóstico para logar o token (sem expor em logs públicos). Ajuste o condition para usar StringLike e patterns adequados: por exemplo, repo:org/repo:ref:refs/heads/main.

Tokens com claims inesperados

GitHub pode mudar claims se usar forks ou runs em contexts diferentes. Para workflows acionados por PRs de forks em repositórios públicos, o token pode ter menos permissões. Prefira executar jobs sensíveis apenas em branches protegidos ou em runs desencadeados por membros da organização.

Problemas com clocks (time skew)

JWTs são sensíveis a relógio. Se as máquinas de validação tiverem clock muito adiantado/atrasado, a validação de exp (expiration) pode falhar. Garanta sincronização NTP nas instancias que fazem validação customizada e verifique TTL das credenciais temporárias.

Uso indevido em runners auto-hospedados

Runners auto-hospedados aumentam a superfície de ataque: se comprometidos, podem requisitar tokens OIDC. Mitigue com segmentation, runner ephemeral (self-hosted runner em job container que é destruído) e monitoramento das ações dos runners.

Erros práticos e soluções rápidas

Aqui coleto mensagens de erro reais e como tratá-las de forma objetiva.

"AccessDenied" ao usar AssumeRoleWithWebIdentity

Geralmente indica que a trust policy não corresponde ao token. Verifique o ARN do provider no role e se o issuer url e thumbprint correspondem ao token.actions.githubusercontent.com. Valide o claim sub dentro do JWT para confirmar o formato.

GCP: "caller does not have permission to impersonate"

Significa que o binding roles/iam.workloadIdentityUser não foi aplicado corretamente ao service account ou o membro está errado. Use member="principal://iam.googleapis.com/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/subject/repo:ORG/REPO" ou principalSet conforme apropriado.

Conclusao pratica

OIDC com GitHub Actions reduz risco operacional removendo secrets estáticos e substituindo por tokens efêmeros com confiança baseada em claims. As implementações para AWS, GCP e Azure seguem o mesmo princípio: estabelecer um provedor de identidade de confiança e uma política que limite quem pode trocar tokens por credenciais.

Checklist mínimo antes de colocar em produção:

  • Roles/service accounts com permissões estritamente mínimas.
  • Trust policies que validem repo, ref e aud.
  • Workflows com permissions.id-token: write apenas onde necessário.
  • Logs e alertas para autenticações federadas.
  • Ambientes de produção com aprovação manual e revisão de auditoria.

Implementar OIDC é trabalho de infraestrutura e segurança: pare de distribuir chaves, adote tokens curtos e audite o uso. Os exemplos aqui são ponto de partida; adapte naming, policies e bindings para o seu modelo de segurança e automação.

Se quiser, posso gerar snippets ajustados ao seu projeto (ARNs, nomes de serviço, políticas JSON customizadas) com base nos recursos que você já possui.

Assuntos: github-actions, oidc, AWS, GCP, Azure, ci-cd, terraform

Leia também