Секреты и безопасность

Введение

В предыдущей лабораторной работе наш робот-помощник автоматически вошел в систему на складе. Но откуда он узнал пароль?

В реальной автоматизации рабочим процессам часто нужны конфиденциальные данные: ключи API, пароли или токены. Никогда не прописывайте такие значения непосредственно в файлах репозитория.

GitHub предоставляет Secrets — защищенное хранилище конфиденциальных значений, которые используют рабочие процессы. Это основополагающая практика безопасности CI/CD, поскольку конвейерам часто требуется доступ с повышенными привилегиями.

Это одна из важнейших границ безопасности автоматизации. Конвейерам нужны учетные данные, но их следует передавать во время выполнения из защищенного хранилища, а не сохранять в системе контроля версий.

В этой лабораторной работе вы:

  • создадите секретный пароль в хранилище;
  • научите робота получать этот пароль;
  • убедитесь, что даже при попытке вывести пароль робот не сможет показать его в GitHub.

Предварительные требования

Мы продолжим использовать репозиторий github-actions-basics.

Создание секрета

Представим, что приложению нужно подключаться к базе данных. Пароль базы данных необходимо сохранить безопасно.

Мы создадим секрет с именем DB_PASSWORD.

  1. Откройте репозиторий github-actions-basics на GitHub.
  2. Перейдите на вкладку Settings.
  3. В левой боковой панели найдите пункт Secrets and variables и нажмите его, чтобы развернуть меню.
  4. Выберите Actions.
  5. Нажмите зеленую кнопку New repository secret.

New repository secret

Откроется простая форма:

  • Name: введите DB_PASSWORD. (Имена секретов обычно записывают ПРОПИСНЫМИ БУКВАМИ.)
  • Secret: введите SuperSafePassword123!.

Нажмите Add secret.

Теперь в списке должен появиться DB_PASSWORD. Обратите внимание: значение секрета больше нельзя просмотреть. После сохранения секрет навсегда скрыт. Вы можете изменить или удалить его, но ни вы, ни кто-либо другой больше не сможете увидеть его текущее значение.

Использование секрета

Теперь, когда пароль находится в защищенном хранилище, создадим рабочий процесс, который будет его использовать.

Здесь применяется важный принцип косвенного доступа: рабочий процесс обращается к секрету по имени, а GitHub безопасно подставляет его значение во время выполнения.

В файле рабочего процесса любой секрет можно получить с помощью синтаксиса ${{ secrets.YOUR_SECRET_NAME }}.

Перейдите в каталог проекта.

cd ~/project
git clone https://github.com/your-username/github-actions-basics.git
cd github-actions-basics

Примечание: замените your-username своим фактическим именем пользователя GitHub.

Создайте новый файл рабочего процесса security-test.yml в каталоге .github/workflows.

touch .github/workflows/security-test.yml

Откройте его в редакторе nano.

nano .github/workflows/security-test.yml

Добавьте следующее содержимое:

name: Security Test

on: [push]

jobs:
  test-secret:
    runs-on: ubuntu-latest
    steps:
      - name: Try to print secret
        env:
          MY_PASSWORD: ${{ secrets.DB_PASSWORD }}
        run: echo "The password is $MY_PASSWORD"

Здесь происходит кое-что интересное. Мы передаем секрет из хранилища GitHub в переменную окружения с именем MY_PASSWORD. Затем пытаемся вывести ее с помощью echo.

Подождите! Разве вывод пароля в журнал не является ужасной идеей? Да, является! Но мы делаем это, чтобы продемонстрировать важную функцию безопасности GitHub Actions.

Сохраните файл и выйдите из nano.

Проверка маскирования

Запустим этот рабочий процесс и посмотрим, что произойдет при попытке раскрыть секрет.

Зафиксируйте изменения и отправьте их в удаленный репозиторий.

git add .
git commit -m "Test secret masking"
git push

Откройте раздел Actions своего репозитория на GitHub.

  1. Нажмите на запуск рабочего процесса «Security Test».
  2. Нажмите на задание test-secret.
  3. Разверните шаг «Try to print secret».

Посмотрите на вывод. Вы должны увидеть примерно следующее:

The password is ***

Secret masked

GitHub Actions автоматически распознал, что значение $MY_PASSWORD получено из секрета. Перед выводом данных в журнал GitHub ищет это конфиденциальное значение и заменяет его на ***.

Маскирование уменьшает последствия случайного раскрытия данных в журналах, но все равно лучше вообще не выводить секреты. Функции безопасности — это страховочная сетка, а не оправдание небрежного обращения с конфиденциальными данными.

Эта функция «Masking» защищает вас. Даже если вы случайно попытаетесь вывести секрет или используемый инструмент окажется слишком подробным, GitHub обнаружит секрет и удалит конфиденциальные данные из журналов.

Примечание о GITHUB_TOKEN: помните ${{ secrets.GITHUB_TOKEN }}, который мы использовали в предыдущей лабораторной работе? Он работает точно так же. Это секрет, который GitHub автоматически создает для каждого запуска, и его значение также маскируется в журналах.

Итоги

В этой лабораторной работе вы изучили основные принципы безопасности автоматизации.

  • Хранилище: вы использовали GitHub Secrets для хранения конфиденциальных данных, например паролей.
  • Доступ: вы использовали ${{ secrets.NAME }}, чтобы предоставить роботу доступ по ключ-карте к этим данным.
  • Маскирование: вы убедились, что GitHub автоматически скрывает секреты в журналах (***), предотвращая случайную утечку.

Теперь у вас есть безопасный автоматизированный конвейер. В последней лабораторной работе мы рассмотрим главную цель DevOps — непрерывное развертывание. Мы научимся поручать роботу развертывать ваш код на работающем сервере!