Секреты — .env и переменные окружения
Секреты (API-ключи, пароли БД, JWT-секреты) хранятся вне исходного кода в переменных окружения или секрет-менеджерах и никогда не коммитятся в git.
Зачем нужно
Секрет в git-репозитории — компрометация навсегда: даже после удаления файла история хранит его. Через GitHub ежедневно утекают тысячи секретов в публичных репозиториях. Правильное управление секретами — базовая гигиена любого проекта.
Где используется
- Все приложения: DATABASE_URL, JWT_SECRET, API-ключи
- CI/CD: секреты для деплоя (SSH-ключи, DockerHub credentials)
- Production: AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager
Основной контент
.env для локальной разработки
# .env (НЕ коммитить!)
DATABASE_URL=postgresql://user:pass@localhost:5432/mydb
JWT_SECRET=super-secret-key-min-32-chars-long
STRIPE_SECRET_KEY=sk_test_xxxxx
REDIS_URL=redis://localhost:6379
# .env.example (коммитить — без реальных значений)
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
JWT_SECRET=your-secret-key-here
STRIPE_SECRET_KEY=sk_test_your_key
REDIS_URL=redis://localhost:6379
# .gitignore — обязательно!
.env
.env.local
.env.production
*.pem
*.key
Загрузка в Node.js
// Только для локальной разработки (dotenv)
require('dotenv').config;
// В production env переменные задаются через платформу (Heroku, Vercel, K8s)
const config = {
db: {
url: process.env.DATABASE_URL,
},
jwt: {
secret: process.env.JWT_SECRET,
expiresIn: process.env.JWT_EXPIRES_IN || '7d',
},
};
// Валидация при старте — не запускать с отсутствующими секретами
const required = ['DATABASE_URL', 'JWT_SECRET'];
for (const key of required) {
if (!process.env[key]) {
throw new Error(`Missing required environment variable: ${key}`);
}
}
Production: AWS Secrets Manager
const { SecretsManagerClient, GetSecretValueCommand } = require('@aws-sdk/client-secrets-manager');
async function getSecret(secretName) {
const client = new SecretsManagerClient({ region: 'eu-west-1' });
const response = await client.send(new GetSecretValueCommand({ SecretId: secretName }));
return JSON.parse(response.SecretString);
}
// Загружаем один раз при старте приложения
const secrets = await getSecret('prod/myapp/credentials');
const dbPassword = secrets.DB_PASSWORD;
Обнаружение утечек: TruffleHog / git-secrets
# Проверить текущий репозиторий на предмет утечек
npx trufflehog git file://. --only-verified
# GitHub Actions: автоматическая проверка в CI
- uses: trufflesecurity/trufflehog-actions-scan@main
with:
path: ./
base: ${{ github.event.repository.default_branch }}
Частые ошибки
- Коммит .env файла в git — даже в private репозиторий (доступ у всей команды)
- Хранение секретов в коде в виде констант:
const API_KEY = "sk-abc123" - Одинаковые секреты в dev и production — ротация невозможна без downtime
- Логирование
process.envцеликом при старте — все секреты попадают в логи - Передача секретов через URL-параметры — видны в логах nginx и browser history
Связанные темы
- _MOC Безопасность
- Принцип наименьших привилегий
- Шифрование данных -- основы
- Supply Chain Attacks -- npm