Files
SQS-service/doc/thinking/my-analysis-of-opus-report-2026-10-05.md
T

7.4 KiB
Raw Blame History

Критический анализ отчёта Opus (мой разбор, 2026-10-05)

Кем: я (DeepSeek). Что: критический разбор отчёта Opus (opus-report-2026-10-05.md) по архитектуре shared-sqs. Метод: ключевые утверждения Опуса перепроверялись по коду напрямую, а не принимались на веру. Источники — «файл:строка».


Что я перепроверил по коду (факты)

Утверждение Опуса Вердикт Источник в коде
P0.1: SecretKey детерминирован из email + соль в исходнике ✅ подтверждено tenant_store.go:289-292 secretKeyFromEmail = SHA256(lower(email)+":shared-sqs:secret-key:v1"); соль — константа secretKeySalt (tenant_store.go:286); accessKeyFromEmail = SHA256(email)[:12]
P0.2: JWT без проверки подписи, доверие на PingNubesAPI ✅ подтверждено jwt.go — парсинг структуры + exp; PingNubesAPI принимает, если хоть один стенд не 401/403
Кэш: отозванный токен живёт до ~7 мин ✅ подтверждено cache.go: cacheTTL=5m, cacheGraceTTL=2m
Глобальный мьютекс на весь сервис ✅ подтверждено globals.go:20-23 — один SyncQueues.RWMutex + Queues map[string]*Queue
Сиротство очередей при пересчёте legacy-тенанта ✅ подтверждено tenant_store.go:202-205 — комментарий в коде сам это описывает
MessageRetentionPeriod не реализован ✅ подтверждено models.go — // TODO - not used

Ложных утверждений не найдено.


Сильные стороны отчёта

  1. P0.1 — самая ценная находка. Детерминированный вывод SecretKey из публичного email — реальный, доказуемый по коду дефект. Указан не только механизм, но и точные функции. Именно это реально блокирует «готовность SQS».
  2. Верно разделены SigV4 и JWT. SigV4 проверяется полноценно (auth_middleware.go: canonical request, subtle.ConstantTimeCompare, clock skew, presigned); JWT — нет. Большинство поверхностных ревью их путают.
  3. Классификация P0/P1/P2 адекватна — безопасность+durability отделены от масштабируемости и гигиены.
  4. Пункты 3–7 (глобальный лок, SPOF, async-Redis, нет RetentionPeriod, плоский слайс) — архитектурно точны.
  5. Раздел «противоречия док↔код» конкретен (особенно №1: док про sub/bySub/sless-, код про email/byEmail/t-).

Слабые места и оговорки

  1. P0.2 переоценён как самостоятельный «критичный». Вектор «подмена email → доступ» опасен только в связке с P0.1: неверный email даёт чужие креды, потому что креды детерминированы из email. Исправь P0.1 (случайные креды в Redis) — и неверный email из JWT уже не даст чужих ключей, только провиженинг под чужим именем (менее критично). Опус не связал P0.1 и P0.2 явно, хотя атака работает попарно. Стоит оформить как один инцидент.

  2. П.4 «SPOF/нет горизонтального масштабирования» — справедливо архитектурно, но сервис и проектировался single-instance managed HTTP-контейнером (README). Это осознанное ограничение, а не баг. В разряд «высокого риска сейчас» ставить преждевременно — это долгосрочная архитектурная развилка, а не текущий блокер.

  3. П.5 (async-Redis = потеря подтверждённых сообщений) — полуверно. Сообщение в памяти уже есть (клиент получил 200 = сообщение в памяти, источнике правды). Теряется только при краше пода до async-HSet, и только это узкое окно. Окно реально, но «нарушение durability» подано сильнее, чем есть: теряются не все сообщения, а только при краше в окне.

  4. П.10 (timing side-channel admin-токена) — технически верно, но admin-токен приходит как высокоэнтропийный bearer; практическая эксплуатируемость timing-атаки через сеть у одного короткого сравнения ничтожна. Формально в P2 и есть, но вес в подаче чуть завышен.

  5. П.14 (/metrics публичен) — стоит оговорка: лейбл tenant = tenantID (t-...), а НЕ SecretKey. Утечка реальна (число очередей/сообщений по тенанту), но это не утечка кредов. Формулировка корректна, но без оговорки читается страшнее.

  6. Пробел контекста (не ошибка Опуса, а следствие моего allowlist-запрета): отчёт не отделяет «код-блокировку» от «платформенной блокировки» — периодические таймауты ~31–33с и MSS-баг для тел >~1400 байт (разобрано в doc/thinking/nubes-ticket.md). Даже идеальный код их не уберёт. Итоговый вывод о «готовности SQS» надо читать с этой поправкой.


Итоговая оценка

Отчёт — добротный, по фактам точный. Из 16 пунктов рисков ложных нет; спорные — только вес/приоритет:

  • P0.2 связать с P0.1 (один инцидент);
  • п.4 (SPOF) и п.10 (timing) слегка переоценены для текущей single-instance роли.

Главная ценность: P0.1 (детерминированный SecretKey) — подтверждённый по коду блокер готовности, который до этого так жёстко не формулировался. Единственный реальный пробел — платформенный контекст (таймауты/MSS), но он возник из моего же allowlist и устраняется дополнением, не исправлением.