Files
nixos/.agent/decisions/0001-sops-secrets-paths.md
T
oqyude 16644fcc0b metaagent: install v3.0.0, migrate docs/arch/* → .agent/
- install.sh: .agent/src/ (PROTOCOLS, COMMANDS, TEMPLATES, install.sh/ps1, GUIDE)
- .temp/ добавлен в .gitignore
- .agent/checkpoints.json: phases.init=completed, project_type=existing
- .agent/rules/project-rules.md: R1-R5 (инварианты, ловушки, куда лезть, проверки)
- .agent/context/analysis-report.md: стек, архитектура, конвенции, кандидаты CI
- .agent/context/project-state.md: сжатый слепок (хосты, сервисы, ADR)
- .agent/roadmap/sources.md: открытые вопросы слоёв 0-11 (бывший invariants.md)
- .agent/tasks/manifest.{json,md}: 16 задач A1-F + 23 в backlog
- .agent/decisions/0001-sops-secrets-paths.md: ADR для инварианта S1
- AGENTS.md: metaagent-шапка + сжатая выжимка nixos (yaml frontmatter сохранён)
- удалены docs/arch/{map,invariants,todo}.md
2026-10-09 20:37:14 +03:00

84 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ADR-0001: sops-пути — только через `config.sops.secrets.<name>.path`
**Статус:** accepted
**Дата:** 2026-10-09
**Контекст:**
sops-nix материализует секреты на `/run/secrets/<attr>` по умолчанию.
Атрибут sops-блока (`config.sops.secrets.<attr>`) — единственный источник
истины для on-disk пути. Любой `path =` override на sops-блоке плюс хардкод
`"/run/secrets/<attr>"` в потребителе делает потребителя **молча**
сломанным: `nixos-rebuild` проходит, сервис стартует, файл читается — но
контент от прошлой версии или пустой. Симптом приходит из рантайма, не из CI.
До этой правки (см. «Обратное») в кодовой базе были хардкоды путей в 5
местах: `authelia.nix`, `open-webui.nix`, `tape-rotation.nix`, `remnawave.nix`.
В `remnawave.nix` тот же риск был двойной: путь хардкожен и в генераторе,
и в контейнере → расхождение двух копий = silent breakage.
**Рассматриваемые альтернативы:**
1. **A. `${config.sops.secrets.<attr>.path}`** — единая точка истины. Любой
`path =` override автоматически подхватывается потребителем.
2. **B. Хелпер `sopsPath = name: "/run/secrets/${name}"`** — был в `authelia.nix:51`
до правки. Компактнее в написании, но тащит хардкод `/run/secrets/` в API
и делает невозможным `path =` override без правки потребителя.
3. **C. `let envFile = "/run/secrets/${name}"; in { … }` для композитных
случаев** — для `remnawave.nix`, где один и тот же env-файл читается и
генератором, и контейнером. Используется, но с явным комментарием.
**Решение:** выбран вариант **A** для прямого доступа к одному секрету и
вариант **C** для композитных env-файлов в `remnawave.nix` (с комментарием).
**Обоснование:**
- **Единая точка истины.** Атрибут sops-блока — единственное место, где
определяется on-disk путь. Потребитель ссылается на `${config.sops.secrets.<attr>.path}`.
- **Симметрия с `mkUserSecret`.** `users.nix:33-41` уже использует этот
паттерн (`config.sops.secrets.<name>.path`) — единый стиль по репо.
- **Без хелпера.** `sopsPath = name: "/run/secrets/${name}"` выглядит
компактнее, но скрывает хардкод `/run/secrets/`. Когда кто-то добавит
`path = "/var/lib/..."` в sops-блок, потребитель через хелпер молча
сломается.
- **Двухкопийный env-файл в remnawave.nix** — композитный случай, где
`let`-биндинг в одном scope с комментарием «не дублировать литерал»
делает связь явной.
**Последствия:**
- Позитивные:
- `nix flake check` (после T1, T2) ловит несоответствие путей в compile-time.
- `path =` override в sops-блоке не ломает потребителя молча.
- Единый стиль по репо: 5 мест исправлены, новые пишутся по образцу.
- Негативные:
- Длиннее в написании, чем `"/run/secrets/${name}"`.
- Риски:
- Если кто-то добавит нового потребителя sops и напишет литерал
`/run/secrets/<name>` — молчаливое расхождение. Защита: код-ревью +
кандидат в CI-проверки (`secrets/missing-paths.nix` или grep).
**Invariant:**
> Любой потребитель sops-секрета в `modules/` ссылается на путь через
> `${config.sops.secrets.<attr>.path}`, а не через литерал
> `"/run/secrets/<attr>"`. Атрибут sops-блока — единственный источник
> истины для on-disk пути.
Зафиксировано в `.agent/rules/project-rules.md` (R1.7) + `analysis-report.md §8`.
**Обратное (где было сломано до этой правки):**
- `modules/server/authelia.nix:51,108,109` — через хелпер `sopsPath = name: "/run/secrets/${name}"`.
- `modules/containers/open-webui.nix:95` — литеральный хардкод.
- `modules/containers/tape-rotation.nix:61` — литеральный хардкод.
- `modules/containers/remnawave.nix:61, 129, 136` — литеральный хардкод, в двух местах (генератор + контейнер).
**Затронутые файлы (после правки):**
- `modules/server/authelia.nix:107-108`
- `modules/containers/open-webui.nix:101`
- `modules/containers/tape-rotation.nix:63`
- `modules/containers/remnawave.nix:16, 70, 138, 145` — `let`-биндинг для композитного env-файла (вариант C).