O que é DevSecOps (usando o Heroku Flow como exemplo)

Inscreva-se em nossa Newsletter!

O que é DevSecOps

Uma visão geral de DevSecOps e como automatizá-lo

Com a proliferação de modelos de desenvolvimento de produtos ágeis, especialistas da indústria de todos os níveis passaram a apreciar o valor de lançamentos incrementais. No entanto, também há uma expectativa de que cada ciclo de lançamento mantenha e melhore a confiabilidade e segurança do produto entregue.

Como desenvolvedor ou engenheiro, o seu desafio é implementar as melhores práticas de segurança sem desacelerar o desenvolvimento ou adiar as datas de lançamento. Este artigo ilustrará várias maneiras de incluir práticas de segurança no seu ciclo de desenvolvimento para evitar problemas críticos mais tarde, e sem desacelerar.

Vou usar o Heroku Flow como um exemplo de fluxo para mostrar como essas práticas de segurança (ou DevSecOps) podem ser integradas à sua prática de CI/CD, embora as práticas possam ser usadas em quase qualquer cenário comum.

O que é DevSecOps?

DevSecOps é a filosofia de integrar as melhores práticas de segurança cedo no processo de desenvolvimento do produto. Com DevSecOps, a segurança não é tratada como um processo isolado ou como um recurso separado, mas sim como uma parte integrante do seu ciclo de desenvolvimento. A automação ajuda a identificar e corrigir problemas de segurança cedo, idealmente antes de mesclar o código da aplicação para o ramo principal do repositório de código.

Alguns exemplos de práticas DevSecOps incluem varreduras de repositórios para vulnerabilidades de segurança, modelagem de ameaças precoce, revisões de design de segurança, análise de código estático e revisões de código.

Entre no Fluxo do Heroku

A Heroku Flow oferece uma solução abrangente de CI/CD para aplicações baseadas na Heroku. Ela une de forma perfeita vários serviços (Heroku Pipelines, Review Apps, Heroku CI e integrações do GitHub) em uma única visão, dando aos engenheiros maior visibilidade para cada lançamento de código – desde uma solicitação de pull até a queda na produção.

Para uma verificação visual, confira este fluxo de trabalho Heroku Flow, desde o commit inicial até a produção.

Como mostra a imagem visual, os testes automatizados serão executados no Heroku CI quando as solicitações de pull são criadas. O Heroku CI é uma ferramenta de integração contínua na nuvem do Heroku; ele pode detectar automaticamente o idioma e executar comandos padrão (por exemplo, npm test) ou pode ser configurado via o arquivo app.json. Os resultados do CI estão disponíveis tanto nos detalhes da solicitação de pull no GitHub quanto na interface do Heroku.

Para um build de CI bem-sucedido, crie uma nova revisão da aplicação e implante-a em um novo ambiente temporário do Heroku usando os Apps de Revisão. O novo link do ambiente está disponível na visão da solicitação de pull do GitHub, permitindo que os engenheiros verifiquem facilmente os resultados do CI ou execute qualquer teste manual imediatamente.

Após mesclar a solicitação de pull, a nova revisão da aplicação está disponível nos ambientes de pré-produção usando os Pipelines do Heroku. Então, a revisão pode ser promovida para a produção.

Embora alguns recursos do fluxo Heroku estejam incluídos em uma conta gratuita (especificamente pipelines e aplicativos de revisão), alguns recursos têm custo (Heroku CI).

Como Automatizar o DevSecOps com o Heroku Flow

Como uma solução abrangente de CI/CD integrada ao GitHub, o Heroku Flow oferece várias maneiras de automatizar suas práticas de DevSecOps. Vamos explorar três exemplos comuns abaixo:

  1. Atualizar as dependências com vulnerabilidades de segurança de forma segura
  2. Identificar bugs de segurança cedo
  3. Prevenir componentes ou bibliotecas não autorizadas

Atualize as dependências com segurança com vulnerabilidades de segurança.

Você provavelmente já sabe que deve atualizar as dependências com vulnerabilidades conhecidas. Pode ser bastante demorado identificar e atualizar essas dependências. Felizmente, você pode automatizar a maioria deste trabalho.

O GitHub fornece um scanner de vulnerabilidade de dependência, também conhecido como Dependabot, que pode ser habilitado por repositório nas configurações de segurança do GitHub. Por padrão, ele adicionará avisos à interface do GitHub quando identificar uma dependência com uma vulnerabilidade conhecida.

Embora seja uma funcionalidade útil, ainda é necessário verificar os avisos e criar manualmente solicitações de pull para atualizar as dependências afetadas e criar uma versão corrigida. Felizmente, há um recurso beta no Dependabot que cria automaticamente solicitações de pull para corrigir vulnerabilidades conhecidas.

Para habilitar esse recurso, basta adicionar um arquivo .github/dependabot.yml ao seu repositório:

# Basic dependabot.yml file for JavaScript application 
# check docs for other dependencies
version: 2

updates:
  - package-ecosystem: "npm"
    directory: "/"
    schedule:
      interval: "daily"

Dependabot criará solicitações de pull com as correções sugeridas, adicionando os proprietários de código do GitHub como revisores padrão. A documentação do Dependabot cobre todas as opções disponíveis.

image 343

Pull request criado pelo Dependabot para endereçar uma vulnerabilidade conhecida.

Enquanto o pull request irá atualizar a versão da biblioteca afetada, ainda é importante verificar se o aplicativo funcionará como esperado após a atualização.

O pull request levantado pelo Dependabot executará testes de CI e será implantado em um novo ambiente Heroku. Ambos os versões são acessíveis a partir da interface do GitHub.

image 344

Visualização de solicitação de extração de verificação no GitHub

Após mesclar o pull request, a pipeline executará testes de CI e implantará em ambientes de pré-produção. Então, pode ser promovido para produção.

image 345

Visão da Pipeline do Heroku.

Configurar o Dependabot e o Heroku Flow automatizará a maioria do trabalho manual necessário para endereçar vulnerabilidades de segurança em bibliotecas e dependências.

Identifique bugs de segurança cedo

Naturalmente, o momento ideal para pegar bugs de segurança é antes de implantar na produção. Muitas ferramentas diferentes podem executar análise de código estático e identificar código problemático antes de mesclar o código para o ramo principal.

Como exemplo, vamos considerar uma aplicação Node.js simples. Os desenvolvedores comumente usam o ESlint para impor estilos de codificação consistentes e para pegar problemas comuns. Habilitar o ESlint-plugin-security também identificará bugs de segurança comuns:

.eslintrc

...
"plugins": [
  "security"
],
"extends": [
  "plugin:security/recommended"
]
...

Para garantir que o Eslint execute durante o CI, o arquivo app.json é editável e aponta para um arquivo no repositório.

app.json

{
  "environments": {
      "test": {
        "scripts": {
           "test": "bash ./ci.sh"
      }
    }
  }
}

Neste arquivo de script personalizado, você pode executar qualquer comando desejado:

ci.sh

#!/bin/bash
set -eux
#### Running unit tests
npm test
#### Searching for security problems 
npm run lint

Se a limpeza falhar, a compilação será marcada como não bem-sucedida e o deploy não continuará.

image 346

Enquanto o ESlint-plugin-security é específico para JavaScript, a maioria das linguagens maduras possui ferramentas de análise de código estático, como o popular Brakeman para Ruby ou Find-Sec-Bugs para Java.

Embora os trechos CI neste artigo tenham sido mostrados em scripts bash, o Heroku CI suporta várias linguagens.

Prevenir Componentes ou Bibliotecas Não Autorizados

Algumas organizações enfatizam fortemente o controle da complexidade do desenvolvimento de aplicativos e a implementação de controles centralizados para todos os aplicativos. Por exemplo, esses controles podem impedir o uso do complemento Redis ou de uma biblioteca JavaScript específica.

Todos os componentes Heroku para um aplicativo são definidos no arquivo app.json como código. Isso abre a possibilidade de verificações pré-desenvolvimento. Os engenheiros de infraestrutura podem criar um script centralizado para impedir o desenvolvimento de componentes específicos e garantir que todos os aplicativos passem nas mesmas verificações.

Por exemplo, considere o script centralizado infrastructure-checks.sh mostrado abaixo. Ele está atualmente disponível em um repositório git público “mygithubaccount/infrastructure-scripts”. Para este tutorial, digamos que seu objetivo é impedir o desenvolvimento de todos os complementos Heroku.

infrastructure-scripts.sh

#!/bin/bash
set -eux
ADDONS=$(cat app.json | jq '.addons')
# Prevents all addons
if [[ "$ADDONS" != "null" ]]; then
  echo "Add-ons are not allowed"
  exit 1
fi

Dentro do script de infraestrutura, você pode adicionar qualquer número desejado de verificações para excluir addons específicos, verificar variáveis de ambiente, impedir que certos tipos de instâncias sejam criadas e até mesmo verificar bibliotecas específicas que não devem ser usadas. Em suma, você pode fazer qualquer coisa necessária para manter a consistência de todos os ambientes. Para cada aplicativo Heroku, o CI pode ser configurado para baixar e executar o infrastructure-scripts.sh do repositório centralizado:

app.json

{
  "environments": {
    "test": {
      "scripts": {
        "test": "bash ./ci.sh"
      }
    }
  }
}

ci.sh

#!/bin/bash
set -eux
INFRA_SCRIPTS_REPOSITORY="mygithubaccount/infrastructure-scripts"
wget https://raw.githubusercontent.com/${INFRA_SCRIPTS_REPOSITORY}/master/infrastructure-checks.sh
bash ./infrastructure-checks.sh
# Add as well all commands to run all other tests 

O repositório de infraestrutura central também pode ser privado, mas a autenticação será necessária ao baixar o arquivo de script.

Conclusão

Esperançosamente, você agora viu alguns exemplos práticos de implementação de controles de segurança como parte de seu pipeline CI / CD usando o Heroku Flow. Você também deve ser capaz de implementar controles semelhantes em outras soluções CI / CD, mas essas podem não ter integração apertada com o GitHub e o Heroku.

Cada vez mais organizações estão percebendo que a segurança não deve ser um pensamento posterior, mas sim parte de um processo de melhoria contínua. A implementação de controles e correções de segurança de forma codificada de maneira minimamente intrusiva ajudará você a entregar código de forma confiável e segura, sem reduzir a velocidade de entrega. Isso também garante que os clientes ou usuários finais estejam amplamente protegidos de possíveis violações de segurança.

Como parte do DevSecOps, a automação também significa que a detecção de vulnerabilidades de segurança não é um processo reativo em que scanners e processos de auditoria encontram falhas de segurança em sistemas ao vivo, mas sim uma abordagem proativa.

Gostou do artigo?

Facebook
LinkedIn
Pinterest
WhatsApp
Picture of Amanda Braga

Amanda Braga