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

5.5 KiB
Raw Blame History

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).