diff --git a/STATE.md b/STATE.md index 13210b7..facbfda 100644 --- a/STATE.md +++ b/STATE.md @@ -349,6 +349,28 @@ Snapshot `/var/www/print-calc.old.20260427-pre-v81` — оставлен для --- +## 🔒 Security политика для claude.ai/Code сессий + +Три инцидента с утечкой credentials в чаты за две недели: 27.04 (manager+owner пароли через `cat /root/print-calc-initial.txt`), 28.04 (DB password через `docker inspect`), 29.04 (Gitea token через clone-URL → `cat .git/config`). Этот раздел — правила, выработанные на этих инцидентах. + +1. **Любой credentials, попавший в текстовый output одной из сессий (claude.ai или Code), считается скомпрометированным с момента отправки.** Без оценки вероятности утилизации, без «там же только минута». Ротируется немедленно. Никогда не делаем исключения вида «доделаем последнюю команду и потом revoke». + +2. **Не использовать `cat` / `docker inspect` / `env` / `grep` на файлах с секретами.** Использовать точечный `awk` / `sed` по нужному ключу, передавать наружу **только результат**, не raw содержимое. Для проверок чистоты — бинарный exit code (`grep -q && echo OK || echo DIRTY`), не stdout значения. + +3. **Token в URL ≠ inline аргумент.** `git clone https://user:token@...` записывает токен в `.git/config`. Использовать `GIT_ASKPASS`, `git credential approve`, env-var с inline `git -c credential.helper`, или SSH-ключи. + +4. **Доставка токенов на сервер — через pipe, без промежуточного файла:** + ```bash + echo -n 'TOKEN' | ssh root@HOST 'umask 077; cat > /root/.token-name; chmod 600 /root/.token-name; wc -c /root/.token-name' + ``` + Пробел перед `echo` пропускает команду из shell history если `HISTCONTROL=ignorespace` (или эквивалент). Не использовать `nano`/`vim` для секретов, не делать локальные tempfile'ы. + +5. **TTL на все токены, никогда no-expiration.** Стандарт: 90 days для рабочих токенов, 30 days для разовых операций. Истекший токен = автоматическая страховка от забытого `shred`. + +6. **claude.ai-сессии ≠ secure transport.** Чат-история передаётся через Anthropic-инфраструктуру и хранится у них. Code-сессии — тоже. Любой текст, попавший в чат, считается прошедшим минимум через Anthropic-логи. Это не приватная переписка двух людей. + +--- + ## 📚 Уроки проекта (постоянные принципы) Эта секция — не про текущий трек, а про архитектурные решения, которые сложились в ходе работы над print-calc и должны соблюдаться следующими сессиями. Если приходит идея «давайте перенесём логику X в UI — так быстрее», сначала загляни сюда: возможно, мы уже это решили иначе и по веским причинам. @@ -459,13 +481,35 @@ Standalone PHP-скрипт **не может** надеяться на env-пе Не пытаемся реплицировать ArtiosCAD. Цель — типовые конструкции с параметрами, для нишевого сегмента (микрогофра у Sunprint). Полный CAD — это отдельный мир и отдельная экономика. +### Security в claude.ai/Code сессиях + +#### 13. Token в URL → токен в `.git/config`. Никогда `git clone https://user:token@...` + +Git автоматически сохраняет URL аутентификации в `.git/config` нового клона под ключом `[remote "origin"] url`. Любая последующая команда, читающая `.git/config` (включая `cat`, `grep`, диагностические скрипты), выводит токен в свой output — а в claude.ai/Code это сразу попадает в чат-логи. + +Безопасные альтернативы: +- `GIT_ASKPASS` обёртка с stdin +- `git credential approve` через pipe +- Inline `git -c credential.helper='!f() {...}; f'` (env-var живёт только время одной команды) +- SSH-ключи (когда настроим — сейчас приоритет в backlog) + +Если **уже** клонировали с токеном в URL — **первой же командой**: +```bash +git remote set-url origin https://host/path.git # без креденшалов +grep -q 'token\|@host' .git/config && echo DIRTY || echo CLEAN +``` + +Никогда не делать `cat .git/config` или `grep .git/config` со stdout'ом значения — даже для проверки чистоты. Бинарный exit code через `grep -q ... && echo DIRTY || echo CLEAN` — единственный допустимый паттерн. + +Инцидент 29.04: при smoke clone print-calc токен ушёл в чат через финальный `cat .git/config`. Поймали через 30 секунд после, отротировали. См. также раздел «🔒 Security политика для claude.ai/Code сессий» — этот урок №13 + 6 правил оттуда работают вместе. + --- ## 📝 Лог сессий (последние 5) | Дата | Среда | Длительность | Главное | |---|---|---|---| -| 2026-04-29 | claude.ai (Opus 4.7) → Claude Code (Opus 4.7) | планёрка + merge + Gitea-deployment | (1) План dieline-трека: путь Б (встроить в print-calc), Фаза 1 локально (1-2 нед), Фаза 2 интеграция (3-5 сессий). 7 решений TBD. (2) **Регрессия STATE.md:** claude.ai-сессия обновила файл от 27.04-baseline, затёрла 28.04. Поймали md5-сверкой, восстановили merge'ем из X-drive. Урок №12 добавлен. (3) **Gitea CE задеплоен на git.suntask.ru** — Let's Encrypt cert, nginx reverse-proxy на 127.0.0.1:3000, docker-compose в /opt/gitea, volume /opt/gitea-data, SQLite, DISABLE_REGISTRATION+DISABLE_SSH=true. Org `sunprint`, public repo `sunprint-state` для read-mirror STATE.md, правило #9 «public mirror = redacted». Новые backlog: swap, disk, db-cpu-spike, .bak-конфиги. | +| 2026-04-29 | claude.ai (Opus 4.7) → Claude Code (Opus 4.7) | планёрка + merge + Gitea-deployment + 2 incident'а | (1) План dieline-трека: путь Б, Фаза 1 локально (1-2 нед), Фаза 2 интеграция (3-5 сессий). 7 решений TBD. (2) **Регрессия STATE.md:** claude.ai обновила файл от 27.04-baseline, затёрла 28.04. Поймали md5-сверкой, восстановили merge'ем. Урок №12 + правило #8. (3) **Gitea CE задеплоен на git.suntask.ru** — Let's Encrypt, nginx reverse-proxy на 127.0.0.1:3000, docker-compose в /opt/gitea, SQLite. Org `sunprint`, public `sunprint-state` (правило #9, redacted), private `print-calc`. (4) **Incident: token в URL** при smoke clone попал в чат через `cat .git/config`. Поймали за 30 сек, отротировали. Урок №13 + Security-секция. Новые backlog: swap, disk, db-spike, .bak-конфиги. | | 2026-04-28 | Claude Code (Opus 4.7) | ~6ч | **Большой день. Полная end-to-end интеграция SunTask ↔ calc работает.** (1) SunTask SSO bridge: calc-redirect.php v1→v4→v5→v6, 6 итераций архитектуры. (2) Lv7CMS reverse-engineering: 5 уроков (routing из БД, bootstrap без dispatch, session_save_path override, parse_ini_file process_sections, env под app). (3) Basic Auth снят с calc.suntask.ru через `sed -i` + `nginx -s reload` — 6-й урок добавлен. Подтверждение: POST /api/v1/calculate → 200 от Димы () и от другого менеджера () — оба смогли реально использовать калькулятор | | 2026-04-28 (утро) | Claude Code (Opus 4.7) | ~10мин | observation v8.1 прошёл — 24h без ошибок, 0 пятисоток, restic backup OK ночью | | 2026-04-27 (вечер) | Claude Code (Opus 4.7) | ~3ч | **v8.1 БАГ колод задеплоен.** Pipeline `prepareEngineInput.ts` (вариант 1.5), 10 новых тестов, 93/93 зелёных, smoke на live прошёл |