# Секреты и шифрование

← [Раздел](README.md) · [Главная](../README.md)

## Цель

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

## Предварительно

- [IAM и доступ](iam-i-dostup.md)

## Время

**3–4 часа**

---

## Что такое секрет

| Секрет | Не секрет |
|--------|-----------|
| Пароль БД | URL публичного API |
| API key Stripe | Имя bucket (часто) |
| Private TLS key | Публичный сертификат |
| JWT signing key | Алгоритм подписи (HS256) |

**Правило:** если утечка в GitHub — катастрофа → секрет.

---

## Никогда в git

```text
# ПЛОХО — пример, НЕ настоящий ключ
DATABASE_URL=postgres://user:SuperSecret123@db.example.com:5432/app
```

Используйте:

| Среда | Хранение |
|-------|----------|
| Local dev | `.env` в `.gitignore`, `.env.example` без значений |
| CI | Secret variables pipeline |
| K8s prod | Secrets / External Secrets Operator |
| Облако | Vault, AWS Secrets Manager, GCP Secret Manager |

Пример **безопасного** `.env.example`:

```bash
DATABASE_URL=postgres://user:CHANGE_ME@localhost:5432/app
API_KEY=replace-with-your-key
```

---

## Шифрование в пути (in transit)

| Связь | Минимум |
|-------|---------|
| Клиент → API | TLS 1.2+, HTTPS only |
| API → БД | TLS в managed DB |
| API → SaaS | HTTPS, verify certificate |
| Внутри VPC | TLS или private network + политика |

**HSTS** на публичном домене — браузер не даёт downgrade на HTTP.

---

## Шифрование в покое (at rest)

| Данные | Мера |
|--------|------|
| Диск БД / S3 | AES-256 (часто default у провайдера) |
| Бэкапы | Шифрованные, отдельный KMS key |
| Пароли пользователей | Хэш + salt (не шифрование!) |
| PII чувствительные | Field-level encryption при необходимости |

Managed DB «encryption at rest» включайте по политике compliance.

---

## KMS (Key Management Service)

**KMS** хранит мастер-ключи; приложение запрашивает **encrypt/decrypt** без экспорта ключа на диск.

```mermaid
flowchart LR
  App[API] -->|encrypt| KMS[Cloud KMS]
  KMS --> Cipher[ ciphertext в БД ]
  App -->|decrypt| KMS
```

Ротация ключей — по регламенту (90–365 дней).

---

## Управление жизненным циклом секретов

| Этап | Действие |
|------|----------|
| Создание | Генератор, не `password123` |
| Распространение | Vault / sealed secrets |
| Ротация | Новый ключ + grace period |
| Отзыв | При увольнении, утечке |
| Аудит | Кто читал secret |

При утечке в git: **rotate немедленно**, не только удалить из истории.

---

## Секреты в контейнерах

| Плохо | Хорошо |
|-------|--------|
| ENV в Dockerfile | Runtime inject из K8s Secret |
| Секрет в image layer | Init container + Vault agent |
| Логировать DATABASE_URL | Маскировать в логах |

---

## Шифрование vs хэширование паролей

| | Шифрование | Хэш |
|---|------------|-----|
| Обратимо | Да (с ключом) | Нет |
| Для паролей | ✗ | ✓ bcrypt, argon2 |
| Для API key в БД | Иногда envelope encryption | — |

---

## Compliance (введение)

| Требование | Архитектурный след |
|------------|-------------------|
| GDPR | Право на удаление, регион данных |
| PCI DSS | Не хранить CVV; tokenization платежей |
| 152-ФЗ | Локализация ПДн в РФ |

Платежи — делегируйте **SaaS** (hosted fields), не храните карты сами.

---

## Практика

1. Создайте `.env.example` для учебного API (5 переменных, фейковые значения).  
2. Список: что шифруется TLS, что at rest, что хэшируется.  
3. План ротации при «ключ попал в Slack».

---

## Самопроверка

1. Почему пароль хэшируют, а не шифруют?  
2. Где хранить production DATABASE_URL?  
3. Что делать первым делом при утечке API key в публичный репозиторий?

---

## Дальше

→ [Сетевая безопасность](setevaya-bezopasnost.md)
