From f3c76ca583b58ce38a5eb867958c684b532941f4 Mon Sep 17 00:00:00 2001 From: Anton Vakhrushev Date: Sat, 25 Jul 2026 11:43:14 +0300 Subject: [PATCH] =?UTF-8?q?backlog:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=B8=D0=B4=D0=B5=D1=8F=20=D0=BE=20=D1=85?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=BF=D0=B0=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D1=8F=20ansible-vault?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Пароль лежит открытым текстом рядом с репозиторием, а `ansible.cfg` подставляет его в любую ansible-команду — отсюда дамп секретов через `ansible-inventory --list`. - Заведена идеей, а не задачей: компромисс «удобство против доступности автоматизации агенту» не разрешён, варианты с KeePassXC записаны с ценой. --- docs/backlog/README.md | 1 + docs/backlog/vault-password-storage.md | 49 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 docs/backlog/vault-password-storage.md diff --git a/docs/backlog/README.md b/docs/backlog/README.md index 20c1891..7b56d47 100644 --- a/docs/backlog/README.md +++ b/docs/backlog/README.md @@ -46,3 +46,4 @@ _(sec-ревью)_ — три независимых security-ревью на м - [Инвентарь: `host_vars`, именованные группы, точечный `become`](ansible-inventory-hostvars.md) — хост-специфику в `host_vars/server.yml`, хост в именованную группу, глобальный root → точечный become _(ансибл-ревью)_ - [Фоновая зачистка стиля и конфигурации Ansible](ansible-style-nits.md) — sudoers.d, профиль ansible-lint, `ansible.cfg`, кавычки, `cache_valid_time` _(ансибл-ревью)_ - [Logrotate для логов бэкапов](backup-logs-logrotate.md) — логи `backup-all.py`/restic копятся без ротации _(tududi)_ +- [[idea] Где хранить пароль ansible-vault](vault-password-storage.md) — пароль открытым текстом рядом с репо, `ansible.cfg` подставляет его в любую ansible-команду; вариант — доставать из KeePassXC diff --git a/docs/backlog/vault-password-storage.md b/docs/backlog/vault-password-storage.md new file mode 100644 index 0000000..51023bb --- /dev/null +++ b/docs/backlog/vault-password-storage.md @@ -0,0 +1,49 @@ +# [idea] Где хранить пароль ansible-vault + +**Приоритет:** Низкий + +Пароль vault лежит открытым текстом в `./ansible-vault-password-file` (в +`.gitignore`, есть `.dist`-заглушка), а `ansible.cfg:4` объявляет +`vault_password_file` глобально — значит расшифровка происходит неявно в **любой** +ansible-команде, не только в деплое. Из-за этой связки 24 июля +`ansible-inventory --list` вывалил в транскрипт 53 из 64 vault-переменных +открытым текстом. + +Зацепка: если файл из `vault_password_file` исполняемый, ansible запускает его и +берёт пароль из stdout. То есть пароль можно не хранить на диске, а доставать из +KeePassXC — `ansible.cfg` при этом не меняется, достаточно `chmod +x`. Сам скрипт +секрета не содержит, его можно закоммитить и выкинуть связку `.gitignore` + +`.dist`. + +Два способа достать, оба проверены на наличие в системе: + +- **Secret Service** — `secret-tool lookup` к разблокированной базе по D-Bus. + Требует `libsecret-tools` (не установлен) и включённой в KeePassXC интеграции с + экспортом отдельной группы. Деплой без запросов пароля, при заблокированной базе + — fail-closed. +- **`keepassxc-cli show -s -a Password `** — без D-Bus и без новых + пакетов (`keepassxc-cli` установлен), но пароль от базы спрашивается на каждый + вызов; `inv pl` придётся перевести на `pty=True`, как уже сделано в + `authelia-cli` и `vault-edit`. + +**Нерешённый компромисс — ради него задача и заведена.** Вводить пароль руками на +каждый деплой неудобно. Но любая автоматизация, которая эту неудобность снимает +(разблокированная база, D-Bus, кэш), ровно так же доступна агенту: он найдёт +скрипт и вызовет его сам. То есть выбор хранилища **не защищает от агента** — от +него защищают только deny-правила в `~/.claude/settings.json`, которые +enforcement-слой применяет снаружи. Что смена хранилища действительно даёт: +пароля больше нет на диске (а значит в снапшотах restic и в Syncthing), и при +заблокированной базе всё падает закрыто для всех. + +Прежде чем решать, стоит честно ответить: от чего именно защищаемся — от +случайного дампа, от копии `~` в чужих руках, или от агента. Ответы ведут к разным +вариантам, а третий не решается на этом уровне вообще. + +Смежное: [secrets-env-to-file](secrets-env-to-file.md) — тот же вопрос слоем ниже +(секреты в `environment:` контейнеров). Отдельно не заведена, но обсуждалась, +идея скоупинга: вернуть `group_vars/all/secrets.yml` в `vars_files`, оставив +`main.yml` в `group_vars` — это режет потолок утечки с 53 переменных до ~11, ценой +возврата boilerplate в плейбуки. + +Связано: ansible.cfg, tasks.py, group_vars/all/secrets.yml, +ansible-vault-password-file.dist, .gitignore.