Вот концентрат практик, чтобы ваши токены и ключи не вываливались в логи и чужие форки.
🔐 Где хранить
-
Secrets: шифруются, доступны через secrets.*. Уровни: Repository, Environment, Organization, Dependabot.-
Variables (vars): не для чувствительного — просто конфиг.- Environment + reviewers: ставьте для
production - без апрува шаги с секретами не стартуют.🪪 GITHUB_TOKEN и права
Явно задавайте права минимально необходимые:
permissions:
contents: read
id-token: write # нужно для OIDC
Не полагайтесь на дефолты. Чем меньше - тем лучше.
🔄 OIDC вместо статических ключей
К облакам — без долгоживущих секретов:
jobs:
deploy:
permissions:
id-token: write
contents: read
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: AWS OIDC
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/gha-deploy
aws-region: eu-central-1
- run: aws sts get-caller-identity
Аналогично есть для GCP/Azure. Итог: нулевые постоянные ключи, только краткоживущие токены.
🧪 Секреты и PR из форков
По умолчанию секреты недоступны для
pull_request из форков - и это хорошо.Если нужно выполнить деплой/проверку после мерджа - делайте через
workflow_run или отделяйте джобы:
if: github.event.pull_request.head.repo.fork == false
Избегайте
pull_request_target для запуска непроверенного кода с секретами.🧯 Не печатайте секреты
- Никогда не
echo $SECRET.- Прокидывайте через stdin:
echo "${{ secrets.NPM_TOKEN }}" | npm login --registry=https://registry.npmjs.org --scope=@org --auth-type=legacy --password-stdin
- Для временных значений добавляйте маску:
echo "::add-mask::${TOKEN_FROM_API}"
- Не включайте
set -x/trace в шагах, где работают секреты.🗝️ Секрет как файл
- name: Write SSH key
run: |
install -m 700 -d ~/.ssh
printf '%s' "${{ secrets.DEPLOY_KEY }}" > ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_ed25519
Если это PEM/JSON — храните в секрете как base64 и декодируйте в рантайме.
🧰 Склады секретов
- Централизуйте в Vault/SM (HashiCorp Vault, AWS/GCP/Azure Secrets Manager) + OIDC.
- В GitHub — используйте Org secrets и environment secrets для переиспользования.
🧹 Ротация и доставка
- Автоматизируйте через CLI:
gh secret set NPM_TOKEN --repo owner/repo --body "$TOKEN"
gh secret set PROD_DB_URL --env production --repo owner/repo --body "$URL"
- Добавьте регулярную ротацию токенов и ключей (календарь + скрипт/бот).
🛡️ Secret scanning
Включите Secret scanning и Push Protection для приватных реп - ловит утечки ещё до пуша/мерджа.
🧩 Шаблон безопасного деплоя
name: deploy
on:
push:
branches: [ main ]
jobs:
deploy:
environment: production # защита + секреты проды
permissions:
contents: read
id-token: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login registry
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
- name: Cloud auth (OIDC)
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/gha-deploy
aws-region: eu-central-1
- name: Deploy
run: ./scripts/deploy.sh
Чек-лист на дорожку: минимум прав, OIDC > статические ключи, секреты в
environment, никакого echo, форки изолируем, сканирование включаем, ротацию автоматизируем.Подпишись 👉@devopslib