Isso aconteceu de verdade, no trabalho. Tirei nomes de empresa, contas, domínios, repositórios e qualquer detalhe sensível.
01 / CONTEXTO
O pipeline precisava acessar a AWS. A access key não precisava morar nele.
O pipeline precisa publicar imagem, consultar recurso e atualizar coisa na AWS. O jeito mais comum de começar é criar uma access key e guardar como secret no GitHub. Funciona, mas aí existe uma chave que vale para sempre, que alguém precisa distribuir, trocar de tempos em tempos e proteger.
Troquei isso por OIDC. Nenhuma chave fica guardada no GitHub: na hora que o workflow roda, ele prova para a AWS quem é e recebe uma credencial temporária de uma role específica.
PRINCÍPIO DO PROJETOO pipeline prova quem é e recebe só o acesso de que precisa, por pouco tempo.
02 / RISCO
O problema não era só onde guardar a chave. Era até onde ela alcançava.
Uma chave fixa continua valendo fora do pipeline. Se vazar, qualquer um usa. E quando a mesma chave é usada por vários repositórios e ambientes, fica difícil saber qual deles fez cada coisa na AWS.
Persistência
A chave vale até alguém lembrar de revogar ou trocar.
Abrangência
Chave compartilhada vai ganhando permissão até ter mais do que precisa.
Rastreabilidade
Com todo mundo usando a mesma chave, ninguém sabe de onde veio cada ação.
Operação
Trocar e distribuir chave é trabalho que se repete e uma hora falha.
03 / ARQUITETURA
A AWS confia no contexto de quem está rodando.
A cada execução, o GitHub gera um token OIDC assinado dizendo qual é o repositório, a branch e o ambiente. O STS da AWS confere esses dados com a trust policy da role. Se bater, devolve uma credencial temporária para o workflow.
AUTENTICAÇÃOO token diz de onde o workflow está vindo.
AUTORIZAÇÃOA role diz o que esse workflow pode fazer.
EXPIRAÇÃOA credencial expira sozinha depois de pouco tempo.
04 / DECISÕES TÉCNICAS
A segurança está nas condições, não só em usar OIDC.
Trust policy restrita ao repositório e à referência correta
Cada role só aceita os repositórios autorizados, e só na branch ou ambiente certos. Sem isso, qualquer workflow da organização conseguiria assumir a role só por usar o mesmo provedor OIDC.
audience: sts.amazonaws.com
subject:
repository: brown-cloud/lab-test
reference: environment:production
session:
duration: short_livedname: publish-lab-test
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
jobs:
publish:
runs-on: ubuntu-latest
environment: production
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Assume AWS role with OIDC
uses: aws-actions/configure-aws-credentials@v6.2.3
with:
role-to-assume: ${{ vars.AWS_DEPLOY_ROLE }}
aws-region: ${{ vars.AWS_REGION }}
- name: Publish immutable image
run: ./scripts/publish-image.sh lab-test ${{ github.sha }}Roles separadas por ambiente e finalidade
Desenvolvimento, homologação e produção têm roles separadas. E quem só publica imagem não usa a mesma role de quem atualiza o GitOps ou faz uma tarefa administrativa.
Políticas construídas pelo menor privilégio
Cada role ficou só com as ações e os recursos que usa. Nada de permissão genérica: olhei o que o workflow realmente fazia e cortei o resto.
- Acesso só aos recursos da própria aplicação.
- Ler, publicar e operar são permissões separadas.
- Produção só depois da aprovação.
Migração sem fallback permanente para chaves estáticas
Depois que o OIDC funcionou, apaguei os secrets antigos. Deixar a chave guardada "por garantia" seria manter exatamente o risco que eu queria tirar.
05 / EXECUÇÃO
Como fiz a troca, passo a passo.
- 01
Inventário
Listei os pipelines, as chaves existentes, o que cada um fazia na AWS e em quais ambientes.
- 02
Fundação
Configurei o provedor OIDC e criei as roles com trust policy fechada.
- 03
Piloto
Testei com uma aplicação que representava bem as outras, do build até a publicação.
- 04
Expansão
Levei o mesmo padrão para os outros repositórios, com policy própria para cada um.
- 05
Desativação
Apaguei as access keys antigas e confirmei no CloudTrail que dava para ver cada sessão nova.
06 / RESULTADOS
Menos segredo para cuidar, mais controle de quem acessa.
Não medi isso em números que possa publicar, então conto o que mudou.
Credencial temporária só existe quando um workflow autorizado está rodando.
Nada para vazar não tem mais access key guardada no CI/CD.
Ambientes separados cada um com sua role e suas condições.
Dá para rastrear cada sessão e o que ela fez na AWS.
Repositório novo entra fácil é só seguir o mesmo padrão.
07 / APRENDIZADOS
OIDC não é só trocar a credencial. Muda em quem a AWS confia.
O ganho aparece quando você olha junto quem é, de onde vem e o que pode fazer. Configurar o provedor é só o começo. O que faz diferença são as condições da trust policy, as roles separadas e apagar de verdade as chaves antigas.
Bem feito, ainda sobra menos trabalho: ninguém precisa trocar chave, e os times nem chegam a encostar em segredo para fazer deploy.
william@devops:~$ echo $LESSON_LEARNED
"Pipeline seguro não carrega chave. Ele recebe acesso na hora, para aquele contexto, e o acesso expira."