Как вы шифруете и маскируете ключи в инфраструктуре как код (IaC) и CI/CD?

«Как вы шифруете и маскируете ключи в инфраструктуре как код (IaC) и CI/CD?» — вопрос из категории Безопасность, который задают на 24% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Шифрование и маскировка — ключевые этапы защиты данных в IaC и пайплайнах. Я разделяю эти процессы.

1. Шифрование для IaC (Terraform, Ansible): Использую инструменты, которые шифруют значения прямо в файлах конфигурации, позволяя безопасно хранить их в Git.

  • Mozilla SOPS (Secrets OPerationS): Мой основной инструмент. Он шифрует значения YAML/JSON/ENV файлов, используя бэкенды (KMS, PGP, Age). Ключ управления доступом хранится отдельно от данных.

    Пример .sops.yaml для AWS KMS:

    creation_rules:
      - path_regex: .enc.yaml$
        kms: 'arn:aws:kms:eu-west-1:123456789012:key/abcd1234-5678-90ab-cdef-1234567890ab'
        aws_profile: production

    Шифрование файла:

    sops --encrypt --in-place secrets.enc.yaml

    Использование в Terraform через sops_decrypt_file:

    data "external" "secrets" {
      program = ["sops", "--decrypt", "--output", "/dev/stdout", "${path.module}/secrets.enc.yaml"]
    }
    
    resource "aws_instance" "app" {
      ...
      user_data = base64encode(templatefile("user_data.sh", {
        db_password = data.external.secrets.result["database_password"]
      }))
    }
  • HashiCorp Vault + Terraform Provider: Более безопасная альтернатива. Секреты вообще не попадают в репозиторий. Terraform запрашивает их у Vault во время plan/apply.

    data "vault_generic_secret" "db" {
      path = "secret/data/production/database"
    }
    output "db_password" {
      value     = data.vault_generic_secret.db.data["password"]
      sensitive = true # Маскировка вывода в консоли Terraform
    }

2. Маскировка в CI/CD логах: Это предотвращает случайную утечку секретов, если они будут выведены командой echo или в сообщении об ошибке.

  • В GitLab CI: Достаточно объявить переменную с флагом masked. GitLab автоматически заменит её значение на [MASKED] в логах джобов.
  • В GitHub Actions: Аналогично, при создании секрета в настройках репозитория он автоматически маскируется в логах.
  • В Jenkins: Используются Credentials Binding Plugin, который маскирует значения.

Важное правило: Даже зашифрованные с помощью SOPS файлы не должны содержать мастер-ключи или root-пароли. Для таких супер-секретов используется только Vault или ручная инъекция через CI/CD переменные.