# SOPS + age: реальные команды и воспроизводимая мастерская

9 задач, 10 записей Windows/Linux. Веб-страница показывает сохранённое выполнение, а не шифрует введённые пользователем секреты. `capture.py` создаёт собственные учебные identity, использует только вымышленные пароли, проверяет результаты и удаляет временные ключи при нормальном завершении.

## Требования и установка Windows x64

Python 3.11+, Node.js 22+, PHP 8.3+, SOPS 3.13.3, age 1.3.2. Бинарные файлы скачайте из официальных релизов:
- https://github.com/getsops/sops/releases/tag/v3.13.3 (`sops-v3.13.3.amd64.exe`)
- https://github.com/FiloSottile/age/releases/tag/v1.3.2 (`age-v1.3.2-windows-amd64.zip`)

Сверьте SHA-256 SOPS с checksums.txt из того же релиза. Совпадение контрольной суммы подтверждает целостность загрузки, но не заменяет проверку подписи поставщика. Закреплённые версии нужны для повторения лаборатории; перед внедрением проверьте актуальные security-релизы.

```powershell
# Пути замените на свои. Установка в системный PATH не обязательна.
$env:SOPS_BIN = 'C:\tools\sops-v3.13.3.amd64.exe'
$env:AGE_KEYGEN_BIN = 'C:\tools\age\age-keygen.exe'
python capture.py
python -m http.server 8543 --bind 127.0.0.1 --directory public
# http://127.0.0.1:8543
```

Скачиваемый ZIP проекта находится рядом с public в опубликованной версии. В локальном исходном проекте основной ZIP не вложен сам в себя: ссылка «Скачать весь проект» актуальна на сайте, остальные функции доступны локально.

## Linux x86_64

Установите официальные `sops` и `age-keygen` в PATH либо передайте абсолютные пути. Для ARM64 выберите ARM64-релизы; Dockerfile лаборатории намеренно рассчитан на amd64.

```bash
SOPS_BIN=/usr/local/bin/sops AGE_KEYGEN_BIN=/usr/local/bin/age-keygen python3 capture.py
python3 -m http.server 8543 --bind 127.0.0.1 --directory public
```

Либо используйте Docker Engine с Compose (на Windows — Docker Desktop в режиме Linux containers):

```bash
docker compose build linux
docker compose run --rm linux
docker compose down
```

Образ загружает закреплённые инструменты при сборке. Сам capture запускается без сети и сохраняет только public/recording-linux.json. В образ не попадает `.runtime`. Создание identity происходит заново при каждом запуске. ciphertext и recipients поэтому будут отличаться.

## Что выполняется

1. Три свежих identity и публичные recipients.
2. JSON: шифрование и полное сравнение после расшифровки.
3. YAML и .env: выбор правила по имени файла.
4. Ожидаемый отказ чужому ключу.
5. Добавление Bob через updatekeys и успешная расшифровка.
6. Удаление Bob, rotate, отказ на новом файле и успешное чтение старой копии.
7. Подмена encrypted-значения между полями, ожидаемый отказ проверки.
8. exec-env: дочерний процесс получает настройку, печатает только boolean.
9. Восстановление отдельным резервным ключом.

Каждая неуспешная обязательная проверка завершает capture ненулевым кодом. Запись сохраняется только после завершения всего набора. Хеши исходников связывают запись с конкретным кодом; это не цифровая подпись автора.

## Использовать в собственном проекте

Создайте identity отдельно от Git. Приватная строка имеет префикс AGE-SECRET-KEY; её нельзя добавлять в репозиторий, статью, логи или скриншот. В `.sops.yaml` положите публичный recipient (начинается с age1). Для разных окружений используйте разные правила и разные ключи.

```yaml
creation_rules:
  - path_regex: '\.json$'
    age: age1REPLACE_WITH_REAL_PUBLIC_RECIPIENT
```

```powershell
$env:SOPS_AGE_KEY_FILE = 'C:\private\my.identity.txt'
# app.json создайте в закрытой папке, вне Git, без настоящих секретов на первом опыте.
sops encrypt --output encrypted-app.json app.json
sops exec-env encrypted-app.json 'node src/app.mjs'
sops exec-env encrypted-app.json 'php src/app.php'
Remove-Item Env:SOPS_AGE_KEY_FILE
```

```bash
export SOPS_AGE_KEY_FILE="$HOME/.config/sops/age/keys.txt"
sops encrypt --output encrypted-app.json app.json
sops exec-env encrypted-app.json 'node src/app.mjs'
sops exec-env encrypted-app.json 'php src/app.php'
unset SOPS_AGE_KEY_FILE
```

Примеры Node/PHP проверяют наличие настройки и печатают только имя demo-пользователя. Они не устанавливают соединение с БД. Рабочий пароль передаётся драйверу вашего приложения; не копируйте его в лог при диагностике.

`sops decrypt` по умолчанию печатает открытые данные. Для записи файла предпочитайте `--output`: это исключает особенности кодировки перенаправления Windows PowerShell. `exec-file --no-fifo` создаёт обычный временный plaintext-файл и убирает его после завершения процесса; это не режим «секрет никогда не был на диске».

## Границы

SOPS защищает сохранённую конфигурацию. После расшифровки приложение имеет доступ к значениям. Окружение процесса доступно достаточно привилегированным пользователям; дампы, отладка, логи и уязвимости приложения остаются отдельными рисками. Ротация ключа данных не меняет API-токен у провайдера и не отзывает старую копию. Для компрометации нужно менять сам секрет и при необходимости identity.

Смотрите LINUX-VPS.md: служебный пользователь, права, systemd, обновление, резервное копирование и восстановление.
