🧑💻 Храним секреты без менеджеров паролей: реальные примерыЕсли у вас нет Vault или AWS Secrets Manager, это не значит, что секреты можно кидать в
.env и надеяться на лучшее. Есть несколько рабочих способов защититься без сторонних платных инструментов.
Docker SecretsDocker Swarm умеет хранить секреты отдельно от контейнера. Файл не попадает в образ, не светится в
docker inspect, не передаётся через переменные окружения.
Создаём секрет:
echo "my_super_password" | docker secret create db_password -
Используем в
docker-compose.yml:
version: "3.8"
services:
app:
image: myapp:latest
secrets:
- db_password
environment:
DB_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
external: true
Внутри контейнера секрет доступен как файл
/run/secrets/db_password. В коде читаем так:
with open("/run/secrets/db_password") as f:
password = f.read().strip()Если Swarm не нужен и работаете в обычном Compose, секрет можно передать через файл на хосте:
secrets:
db_password:
file: ./secrets/db_password.txt
Файл
./secrets/db_password.txt добавляем в
.gitignore. В репозиторий он не попадает, но и на машине лежит в читаемом виде.
GitHub Actions: repository secretsСекреты хранятся на стороне GitHub, в код не попадают. Добавляем через Settings → Secrets and variables → Actions.
Пример воркфлоу, который использует токен для деплоя:
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to VPS
env:
SSH_KEY: ${{ secrets.VPS_SSH_KEY }}
VPS_HOST: ${{ secrets.VPS_HOST }}
run: |
echo "$SSH_KEY" > /tmp/deploy_key
chmod 600 /tmp/deploy_key
ssh -i /tmp/deploy_key -o StrictHostKeyChecking=no user@$VPS_HOST "cd /app && git pull && systemctl restart app"
Что здесь важно:
${{ secrets.VPS_SSH_KEY }} нигде не выводится в логи — GitHub автоматически маскирует значения. Если случайно напишете
echo ${{ secrets.VPS_SSH_KEY }}, в логах увидите
***.
Для разных окружений используйте энвы:
jobs:
deploy:
environment: production # у этого environment свой набор секретов
runs-on: ubuntu-latest
VPS без managed-сервисов: systemd и переменные окруженияЕсли приложение запускается через systemd, секреты можно передать через
EnvironmentFile. Файл лежит на сервере с ограниченными правами доступа.
Создаём файл с секретами на VPS:
sudo mkdir -p /etc/myapp
sudo nano /etc/myapp/secrets.env
Содержимое файла:
DB_PASSWORD=my_super_password
API_TOKEN=abc123xyz
Ограничиваем доступ:
sudo chmod 600 /etc/myapp/secrets.env
sudo chown root:root /etc/myapp/secrets.env
В юнит-файле systemd подключаем файл:
[Unit]
Description=My App
[Service]
User=appuser
EnvironmentFile=/etc/myapp/secrets.env
ExecStart=/usr/bin/myapp
Restart=always
[Install]
WantedBy=multi-user.target
Приложение получает переменные окружения как обычно. Файл с секретами читает только root, в репозиторий он не попадает никогда.
Дополнительный слой: git-cryptЕсли секреты всё-таки нужно хранить в репозитории (например, конфиги для команды), можно шифровать их прямо в git.
git-crypt шифрует выбранные файлы с помощью GPG-ключа. Все видят зашифрованный blob, расшифровать может только тот, у кого есть ключ.
# Инициализация
git-crypt init
# Добавляем пользователя по GPG-ключу
git-crypt add-gpg-user USER_ID
# Указываем какие файлы шифровать (.gitattributes)
echo "secrets.env filter=git-crypt diff=git-crypt" >> .gitattributes
После этого
secrets.env в репозитории выглядит как бинарный мусор. На машине с ключом обычный текст.
Ни один из этих способов не заменяет полноценный менеджер секретов, но каждый из них закрывает конкретную дыру лучше, чем голый
.env.
📍 Навигация:
Вакансии •
Задачи •
Собесы🐸 Библиотека devops'a#арсенал_инженера