O Pipeline Não Deve Armazenar Segredos: Armazenamento e Entrega Seguros de Segredos para CI/CD com Deckhouse Code e Stronghold

O Pipeline Não Deve Armazenar Segredos: Armazenamento e Entrega Seguros de Segredos para CI/CD com Deckhouse Code e Stronghold

Este artigo explora as práticas de armazenamento de segredos em pipelines CI/CD, comparando diferentes abordagens, desde variáveis GitLab até integrações personalizadas com HashiCorp Vault. Ele destaca os desafios e apresenta uma solução integrada com Deckhouse Code e Stronghold, que simplifica o gerenciamento de segredos e melhora a segurança.

MundiX News·21 de maio de 2026·15 min de leitura·👁 4 views

64K+ Alcance em 30 dias Flant 4,6 Avaliação do empregador 130,39 Classificação 65 960 Assinantes Assinar an_shilov 1 minuto atrás O pipeline não deve armazenar segredos: armazenamento e entrega seguros de segredos para CI/CD com Deckhouse Code e Stronghold Médio 15 min 41 Blog da empresa Flant DevOps * Git * Infraestrutura de TI * Segurança da informação * Olá! Meu nome é Andrey Shilov, sou engenheiro sênior de práticas DevOps na empresa Flant. Trabalhamos com consultoria e ajudamos os clientes a construir sistemas de informação, o que quase sempre significa construir pipelines CI/CD, que devem ser seguros, escaláveis e funcionais. E a palavra-chave aqui é "seguro". E a segurança do pipeline é em grande parte determinada por como os segredos são armazenados nele. No artigo, vamos descobrir como as coisas estão na prática. Primeiro, analisarei as abordagens para armazenar segredos para pipelines e as limitações das Variáveis GitLab CI/CD. Em seguida, mostrarei três casos de integração caseira do GitLab CE com o HashiCorp Vault e as dificuldades que permanecem mesmo com sua implementação cuidadosa. E, no final, configurarei a integração nativa do Deckhouse Code e Deckhouse Stronghold, que resolve os problemas de armazenamento de segredos em pipelines "prontos para uso". Aviso legal: Deckhouse Code e Deckhouse Stronghold são produtos comerciais, você precisa comprar uma licença para usá-los, embora os recursos básicos do Stronghold também estejam disponíveis na plataforma de código aberto Deckhouse Kubernetes Platform Community Edition. No artigo, analiso os problemas das abordagens existentes e mostro como nossos produtos os resolvem. A escolha final da solução, como sempre, é sua. Formas de armazenar segredos para pipelines: do repositório ao armazenamento Em pipelines CI/CD, segredos são necessários em quase todas as etapas. Construir e publicar imagens - você precisa de credenciais para o registro. Implantação no cluster Kubernetes - você precisa de kubeconfig ou um token de conta de serviço. Testes de integração - você precisa de strings de conexão reais para se conectar ao banco de dados. Notificações e APIs externas - tokens Slack, Telegram, Kaiten, S3. Se você estimar grosseiramente, as formas de armazenar segredos para pipelines são construídas de "simples, mas inseguro" para "mais complexo, mas mais confiável". Segredos no repositório junto com o código. Os segredos estão em formato aberto, às vezes encapsulados em Base64, e são colocados em variáveis de ambiente ou arquivo de configuração no lançamento ou implantação. As vantagens são óbvias: muito simples, as alterações são visíveis nos commits. As desvantagens são igualmente óbvias: todos que têm acesso ao repositório têm acesso aos segredos. Isso, é claro, é um antipadrão. Mas na prática, é encontrado com mais frequência do que gostaríamos, por isso é preciso mencioná-lo. Variáveis CI/CD. Os segredos são armazenados em formato criptografado dentro da ferramenta CI/CD, podem ser mascarados, sua visibilidade pode ser filtrada por ramificações e tags. Parece melhor do que a primeira opção. É verdade, há muito mais armadilhas aqui do que parece, como veremos abaixo. Aqui também está uma opção intermediária: os segredos estão no repositório, mas em formato criptografado. É assim que SOPS, helm-secrets e werf funcionam: valores confidenciais são criptografados com uma chave, e a própria chave é passada para o pipeline por meio de variáveis CI/CD (com menos frequência - está em KMS). Você não pode ler o segredo do repositório sem a chave, enquanto o histórico de alterações é salvo no Git. Mas todo o esquema é seguro apenas na medida em que a chave nas Variáveis CI/CD é segura, o que significa que herda todos os seus problemas. Armazenamento de segredos dedicado. Os segredos são armazenados em formato criptografado dentro de uma solução especializada e entregues por vários métodos seguros. Todos os segredos em um só lugar, o gerenciamento do ciclo de vida e o acesso são construídos com base em princípios únicos, a entrega é segura em todas as etapas e não requer a escrita de nenhum mecanismo especial. O padrão da indústria aqui é historicamente o HashiCorp Vault. A principal forma de armazenar segredos para CI/CD são as Variáveis GitLab CI/CD. Por que é assim? De acordo com nossa pesquisa State of DevOps Russia para 2025, a maior parte do mercado russo usa o GitLab como sistema de armazenamento de código (70,2%) e como plataforma para CI/CD (64,5% na pergunta de múltipla escolha). E é precisamente as Variáveis CI/CD que o GitLab posiciona como um local para armazenar segredos. Vamos descobrir por que existem sérios problemas com isso. Por que as Variáveis GitLab CI/CD não são um armazenamento de segredos O GitLab oferece três níveis de armazenamento de variáveis: Nível de instância - as variáveis estão disponíveis em todos os projetos, gerenciadas apenas pelo administrador. Nível de grupo - disponível em todos os projetos do grupo e subgrupos, herdado automaticamente. Nível de projeto - disponível apenas em um projeto específico, gerenciado pelo mantenedor. Cada variável pode ter o tipo Variável ou Arquivo, vários modos de visibilidade (Visível, Mascarado, Mascarado e oculto) e as flags Protegido e Expandir referência de variável. Você pode vincular uma variável a um ambiente específico. Parece funcional. Mas aqui reside um problema arquitetônico fundamental. As Variáveis GitLab CI/CD não separam "quem pode executar o pipeline" e "quem deve conhecer o segredo". O mantenedor pode adicionar printenv ao Job - e todos os segredos estarão nos logs. Mas isso não é tudo. Os segredos estão acessíveis via API do GitLab se houver um token. Todos nós conhecemos o hábito de emitir tokens com o ciclo de vida mais longo possível e os escopos mais amplos possíveis, apenas para não tê-los que reemitir. Não há rotação: um segredo gravado vive por anos sem nenhum alerta. Não há log de auditoria: não está claro quem e quando alterou ou leu o segredo. O proprietário do grupo vê as variáveis de todos os projetos filhos. A propósito, a rotação é uma dor separada. Um segredo é usado em 30 pipelines, espalhados por diferentes grupos, por exemplo, a mesma string de conexão com o banco de dados. Ao girar, você precisa atualizá-lo em cada projeto manualmente. Parte, provavelmente, será esquecida, o que levará, no mínimo, à queda do pipeline, no máximo, a um incidente em algum ambiente. Mas o mais desagradável é que mascarar a variável não salva. Imagine que você deseja dar aos desenvolvedores acesso aos pipelines, mas ocultar deles os segredos de produção. Com as Variáveis CI/CD, isso é arquitetonicamente impossível. Masked var não ajudará, porque qualquer desenvolvedor pode escrever o seguinte: script:

  • echo ${SUPER_SECRET::1} ${SUPER_SECRET:1} O GitLab mascara nos logs apenas as correspondências exatas do valor da variável. Aqui, o segredo é cortado pela substring Bash no primeiro caractere e na cauda - nenhuma das partes corresponde à máscara como um todo, portanto, o valor em formato aberto, separado por um espaço, aparecerá nos logs. Se você não quiser mexer com os logs, pode salvar o segredo em um artefato e baixá-lo pela interface do usuário: script:
  • echo $SUPER_SECRET > secret.txt artifacts: paths:
  • secret.txt # Baixar via UI. O momento com artefatos pode ser fechado pontualmente: por exemplo, através de artifacts:access: 'maintainer', que proíbe o download do artefato para não-mantenedores. Mas isso corta uma forma de vazamento de dezenas: a forma de compromisso não é limitada por nada, exceto pela engenhosidade do invasor. Uma solução mais sistemática pode fornecer o mecanismo de pipelines gerais. A configuração CI é retirada para um repositório separado com acesso somente leitura para desenvolvedores, importada para repositórios de projetos como um todo, e nada pode ser substituído do .gitlab-ci.yml local. Mas em nossa prática de consultoria, essa solução é extremamente rara - ela requer uma cultura de engenharia muito alta. As equipes quase sempre precisam de "botões giratórios": parâmetros, tarefas personalizadas (Jobs), substituições para um projeto específico. É difícil fazer um pipeline comum que cubra todas as necessidades e, ao mesmo tempo, não permita que nada seja alterado localmente. Portanto, a maioria das equipes usa esquemas mais suaves - modelos comuns via include e extends, onde tudo pode ser substituído. O que significa que, na prática, a mesma regra permanece: se um desenvolvedor tiver a capacidade de alterar .gitlab-ci.yml, ele alcançará os valores das variáveis de ambiente. Conceito de solução: o pipeline não armazena o segredo A solução via HashiCorp Vault muda o próprio conceito: o pipeline não armazena o segredo - ele o recebe. Isso é feito via fluxo JWT/OIDC. O esquema funciona da seguinte forma. Toda vez que o pipeline é executado, o GitLab gera automaticamente um token JWT único assinado com sua chave privada. Dentro do token - um amplo conjunto de metadados sobre o contexto de lançamento: projeto, ramificação, ambiente e muito mais, incluindo se a ramificação é protegida. Este token é exclusivo para cada tarefa. O Runner passa o JWT para o endpoint de autenticação do Vault. Nenhuma senha ou token estático é necessário. O Vault baixa a chave pública do GitLab via OIDC Discovery URL, verifica a assinatura e verifica as declarações vinculadas - por exemplo, que a solicitação vem do seu projeto e da ramificação protegida. Se a verificação for bem-sucedida, o Vault retorna um token de acesso temporário com um TTL limitado - exatamente para a duração da tarefa. Com este token, o runner lê o segredo necessário do Vault. Após a conclusão da tarefa, o token é automaticamente revogado, nada é salvo. Um esquema elegante. Mas aqui começam as dificuldades práticas. Três opções de integração caseira do GitLab CE e HashiCorp Vault A maioria de nossos clientes e entrevistados do State of DevOps Russia usam o GitLab na Community Edition e o HashiCorp Vault "baunilha". O problema é que o GitLab CE não tem a palavra-chave secrets:, ela está disponível apenas no Premium/Ultimate. Tudo o que resta é escrever uma integração caseira. No exemplo de três casos reais, vamos analisar como isso se parece na prática. Opção 1: Python hvac + AppRole As credenciais AppRole são armazenadas nas Variáveis GitLab CI/CD - VAULT_ROLE_ID (login da função) e VAULT_SECRET_ID (senha da função). Estas não são referências a segredos, mas credenciais para entrar no Vault. Um leitor atento notará: estes são novamente segredos, que devem estar sujeitos a requisitos de armazenamento seguro. O cliente os armazenou em Variáveis CI do GitLab - o que significa que ele simplesmente adicionou outro "hop" no caminho para a comprometimento. Um script Python via biblioteca hvac autoriza no Vault por AppRole, contorna todas as variáveis com o prefixo V_, lê os valores do Vault para elas e os injeta no ambiente da tarefa:

.gitlab-ci.yml

variables: V_TRIVY_REGISTRY_PASSWORD: projects/project/TRIVY_REGISTRY_PASSWORD script:

  • source <(get-vault-secrets-by-approle)
  • echo $TRIVY_REGISTRY_PASSWORD

Funções-chave do script.

def get_vault_vars(self): for k, v in os.environ.items(): if k.startswith(self.var_prefix): # var_prefix = 'V_' self.vault_vars[k] = v def login_to_vault_using_approle(self): self.client = hvac.Client(namespace=os.environ.get("VAULT_NAMESPACE")) self.client.auth.approle.login( os.environ.get('VAULT_ROLE_ID'), os.environ.get('VAULT_SECRET_ID')) def get_vault_secrets(self): for k, v in self.vault_vars.items(): secret_var_name = re.sub(r'^V_', '', k) vault_path = re.fullmatch( r'^(?P<mount_point>[^/]+)/(?P.+)/(?P[^/]+)$', v ).groupdict() vault_secret = self.client.secrets.kv.v2.read_secret_version( vault_path['path'], 0, vault_path['mount_point']) self.secret_vars[secret_var_name] =
vault_secret['data']['data'][vault_path['key']] for k, v in self.secret_vars.items(): print("export {}=""+k+""".format(k, v)) Opção 2: Script Bash com prefixo vault: Esta opção já usa a autenticação JWT e está conceitualmente mais próxima do que o GitLab EE oferece. A variável com o prefixo vault: contém o caminho para o segredo. before_script contorna o env e substitui os valores do Vault via API: variables: VAULT_ADDR: https://vault.example.com VAULT_ROLE: project_role job_with_secrets: id_tokens: VAULT_ID_TOKEN: aud: vault variables: TRIVY_REGISTRY_PASSWORD: vault:projects/project#TRIVY_REGISTRY_PASSWORD before_script:

  • export VAULT_TOKEN=$(vault write -field=token
    auth/jwt/login role=$VAULT_ROLE jwt=$VAULT_ID_TOKEN)
  • | while IFS='=' read -r name value; do if [[ $value == vault:* ]]; then stripped=${value#vault:} export "$name=$(vault kv get
    -field=${stripped##} ${stripped%%#})" fi done < <(env) script:
  • echo $TRIVY_REGISTRY_PASSWORD

before_script geralmente é retirado para um modelo separado e conectado via extends - para não copiar a "portyanka" em cada tarefa. Na verdade, este é um análogo da palavra-chave secrets: do GitLab EE, mas funcionando no CE. Opção 3: Script Bash na imagem de compilação Esta opção apareceu em um cliente com um modelo de função rígido: ele tem muitos clientes próprios, para cada um dos quais o software é desenvolvido, e cada cliente tem um conjunto de projetos, e cada projeto funciona em vários ambientes. O script é embutido em cada imagem de compilação. A função e o caminho são construídos estritamente de acordo com a máscara CLIENT-PROJECT-ENV - nenhum caminho arbitrário pode ser definido. Basta especificar três parâmetros, e o script sabe para onde ir no Vault: deploy: variables: CI_VAULT_CLIENT: mycompany CI_VAULT_PROJECT: backend CI_ENV: production before_script:

  • source ExportVaultVars script:
  • echo $TRIVY_REGISTRY_PASSWORD

Construindo a função e o caminho.

VAULT_ROLE="$VAULT_CLIENT-${VAULT_PROJECT/./-}-$ENV" # mycompany-backend-production VAULT_PATH="$VAULT_CLIENT/data/$VAULT_PROJECT/$ENV" # mycompany/data/backend/production

Dupla autenticação: JWT em CI, LDAP localmente.

if [[ $CI_JOB_JWT != "" ]]; then VAULT_TOKEN=$(curl -s -X POST "$VAULT_URL/v1/auth/jwt/login"
--data "{"jwt":"$CI_JOB_JWT","role":"$VAULT_ROLE"}" | jq -r .auth.client_token) else VAULT_TOKEN=$(curl -s -X POST "$VAULT_URL/v1/auth/ldap/login/$username"
--data "{"password":"$password"}" | jq -r .auth.client_token) fi

Cleanup

unset VAULT_TOKEN VAULT_ROLE VAULT_PATH VAULT_CLIENT VAULT_PROJECT ENV Uma característica interessante desta opção é que a dupla autenticação é suportada - JWT em CI e LDAP localmente. O desenvolvedor pode executar o script manualmente com os mesmos direitos. Existem três modos de saída: exportar para env, arquivo JSON ou arquivo .env - estas são as formas de salvar os segredos recebidos. Mas este cliente teve um incidente desagradável. A variável CI_JOB_JWT no GitLab foi marcada como obsoleta, e em um ponto, ao atualizar para uma versão principal, ela simplesmente parou de funcionar. Todas as automações e implantações pararam até que uma saída fosse encontrada. Problemas de integração caseira e problemas comuns com o HashiCorp Vault Vamos resumir a integração caseira: Não há palavra-chave secrets: nativa, este recurso está disponível apenas no GitLab Premium/Ultimate. Não há um padrão único: alguém escreve Bash, alguém - Python, alguém arrasta o Vault Agent. Em alguns casos, você precisa configurar políticas para "imprimir" segredos. Cada novo projeto começa do zero. Com qualquer atualização do GitLab ou Vault - o risco de falha completa. Mas a lista de dificuldades não se limita a isso. Existem problemas de qualquer integração com o Vault, e eles são relevantes, independentemente de você ter CE ou Premium no GitLab. Primeiro, printenv dentro do Job funciona com qualquer abordagem - mencionei isso acima. Se o segredo for entregue no env, o processo poderá lê-lo. Esta é uma limitação fundamental da entrega de segredos por meio de variáveis de ambiente. Em segundo lugar, a deriva da configuração do Vault. Funções e políticas são criadas manualmente. Existe o risco de que, em seis meses, ninguém se lembre por que cada função é necessária. Mesmo que sejam criados via Terraform, mais cedo ou mais tarde, o código HCL pode se transformar em uma portyanka ilegível, dentro da qual uma função com acesso curinga pode ser facilmente perdida. Terceiro, a carga operacional. O Vault como um serviço de produção separado requer HA, unseal, rotação de certificados, monitoramento. E, finalmente, o HashiCorp Vault mudou para a licença BUSL 1.1 em 2023 - o uso comercial requer a compra de uma licença. Existe uma alternativa na forma de OpenBao, mas este é um projeto jovem sem suporte empresarial. Além disso, ambos os produtos são difíceis de usar em grandes empresas russas por razões bastante óbvias. Esses problemas podem ser resolvidos escolhendo produtos onde a integração já foi feita para você e não há dificuldades com a compra de licenças. Deckhouse Code + Deckhouse Stronghold: integração nativa para pipelines seguros Vamos conhecer os personagens. Deckhouse Code é uma plataforma totalmente compatível com o GitLab CE e que aprimora seus recursos para armazenar código e CI/CD. E a palavra-chave secrets: está disponível nele. Deckhouse Stronghold é uma solução compatível com Vault para gerenciamento centralizado do ciclo de vida de segredos. O Deckhouse Code pode trabalhar com ele nativamente via fluxo JWT/OIDC. E em mais detalhes? Deckhouse Code é uma solução para desenvolvimento contínuo e gerenciamento do ciclo de vida de software com recursos empresariais. Permite armazenar com segurança o código-fonte e automatizar pipelines CI/CD de qualquer complexidade. É fácil migrar para o Deckhouse Code de qualquer versão do GitLab devido à compatibilidade total. Os principais recursos incluem: criação de regras de revisão de código personalizadas, espelhamento de repositórios de fontes externas e um pipeline CI/CD estável que garante a operação previsível de pipelines, bem como alta disponibilidade e autoescalabilidade. Deckhouse Stronghold é uma solução para gerenciamento centralizado do ciclo de vida de segredos com um certificado FSTEC da Rússia. Ele protege senhas, chaves de API, certificados, chaves SSH, tokens e outros dados confidenciais contra vazamentos, garantindo a entrega segura de segredos aos aplicativos. Não copiamos o HashiCorp Vault, mas repensamos o armazenamento de segredos e criamos um padrão para o mercado russo. Ao mesmo tempo, o Deckhouse Stronghold é totalmente compatível com a API com o HashiCorp Vault - via CLI e via API. Os principais recursos incluem: um mecanismo de namespaces para criar namespaces e delegar direitos, auto unseal sem usar KMS externo, backup automático, replicação KV1/KV2 na arquitetura mestre-escravo, uma interface web conveniente, um módulo secrets-store-integration para entrega segura e automatizada de segredos em aplicativos. E tudo isso - em um único arquivo binário, o que minimiza os vetores de ataque. O Deckhouse Stronghold funciona de acordo com o esquema familiar: o cliente confirma sua identidade, o Stronghold verifica se ele tem acesso ao segredo solicitado e permite a operação de leitura/gravação ou a rejeita. É simples - e todos os seus segredos estão protegidos. A configuração da integração consiste em três etapas no lado do Deckhouse Stronghold e uma configuração mínima no lado do Deckhouse Code. Configurando a integração passo a passo Os comandos abaixo funcionam via CLI vault padrão - Deckhouse Stronghold é compatível com a API com ele. Os mesmos comandos podem ser executados via d8 stronghold - esta é parte do d8, nosso "canivete suíço" para trabalhar com todos os componentes do ecossistema Deckhouse. Por exemplo, em vez de vault write auth/jwt/config, haverá d8 stronghold write auth/jwt/config. Para brevidade, deixarei vault nos exemplos. Etapa 1: habilitar a autenticação JWT no Deckhouse Stronghold O Deckhouse Stronghold aceita tokens de ID via método JWT. O OIDC Discovery URL e o emissor são especificados - este é o URL do seu Deckhouse Code: vault auth enable jwt vault write auth/jwt/config
oidc_discovery_url="https://code.example.com"
bound_issuer="https://code.example.com" Etapa 2: criar uma função com bound_claims bound_claims restringe o acesso - apenas tokens com os valores especificados podem se autenticar. Sem isso, qualquer token CI receberá acesso. vault write auth/jwt/role/gitlab-role - <<EOF { "role_type": "jwt", "user_claim": "sub", "bound_audiences": ["vault"], "bound_claims": { "project_id": "23" }, "policies": ["gitlab-policy"], "ttl": "1h" } EOF Em bound_claims, você pode usar project_id, project_path, ref, ref_protected, environment, namespace_path. Selecione a combinação certa para um cenário específico, por exemplo, permita o acesso apenas de ramificações protegidas de um projeto específico. Etapa 3: escrever uma política ACL A política define caminhos específicos no Deckhouse Stronghold que podem ser acessados. O princípio dos direitos mínimos funciona aqui: apenas leitura para os segredos necessários. vault policy write gitlab-policy - <<EOF path "kv/data/code/vault-demo" { capabilities = ["read"] } EOF Etapa 4. Configuração no lado do Deckhouse Code No CI, você precisa especificar a variável obrigatória VAULT_SERVER_URL (URL do servidor Stronghold). Opcionalmente - VAULT_AUTH_ROLE (nome da função, por padrão, é tomado da configuração de autenticação JWT), VAULT_AUTH_PATH (caminho para o método de autenticação, por padrão jwt) e VAULT_NAMESPACE (para uma hierarquia de vários níveis). Usando em .gitlab-ci.yml: stages:

  • test vault-demo: stage: test image: alpine

1. Solicitamos um token JWT com audience = nosso Vault.

id_tokens: VAULT_ID_TOKEN: aud: https://vault.example.com

2. Declaramos o segredo: caminho@mecanismo.

secrets: DATABASE_PASSWORD: vault: code/vault-demo/DATABASE_PASSWORD@kv token: $VAULT_ID_TOKEN file: false script:

  • echo $DATABASE_PASSWORD Vamos analisar a anatomia do caminho para o segredo na linha code/vault-demo/DATABASE_PASSWORD@kv: code/vault-demo - o caminho para o segredo no Vault; DATABASE_PASSWORD - o nome do campo dentro do segredo; kv - o ponto de montagem do Secret Engine (por padrão, kv-v2). Tudo. Sem before_script com uma portyanka Bash, sem um script Python na imagem. Apenas uma descrição declarativa do segredo necessário e de onde obtê-lo. O que a combinação Deckhouse Code e Deckhouse Stronghold oferece Além da própria integração, esta combinação tem várias propriedades agradáveis que vale a pena mencionar. Um fornecedor - uma área de responsabilidade. Ambos os produtos são desenvolvidos pela Flant. Se houver um problema na interface do Deckhouse Code e Deckhouse Stronghold - este é um tíquete e um engenheiro que irá resolvê-lo. Sem "este não é o nosso problema" entre dois fornecedores. A proteção do próprio pipeline. Um one-liner com mascaramento é um caso especial. Enquanto alguém pode escrever código arbitrário em .gitlab-ci.yml, nenhum armazenamento de segredos salvará de comprometimento. A segurança do pipeline depende do controle sobre a configuração CI - quem e sob quais condições pode alterá-la. No GitLab CE puro, não há tal controle: a aprovação obrigatória do proprietário do arquivo antes da mesclagem é a funcionalidade das edições pagas, Premium e Ultimate. No CE, é possível restringir a mesclagem em uma ramificação protegida apenas por mantenedores ou removendo a configuração CI para um repositório separado via pipelines gerais (que analisamos acima). No Deckhouse Code, essa proteção existe e funciona da mesma forma que no GitLab Premium - via arquivo CODEOWNERS. Ele especifica as pessoas ou grupos responsáveis ​​por .gitlab-ci.yml, e a ramificação na qual a mesclagem está sendo feita é protegida via ramificações protegidas. Depois disso, a solicitação de mesclagem com alterações em .gitlab-ci.yml não pode ser mesclada até que seja aprovada por pelo menos um dos proprietários especificados. O mantenedor do repositório não tem prioridade aqui: se ele não estiver na lista de proprietários .gitlab-ci.yml, sua aprovação não é suficiente. Deckhouse Stronghold e CODEOWNERS fecham diferentes partes da tarefa. O Stronghold é responsável por quem e quando dar o segredo - via autenticação JWT, declarações vinculadas e políticas ACL. CODEOWNERS é responsável por que tipo de código pode aparecer no pipeline que lê este segredo. A dupla proteção é obtida: Deckhouse Stronghold garante quem receberá o segredo, e CODEOWNERS - que nenhum código para comprometê-lo aparecerá no pipeline. O mecanismo CODEOWNERS no Deckhouse Code está incluído na entrega padrão. Modelo de operações unificado no Deckhouse Kubernetes Platform. Se você já usa o DKP, o Deckhouse Code e o Stronghold são conectados como módulos - via ModuleConfig ou d8 CLI. Ambos os módulos são integrados ao monitoramento, registro e políticas de rede da plataforma. Questões regulatórias e legais. "Flant" é um fornecedor russo, o que significa que todos os contratos estarão dentro da lei russa, e a comunicação com o suporte será em russo. Além disso, Deckhouse Code e Deckhouse Stronghold estão incluídos no registro de software russo, e o Stronghold também recebeu recentemente um certificado FSTEC da Rússia. Para empresas que se preocupam com esses pontos, isso remove uma camada separada de questões. Conclusão: comparação de abordagens Vamos comparar quatro abordagens para armazenar segredos para pipelines por critérios-chave. Para completar o quadro, adicionaremos a opção com uma licença comercial do GItLab mencionada no artigo. Critério Variáveis GitLab CI/CD CE GitLab + HashiCorp Vault EE GitLab + HashiCorp Vault Deckhouse Code + Deckhouse Stronghold Nativo secrets: palavra-chave ✗ ✗ ✓ ✓ Tokens de curta duração ✗ ✗ ✓ ✓ Log de auditoria ✗ ✗ ✓ ✓ Ponto único de rotação de segredo ✗ ✗ ✓ ✓ Segredos de produção inacessíveis ao desenvolvedor ✗ ✗ ✓ ✓ Sem riscos de licenciamento ✓ ✓ ✗ ✓ Um fornecedor / suporte técnico — ✗ ✗ ✓ CODEOWNERS: proteção .gitlab-ci.yml ✗ ✗ ✓ ✓ Registro de software russo — ✗ ✗ ✓ Variáveis GitLab CI/CD - não há divisão em "quem executa o pipeline" e "quem conhece o segredo". O mantenedor sempre tem acesso potencial a todas as informações confidenciais. GitLab CE + Vault - o conceito está correto, mas você terá que mexer com a integração sozinho. Com qualquer atualização de uma das soluções, a integração pode quebrar. GitLab EE + Vault - tudo funciona nativamente, mas em caso de problemas, você precisará se comunicar com dois fornecedores de uma vez. Bem, e é importante lembrar da licença BUSL, então você precisa comprar ambos os produtos. Deckhouse Code + Deckhouse Stronghold - integração nativa, um fornecedor, sem riscos de licenciamento. Você pode saber mais sobre nossos produtos em suas páginas - Deckhouse Code, Deckhouse Str

📤 Compartilhar & Baixar