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

Как GitHub Actions получает доступ к секретным ключам

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

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

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

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

Отличный вопрос! Это ключевой момент при работе с любым CI/CD, включая GitHub Actions. Механизм доступа к секретам (Secrets) в GitHub Actions построен на принципах безопасности и изоляции. Давайте разберем его детально.

Архитектура и принцип работы GitHub Secrets

GitHub Actions не «получает доступ» к секретам в традиционном смысле файлов в переменных окружения. Вместо этого используется система безопасной передачи, где секреты никогда не появляются в логах в открытом виде и не передаются напрямую в среду выполнения (runner).

1. Хранение секретов: GitHub-сторона

  • Секреты хранятся не в вашем репозитории, а в зашифрованном виде в базе данных GitHub, связанной либо с репозиторием (Settings > Secrets and variables > Actions), организацией, либо с окружением (Environment).
  • Для шифрования используется симметричный шифр (libsodium). Ключи шифрования уникальны для каждого репозитория/организации и управляются инфраструктурой GitHub. Секреты шифруются перед сохранением и расшифровываются только в момент подготовки к передаче в Runner.
  • GitHub строго ограничивает доступ: секреты уровня репозитория могут использовать любые workflow этого репозитория. Секреты уровня окружения могут быть дополнительно защищены правилами утверждения (Environment protection rules).

2. Передача секретов в Runner: безопасный канал

Когда workflow запускается, система GitHub Actions подготавливает среду выполнения:

  1. Планирование задания: GitHub Actions определяет, какой Runner (GitHub-hosted или self-hosted) будет выполнять задание (job).
  2. Подготовка секретов: Для этого конкретного запуска (run) система извлекает и расшифровывает только те секреты, которые явно запрошены в данном job (через secrets контекст или env).
  3. Создание безопасного канала: GitHub устанавливает зашифрованное соединение с Runner'ом (используя TLS). Все коммуникации между серверами GitHub и Runner'ом шифруются.
  4. Передача по требованию: Секреты передаются в Runner не сразу все скопом, а по мере необходимости для каждого шага (step). Они передаются как зашифрованные временные переменные, которые Runner получает только для текущего шага.

3. Использование секретов внутри Runner'а

Вот как это выглядит на практике в файле workflow (.github/workflows/deploy.yml):

name: Deploy App
on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production # Указываем защищенное окружение
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          # Секреты передаются как входные параметры действия
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      - name: Deploy to S3
        run: |
          # Секреты доступны как переменные окружения в процессе выполнения шага
          echo "Deploying using key ID ending in...${AWS_ACCESS_KEY_ID: -4}"
          # ВАЖНО: GitHub автоматически скрывает секреты в логах
          aws s3 sync ./dist s3://my-bucket
        env:
          # Также можно явно маппить секрет в переменную окружения шага
          CUSTOM_SECRET: ${{ secrets.MY_API_TOKEN }}

Критически важные механизмы безопасности на стороне Runner'а:

  • Маскирование логов (log masking): Перед выполнением шага, система GitHub Actions сканирует его содержимое. Если она обнаруживает значение, совпадающее с переданным секретом, она автоматически заменяет его на *** в выводе логов. Это предотвращает случайную утечку.
  • Ограниченное время жизни: Секреты существуют только в памяти процесса Runner'а на время выполнения шага. Они никогда не записываются на диск Runner'а (за исключением возможных дампов памяти или свопа, что является общеинфраструктурным риском).
  • Изоляция между шагами: Каждый шаг выполняется в своем процессе. Секреты, определенные для одного шага, не доступны другому, если они не переданы явно через env или выходные данные (outputs).

Особые сценарии и рекомендации

  • Self-hosted Runners: Если вы используете собственные Runner'ы, вы несете ответственность за их безопасность. Секреты будут переданы на вашу машину. GitHub рекомендует использовать их только в доверенных, изолированных сетях, так как любой процесс на этой машине потенциально может получить доступ к памяти Runner'а.
  • Предотвращение непреднамеренного раскрытия:
    - name: Небезопасный шаг (НИКОГДА ТАК НЕ ДЕЛАЙТЕ)
      run: |
        # Секрет будет раскрыт в логах!
        echo "My token is ${{ secrets.TOKEN }}"
        # Секрет может попасть в историю команд bash
        curl -H "Authorization: Bearer ${{ secrets.TOKEN }}" https://api.example.com
    
    - name: Безопасный шаг
      run: |
        # Правильно: передавать через переменные окружения
        curl -H "Authorization: Bearer $TOKEN" https://api.example.com
      env:
        TOKEN: ${{ secrets.TOKEN }}
    
  • Action'ы сторонних разработчиков: Будьте осторожны! Action, которому вы передаете секрет (with:), получает к нему доступ. Используйте только проверенные Actions из официального Marketplace или собственной разработки.

Итог: GitHub Actions получает доступ к секретным ключам через безопасный, зашифрованный и изолированный канал передачи «just-in-time». Секреты расшифровываются на серверах GitHub и передаются в Runner только для конкретного шага, где они маскируются в логах и очищаются из памяти после выполнения. Эта многоуровневая модель минимизирует окно уязвимости и является отраслевым стандартом для систем CI/CD.