Gerenciando segredos no CI / CD com o AWS Secrets Manager

Francois Falala-Sechet Blocked Desbloquear Seguir Seguindo 12 de janeiro

O gerenciamento de chaves de API, senhas de banco de dados e outras variáveis secretas no CI sempre foi um pouco doloroso e, muitas vezes, uma falha maciça de segurança na maioria das organizações.

Vamos tentar ver como podemos melhorar a situação com o AWS Secrets Manager , esse simples invólucro e seu provedor de CI favorito (no nosso caso, o Gitlab CI – mas ele deve funcionar de forma relativamente semelhante à maioria dos provedores).

Vamos usar o AWS Secrets Manager para ajudar você a proteger seus estágios de CI.

O problema

Por definição, os segredos são … secretos. Mas o CI não deve ser uma caixa preta, acessível por alguns escolhidos, apenas para que você possa proteger seus preciosos segredos! A CI é basicamente a última vez que você toca seu aplicativo antes de ser enviado aos seus clientes ou usuários. Todos os desenvolvedores devem poder inspecionar os logs de versões anteriores e executar construções por conta própria.

Vamos começar afirmando o óbvio:

  • Se você conseguir fazer o que está fazendo sem usar segredos e apenas tornar tudo público, ótimo. Mas as chances são que você não pode.
  • Os segredos são obviamente secretos, mas pelo menos uma pessoa precisará conhecê-los em algum momento, e as pessoas são fracas.
  • Segurança através da obscuridade não é segurança. Ocultar segredos, por exemplo, dentro dos estágios de CI, não é segurança.

Nesse caso, o que é um bom (como em " fácil e eu posso fazer isso sem ter um time caro todo devops ") para lidar com segredos? Vamos considerar sua situação provável.

  • Você pode configurar segredos no painel de configuração do provedor de CI. Isso é ótimo, pois permite que você passe qualquer variável para qualquer projeto com muita facilidade. No entanto, quando você tem centenas de projetos e, possivelmente, algumas variáveis compartilhadas entre projetos, pode se tornar um pouco difícil de gerenciar. Você também precisa configurar o ambiente adequadamente antes da primeira construção, o que significa informar alguém sobre a variável, o que significa introduzir um ponto fraco.

O painel "Variáveis" dentro da configuração de IC do Gitlab para um determinado projeto.

  • Segredos geralmente têm muito poder a eles (caso contrário, não seriam secretos). Geralmente, os estágios de CI precisarão recuperar pacotes privados, executar alguma tarefa privada, acessar um banco de dados privado ou publicar uma nova versão do seu aplicativo que, por fim, possa ficar nas mãos de seus usuários. Se alguém obtiver acesso a um segredo usado no IC, eles geralmente ganham MUITO poder, e não é necessariamente fácil detectá-los imediatamente.
  • Talvez você queira ocultar seus segredos e não disponibilizá-los para seus desenvolvedores. Você pode usar a configuração "protegida" acima e algumas configurações de segurança nas regras de acesso, mas isso não impede completamente que os desenvolvedores registrem o segredo em uma parte oculta do código que passe milagrosamente todas as revisões de código ( você tem revisões de código, certo? ), e aí você tem o seu segredo disponível em texto simples para qualquer pessoa com acesso de leitura aos logs do IC – que deve ser a maioria dos seus desenvolvedores, se você me perguntar.
  • Quão difícil seria substituir todos os seus segredos agora? Digamos que um de seus engenheiros, encarregado de configurar esses ambientes, saia da empresa. Que danos eles podem causar com as chaves que eles conhecem? E se uma senha de banco de dados, usada em alguns projetos diferentes, precisar ser substituída por algum motivo – em quantos lugares ela é usada em todos os seus repositórios? Você realmente quer gastar meio dia atualizando 50 repositórios toda vez que alguém deixa a empresa, ou como uma tarefa rotineira a cada poucas semanas porque sua política diz que você deveria rotacionar todos os segredos regularmente?

Então o que nós podemos fazer?

A única maneira de tornar seus segredos mais seguros (dada a limitação de que você não pode se safar de não ter segredos, E não importa o que você faça para impedi-los, as pessoas poderão acessá-los de uma forma ou de outra em algum momento ) é torná-los mais voláteis. Eles devem ser revogáveis a qualquer momento, sem causar muito dano e sempre que possível.

Você não deve se preocupar com quem sabe sobre o segredo a qualquer momento (porque as pessoas vão descobrir).

A única maneira que você pode praticamente considerar revogar seus segredos frequentemente (e não gastar uma quantidade considerável de tempo manualmente substituindo-os em todos os lugares se você tiver centenas deles) é tê-los gerenciados centralmente.

Você não deve se preocupar em ter que substituir o segredo de vez em quando (porque é uma operação indolor).

A única maneira de garantir que os segredos serão revogados frequentemente é automatizando a rotação deles. O ser humano é preguiçoso, esquece, sai de férias, está ocupado, dorme …

Você não deve se preocupar com isso porque tem coisas melhores para fazer.

Segredos são feitos para serem voláteis.

Eu acho que o problema está na palavra segredo . As pessoas naturalmente pensam que os segredos são efetivamente secretos e dependem deles para permanecerem secretos . A verdade é, segredos não ficam expostas. É uma parte inevitável de seu ciclo de vida: quanto mais tempo um segredo permanece no lugar, maior o risco de que ele seja exposto e, em seguida, o que?

Se toda a sua empresa confia no conceito exclusivo de segredos que permanecem em segredo, sinto muito por você.

Por outro lado, se você se preparar ativamente para os seus segredos a serem expostos em algum momento, e tornar um evento natural de sua aplicação apenas mudar casualmente os segredos de vez em quando sem ter que pensar, então você resolve um problema questão muito grande: paz de espírito. É muito, muito comparável ao conceito de integração contínua: a implantação na produção muitas vezes o torna um absoluto não-evento.

Considere que você é terrível em segurança. Considere qualquer segredo comprometido se ele não for reciclado a cada poucas horas / dias / semanas. Faça da rotação de suas senhas um não evento. É uma operação tão natural quanto possível.

Segredos são um dado volátil, nada mais.

Digite o Gerenciador de Segredos da AWS

O AWS Secrets Manager é um serviço relativamente novo da AWS, que é semelhante a um tipo de API 1, habilitado para nuvem, habilitado para nuvem, com esteróides.

Basicamente, sua senha principal é como sempre com a AWS, suas credenciais da AWS (função de instância, usuário do IAM, etc.), o que lhe dá acesso a configurações de acesso refinadas (quem pode ler / atualizar segredos armazenados no serviço). Eu não vou entrar em como configurar uma conta da AWS ou os conceitos básicos do IAM aqui, existem inúmeros recursos incríveis sobre isso on-line! Vamos considerar que você pode acessar o console da AWS e saber como fazer isso, e já ouviu falar sobre o IAM antes.

As principais características que estamos interessados aqui são:

  • Centralize o gerenciamento de quantos segredos você quiser, sem torná-los diretamente disponíveis para qualquer entidade em particular. Em vez disso, elas devem ser consumidas sob demanda, usando credenciais regulares da AWS e limitando o acesso por meio de regras padrão do IAM. Esse é um ótimo exemplo de separação de responsabilidade por design : use o IAM para ACL, o Gerenciador de Segredos para gerenciamento de segredos seguros e combine ambos sob demanda. Os segredos não devem se importar com quem tem acesso a eles, pois devem ser simplesmente considerados como uma parte de dados e, ao definir ACLs baseadas em grupos ou funções, você pode conceder ou revogar o acesso a quaisquer valores secretos em todos os momentos.
  • Automatize a rotação de segredos quantas vezes quiser com uma função Lambda. Defina uma vez e esqueça. O que isso te compra é que assim que você revoga o acesso ao Secrets Manager para qualquer um (ou qualquer coisa), eles ainda podem acessar os segredos atuais por um tempo, mas assim que esse script de rotação rodar … quem se importa com o segredo?

Ao tornar o acesso a segredos volátil e baseado em identidade , esse serviço resolve vários problemas de segurança para todos os engenheiros da devops que não precisam reinventar a roda para o gerenciamento de segredos (ou colocar em risco a segurança de toda a empresa se não resolverem isso devidamente).

Usando o Gerenciador de Segredos da AWS no CI / CD

Como a configuração do AWS Secrets Manager leva cerca de 5 minutos, a principal complexidade é facilitar a integração deste no seu projeto de CI. Para ajudá-lo com isso, lançamos https://hub.docker.com/r/clevy/awssecrets , uma ferramenta que ajuda a recuperar segredos para usar nas etapas de IC de seus projetos. Se você preferir construir a partir de fonte para algo tão sensível (você deve), você pode encontrá-los aqui: https://github.com/Clevyio/docker-awssecrets

O seguinte é nossa configuração de produção atual:

  • Corredores gitlab particulares em instâncias do EC2 com uma função IAM do GitlabCiInstance anexada. Essas instâncias são executadas em um VPC, o que significa que seu acesso de / para fora é imposto por qualquer regra de segurança que possamos controlar.
  • Uma política do IAM para limitar o acesso de leitura ao Gerenciador de Segredos, anexado ao acesso à função GitlabCiInstance que se parece com algo assim (você pode, é claro, limitar os segredos aos quais ele tem acesso, mas você tem a ideia):
 { 
"Versão": "2012-10-17",
"Declaração": [
{
"Sid": "GitlabCiPolicy",
"Efeito": "Permitir",
"Açao": [
"secretsmanager: GetSecretValue"
]
"Recurso": "*"
}
]
}
  • Alguns segredos armazenados no AWS Secrets Manager com auto-rotação ativada, alguns projetos em nossos repositórios gitlab com CI ativado, etc. 🙂

O seguinte seria semelhante a um arquivo .gitlab-ci.yml típico que define nosso processo de CI, geralmente com uma primeira etapa que se parece com isso:

 secrets: 
stage: secrets
image: clevy/awssecrets
script:
- awssecrets --region eu-west-1 --secret my-secrets > .ci-secrets
artifacts:
# you want to set this to a value high enough to be used in all your stages,
# but low enough that it gets invalidated quickly and needs to be regenerated later
expire_in: 30 min
paths:
# this will be available by default in all the next stages
- .ci-secrets

Algumas coisas a serem observadas aqui: não há necessidade de passar as credenciais da AWS para os segredos do aws: lembre-se de que a instância tem um papel anexado a ela que automaticamente dá acesso ao serviço! Assim, todas as chamadas são autenticadas "automaticamente" e não há risco de vazar credenciais da AWS que possam dar acesso aos seus segredos, pois isso deve ser usado em uma função de instância em um EC2 autorizado, que você não deseja conceder a ninguém .

Isso produzirá um artefato, que é uma palavra chique para qualquer arquivo ou pasta que você decidir passar para estágios posteriores. No nosso caso, nós simplesmente criamos um arquivo .ci-secrets. Este arquivo se parece com isto:

 SOME_SECRET = poepoe 
OTHER_SECRET = tutu
VERY_SECRET = lalala

Como definimos um valor "expire_in", o gitlab removerá automaticamente o artefato após 30 minutos. Se o seu processo de IC levar mais tempo para ser executado, é claro que você pode ajustar essa duração. Com esse recurso você pode controlar o risco de vazar segredos a longo prazo, mas não é tecnicamente uma medida de segurança!

Em seguida, nas etapas a seguir, você pode simplesmente usar o arquivo .ci-secrets que acabou de ser criado:

 release: 
stage: deploy
image: node
before_script:
# export the contents of the secrets file in your environment
- export $(cat .ci-secrets | xargs)
- echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" >> ~/.npmrc
script:
- npm install -q
- npm publish

Este passo efetivamente publica uma imagem em um repositório npm, então este segredo contém um NPM_TOKEN com acesso de gravação a um pacote – bastante sensível!

Pior cenário

Vamos considerar alguns cenários de pior caso plausíveis diretamente sobre seus segredos. (Não vou considerar um cenário como "alguém teve acesso à minha instância do gitlab runner e pode fazer o que quiser por causa da função de instância": esse é um problema de segurança completamente diferente, não vinculado à exposição de segredos e normalmente deve ser cuidado, pelo menos, com regras de acesso VPC e grupo de segurança.)

  1. Alguém da sua organização em quem você confia totalmente obtém acesso total à configuração do IC e de alguma forma consegue gerar todas as suas preciosas variáveis secretas em texto não criptografado nos logs do IC, tornando-as visíveis para qualquer outra pessoa com acesso de leitura. Merda acontece!
    Agora, um de seus funcionários viu isso, foi demitido no dia seguinte, voltou para casa e quer te machucar muito. Como configuramos o AWS Secrets Manager para a rotação automática de nossas chaves todos os dias, quando chegarem em casa, o token já terá sido rotacionado. Eles tentam usar o NPM_TOKEN acima, mas recebem um erro do 403 Forbidden, e seguem em frente com suas vidas.
  2. Alguém de fora da sua organização de alguma forma tem acesso a alguma variável muito secreta e você precisa urgentemente substituí-la em todos os lugares: basta executar a função de rotação uma vez e voltar para a cama, você merece!

Conclusão

Minha opinião sobre isso é que devemos parar de nos preocupar com segredos de uma só vez e apenas torná-los voláteis . É claro que você não deve colocar segredos em texto puro em repositórios públicos. Mas talvez você estivesse bêbado uma noite, tentou fazer algo estúpido às 3 da manhã, esqueceu de atualizar o .gitignore e publicou em texto claro. Você é apenas humano!

O que você acha?

Texto original em inglês.