← Назад к вопросам

Как используешь GitLab CI для шифрования переменных

2.2 Middle🔥 182 комментариев
#CI/CD и автоматизация#Безопасность

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

GitLab CI: Шифрование переменных окружения

В GitLab CI/CD существует несколько методов защиты конфиденциальных данных, каждый из которых я использую в зависимости от контекста и требований безопасности. Вот основные подходы, которые применяю в своей практике.

1. Переменные CI/CD (CI/CD Variables)

Базовый и наиболее распространенный способ — использование встроенных переменных в настройках проекта/группы. Они могут быть защищены различными флагами:

  • File variables (для больших данных, например, сертификатов):
    # .gitlab-ci.yml
    deploy:
      script:
        - cat $KUBECONFIG > ~/.kube/config
        - kubectl apply -f manifest.yaml
    
    В UI GitLab переменная `KUBECONFIG` создается с типом **File**. Её значение автоматически сохраняется в файл, путь к которому передается в переменной.

  • Masked variables (скрывают значение в логах):
    # Если переменная API_KEY помечена как Masked, её значение 'secret123' в логах будет показано как [MASKED]
    echo "Using key $API_KEY"
    
    **Важно:** переменную можно помечать как `Masked` только если её значение не содержит специальных символов и соответствует определенным правилам.

  • Protected variables (доступны только для защищенных веток/тегов):
    Настраивается в UI. Такая переменная будет подставляться только в пайплайны, запущенные для защищенных веток (например, `main`, `production`), что предотвращает утечку в пайплайнах feature-веток.

2. Использование HashiCorp Vault с GitLab CI

Для сложных инфраструктур с централизованным управлением секретами интегрирую GitLab с HashiCorp Vault. Это золотой стандарт для управления секретами.

  • Аутентификация через JSON Web Token (JWT):
    GitLab Runner генерирует JWT, который пайплайн использует для получения кратковременного токена доступа к Vault.

```yaml
# .gitlab-ci.yml
vault:
  stage: .pre
  image: vault:latest
  script:
    - |
      export VAULT_TOKEN="$(vault write -field=token auth/jwt/login role=gitlab-deploy jwt=$CI_JOB_JWT)"
      # Теперь можно читать секреты
      export DB_PASSWORD="$(vault kv get -field=password secret/production/db)"
  artifacts:
    reports:
      dotenv: vault.env # Экспорт переменных в последующие джобы
```
  • Использование ID токена (OIDC):
    В новых версиях GitLab (начиная с 14.7) появилась более элегантная интеграция через **ID токены** (OIDC). Это позволяет определять политики доступа в Vault на основе атрибутов проекта/пайплайна.

```yaml
# .gitlab-ci.yml
get_secret:
  id_tokens:
    VAULT_ID_TOKEN:
      aud: https://vault.company.com
  script:
    - |
      export DB_SECRET=$(curl -H "X-Vault-Token: $VAULT_TOKEN" \
        -H "X-Vault-Request: true" \
        $VAULT_ADDR/v1/secret/data/production | jq -r '.data.data.password')
```
    Соответствующая политика в Vault будет привязана к `bound_claims`, например, `project_id` или `ref_protected`.

3. Шифрование файлов с помощью git-crypt или SOPS

Для защиты конфигурационных файлов, которые должны храниться в репозитории (например, helm-values.yaml с паролями), использую инструменты прозрачного шифрования.

  • SOPS (Secrets Operations) с Age/GPG/KMS:
    # .gitlab-ci.yml
    stages:
      - deploy
    before_script:
      - curl -sL https://github.com/mozilla/sops/releases/download/v3.8.1/sops-v3.8.1.linux.amd64 -o /usr/local/bin/sops
      - chmod +x /usr/local/bin/sops
      - echo "$AGE_KEY" > age.key
    deploy:
      script:
        - sops --decrypt --age age.key production-secrets.enc.yaml > secrets.yaml
        - helm upgrade --install -f secrets.yaml my-app ./chart
    
    Здесь `AGE_KEY` (приватный ключ Age) хранится как защищенная переменная GitLab. В репозитории лежит зашифрованный файл `production-secrets.enc.yaml`.

4. Использование внешних сервисов (AWS Secrets Manager, GCP Secret Manager)

В облачных средах часто напрямую интегрируемся с нативными менеджерами секретов.

# .gitlab-ci.yml для AWS
deploy:
  script:
    - |
      SECRET=$(aws secretsmanager get-secret-value --secret-id prod/database --query SecretString --output text)
      export DB_PASSWORD=$(echo $SECRET | jq -r .password)
    - ./deploy.sh

Для аутентификации в AWS используем IAM-роль, присвоенную раннеру, или временные крединшалы через OIDC.

Ключевые принципы и лучшие практики

  • Минимизация привилегий: Токены/ключи, хранящиеся в GitLab Variables, должны иметь минимально необходимые права.
  • Ротация секретов: Все секреты, особенно статические, должны регулярно обновляться. Интеграция с Vault или облачными менеджерами облегчает этот процесс.
  • Аудит: Все операции с секретами (чтение из Vault, расшифровка SOPS) должны логироваться в централизованную систему (например, в сам Vault или CloudTrail).
  • Не хранить секреты в .gitlab-ci.yml: Конфигурационный файл пайплайна — это код, который коммитится. Секреты в нём, даже в закодированном виде, — это угроза безопасности.
  • Использование rules:if для защиты: Критичные этапы пайплайна, работающие с секретами, должны выполняться только в определённых условиях:
    deploy_prod:
      stage: deploy
      script: ./deploy-to-prod.sh
      rules:
        - if: $CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE == "push"
    

Выбор метода зависит от стека технологий и масштаба. Для простых проектов достаточно Protected Masked Variables. Для Kubernetes и сложных инфраструктур комбинация Vault (для динамических секретов) и SOPS (для зашифрованных конфигов) является оптимальным решением, обеспечивающим безопасность, аудиттируемость и удобство разработки.

Как используешь GitLab CI для шифрования переменных | PrepBro