Vault + GitHub Actions (OIDC): secrets dinâmicos e melhores práticas
Por John Pires · 20 de março de 2026

Vault + GitHub Actions (OIDC): secrets dinâmicos e melhores práticas
1) Motivacao e trade-offs
Por que usar OIDC com Vault
O objetivo é eliminar credenciais estáticas armazenadas no repositório ou em secrets do GitHub. Em vez disso, o pipeline solicita um token OIDC curto (fornecido pelo runtime do GitHub Actions) e faz login no Vault para obter credenciais dinâmicas — por exemplo, chaves IAM temporárias ou segredos de banco com TTL reduzido. Isso reduz blast radius e automatiza rotação.
O foco aqui é praticidade: mostro como configurar o Vault para aceitar o token OIDC do GitHub, como criar políticas mínimas, e como o workflow consome o secret temporário para operações reais como deploy de imagem Docker. Exemplos são comandos CLI do Vault, payloads JSON e workflows do GitHub Actions.
Trade-offs e limites
Usar OIDC com Vault tem vantagens claras, mas também restrições. Você depende da disponibilidade do provedor OIDC (GitHub), e do relógio das máquinas (time skew). A configuração de roles no Vault precisa ser exata: bound_claims ou bound_subject mal configurados resultam em falhas de autenticação.
Além disso, Vault continua sendo um ponto crítico: políticas muito liberais ou endpoints expostos aumentam risco. Por isso mostro padrões de least-privilege e checagens práticas para reduzir risco operacional.
2) Fundamentos tecnicos
Como funciona o fluxo
Resumo do fluxo mínimo que vamos implementar nas demonstrações:
- Workflow GitHub com permission id-token: write solicita um token OIDC para o runner.
- Workflow pega o token OIDC (via ACTIONS_ID_TOKEN_REQUEST_URL) e faz login no Vault usando o auth method jwt/oidc.
- Vault valida claims (repository, ref, audience) contra uma role configurada e retorna um client_token com políticas específicas.
- Workflow usa o client_token para ler segredos dinâmicos (ex: aws/creds/) e executa deploy.
O ponto crítico: o bound_claims / bound_subject na role do Vault devem corresponder ao payload do token OIDC emitido pelo GitHub. Sem isso, o Vault nega o login.
Configurações do Vault
Vamos habilitar o auth method JWT (ou OIDC dependendo da versão) e criar uma role que permita apenas um repositório e um branch.
Exemplo: habilitar o auth/jwt e criar uma role chamada github-actions. Os comandos abaixo funcionam com a CLI do Vault (supondo VAULT_ADDR e VAULT_TOKEN configurados).
vault auth enable jwt
vault write auth/jwt/config oidc_discovery_url="https://token.actions.githubusercontent.com" \
oidc_client_id="api"
O que faz: habilita o auth method jwt e aponta discovery para o endpoint de OIDC do GitHub. O client_id/audience deve bater com o pedido do runner (audience que vamos solicitar no token).
Agora criamos a role. Esse exemplo limita o login ao repositório myorg/myrepo no branch main:
vault write auth/jwt/role/github-actions \
role_type="jwt" \
bound_claims='{"repository":"myorg/myrepo","ref":"refs/heads/main"}' \
user_claim="sub" \
policies="github-runner" \
ttl="1h"
O que acontece: se o token OIDC conter as claims repository e ref correspondentes, Vault emitirá um client_token com a policy github-runner.
Policy exemplo (minimal):
{
"path": {
"aws/creds/github-deployer": { "capabilities": ["read"] },
"secret/data/company/*": { "capabilities": ["read"] }
}
}
Coloque isso em uma policy chamada github-runner. Ela dá acesso apenas ao endpoint AWS credenciado usado no exemplo avançado e a um prefixo de segredos.
3) Exemplo 1: caso simples
Objetivo
Caso simples: o workflow precisa obter um secret estático do Vault (por ex. chave API curta) e executar um teste de integração. O segredo é lido via OIDC-login no Vault. Aqui mostramos o login via curl (sem actions externos) para deixar tudo transparente.
Workflow e comandos
Contexto: o repositório é myorg/myrepo e o role no Vault foi configurado conforme seção anterior. A workflow pede id-token com audience "vault". Primeiro pedimos token OIDC ao GitHub e depois trocamos por client_token no Vault.
name: ci-oidc-vault
on: [push]
permissions:
id-token: write
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Request OIDC token
id: id-token
run: |
TOKEN=$(curl -s "${ACTIONS_ID_TOKEN_REQUEST_URL}&audience=vault" -H "Authorization: Bearer ${ACTIONS_ID_TOKEN_REQUEST_TOKEN}")
echo "::set-output name=token::$TOKEN"
- name: Vault login using OIDC token
id: vault-login
env:
VAULT_ADDR: https://vault.example
run: |
JWT=${{ steps.id-token.outputs.token }}
LOGIN_RESP=$(curl -s --request POST "${VAULT_ADDR}/v1/auth/jwt/login" -d '{"role":"github-actions","jwt":"'Assuntos: DevOps, Git
Leia também
Acelerando builds Docker em CI usando cache BuildKit (export/import) no GitHub Actions
Reduza drasticamente tempo de builds Docker no GitHub Actions usando BuildKit cache export/import. Veja exemplos reais de Dockerfile, workflows, erros comuns…
Ambientes de preview em PRs com GitHub Actions e Docker Compose — passo a passo
Aprenda a criar ambientes de preview para PRs usando GitHub Actions e Docker Compose. Mostro o jeito errado e o certo, com exemplos reais, scripts de saúde e…
Canary deploy com GitHub Actions e Docker: métricas, rollout e rollback automático
Pipeline prático de canary deploy com GitHub Actions, Docker e Kubernetes: exemplos funcionais de Dockerfile, manifests Nginx-canary, workflow e script de…
Escanear imagens Docker no CI com Trivy e GitHub Actions — falhe por CVSS
Aprenda a escanear imagens Docker no CI com Trivy e GitHub Actions e a fazer o pipeline falhar quando uma vulnerabilidade atingir um limiar CVSS. Passo a…
Canary deploy com GitHub Actions em Kubernetes usando Helm e Flagger
Guia prático para implementar canary deploy com GitHub Actions, Helm e Flagger: padrões de pipeline, exemplos de Canary CRD e AnalysisTemplate, integrações…
GitHub Actions: build, testar em container e publicar imagem no GHCR
Pipeline prática: build de imagem Docker, executar testes no container carregado e publicar no GHCR usando GitHub Actions. Código e workflow para iniciar e…