diff --git a/.tasks/STATUS.md b/.tasks/STATUS.md index 9b2fcf4..f48910d 100644 --- a/.tasks/STATUS.md +++ b/.tasks/STATUS.md @@ -299,3 +299,60 @@ Done — 🟢; unblock `secrets-manager-adopt`. --- + +## 🔵 [secrets-manager-adopt] — Этап 2 secret-management: внедрить `pass` (gpg-based password-store) — encrypted-at-rest secrets + cross-machine sync через private Gitea repo с encrypted blobs. + +Альтернатива — Bitwarden CLI (cloud vault, audit log). Recommend `pass` для one-user setup — нет cloud-dependency, gpg native, encrypted git-syncable. + +**Why этап 2 нужен:** после `secrets-out-of-common` (этап 1) секреты лежат plaintext в `~/.config/projects-secrets/`. Этап 1 убирает риски 1+3 (git leak + IDE indexing), но не риск 4 (любой filesystem read даёт plaintext) и не риск 2 (Hyper Backup на kreknin всё ещё тащит plaintext если `~/.config/` в scope, что зависит от backup config). `pass` закрывает оба — secrets зашифрованы на диске, расшифровка только в RAM при `pass show`. + +См. `concepts/admin-infra-project.md` §Initial admin agenda E.3. + +**Status:** blocked +**Where I stopped:** (not started) +**Next action:** **1. Pre-install — gpg setup (Windows):** +- Install Gpg4win (https://www.gpg4win.org/) или через Scoop: `scoop install gpg`. +- `gpg --full-generate-key` — выбрать RSA 4096, без expiration ИЛИ 2-year expiration с rotation reminder. +- `gpg --list-secret-keys` — захватить fingerprint. + +**2. Install pass:** +- MSYS2: `pacman -S pass` (если есть MSYS2) +- Scoop: `scoop install pass` +- Manual: pass is bash script — clone https://git.zx2c4.com/password-store/ и положить на PATH. + +**3. Initialize store:** +```bash +pass init +# Creates ~/.password-store/.gpg-id +``` + +**4. Migrate secrets:** +- Для каждого file/var в `~/.config/projects-secrets/`: + - `pass insert /` → вводим plaintext, pass сохраняет как `~/.password-store//.gpg` +- Примеры: + - `pass insert gitea/admin-token` + - `pass insert vds-kzntsv/ssh-password` + - `pass insert vds-kzntsv/portainer-password` + - `pass insert interns/openai-key` + - `pass insert interns/anthropic-key` +- Сохранить mapping (какой `.env` key какой `pass`-path) — `concepts/secrets-pass-mapping.md` ingest в admin wiki. + +**5. Update consumers** — заменить direct file reads на shell-out calls: +- `interns-mcp` config: вместо `OPENAI_API_KEY=` в env-файле → `OPENAI_API_KEY=$(pass show interns/openai-key)` в wrapper-скрипте startup. +- `~/.claude.json` `mcpServers.*` env: если поддерживает command-eval — `pass show ...`; иначе wrapper-script. +- Альтернатива — `pass`-aware loader script `~/.config/projects-secrets/load.sh` который populate'ит env vars из pass при session start. + +**6. Cross-machine sync:** initialize private Gitea repo `OpeItcLoc03/password-store-private` (visibility=private), push `~/.password-store/`. На каждой машине: clone + `gpg --import` master key + работает. + +**7. Cleanup plaintext:** удалить `~/.config/projects-secrets/*` (содержимое мигрировано в pass). Оставить пустой dir + README указывающий на pass. + +**8. Verify:** в чистой сессии все MCP / scripts работают через pass-resolved secrets. + +Acceptance: `ls ~/.config/projects-secrets/` пуст или содержит только README, все consumers работают, `pass git status` clean, encrypted blobs в Gitea private repo. + +Done — 🟢; secret-management dyra closed. +**Blocker:** secrets-out-of-common +**Branch:** n/a + + +---