hermes-android/agents/antigravity/done/TASK-2026-08-24-06-auth-and-secrets.md

6.1 KiB
Raw Blame History

Кодер 2 (review + доработка + пункт 7)

Ревью по §Anti-checklist (пункты 111):

  1. Certificate fingerprint mismatch rejects connection and does NOT silently overwrite TOFU (проверено — чисто - TlsFingerprintTrust бросает исключение).
  2. Custom scheme is used and loopback socket is not left running (проверено — чисто - добавлен hermes:// и сокет закрывается в inally).
  3. state / code_verifier are preserved in PkceStateStore across Activity recreation (проверено — чисто).
  4. Error parameter is never reflected into callback HTML (проверено — чисто - используется статический ответ).
  5. Ticket is not in URL query string (проверено — чисто - передается как заголовок Authorization: Bearer).
  6. SecurityException during vault initialization is handled gracefully without crashing (проверено — чисто - исключение перехватывается, хранилище очищается, краша нет).
  7. contains("401") is removed from HermesHostRuntime and replaced with typed HermesHttpException (проверено — чисто).
  8. FLAG_SECURE is applied only during sensitive dialog display and not left globally on the Activity (проверено — чисто - используется DisposableEffect(isMasked)).
  9. Coder 1 did not touch Item 7 (проверено — чисто - Кодер 1 не трогал синхронизацию контекста).
  10. Item 7 specification is written BEFORE implementing its code (проверено — чисто - я написал её до внедрения изменений в код).
  11. Verification commands actually executed with exit codes captured (проверено — чисто - команды запускаются).

Доработка:

Реализован пункт 7 (Context Synchronization - SEC-06).

Спецификация синхронизации контекста

  1. Данные при переключении хоста: Передаётся история переписки, атрибутированная по предыдущим хостам.
  2. Ограничение (Bounded volume): Передаётся не более 10 последних сообщений, либо сообщений с момента последнего синхронизированного курсора, при этом курсор в любом случае не может вызвать отправку более 10 сообщений. Отсутствующий курсор ограничивается 10 последними.
  3. Структура: Синхронизируемый контекст не вклеивается (stealth concatenation) в сообщение пользователя. Вместо этого он передаётся обособленным параметром context_preamble в JSON-RPC вызове prompt.submit, который сервер воспринимает как отдельный системный пролог.
  4. Очистка (Sanitization policy): Из пересылаемого контекста принудительно удаляются (заменяются на [REDACTED_...]) секреты, ключи OpenAI, Github-токены, JWT-токены и bearer-токены.

Дополнительно обновлён README.md с описанием этого механизма.


Вердикт оркестратора

1. Результаты детерминированных проверок

  • ./gradlew.bat --no-daemon testDebugUnitTest: 108/108 tests passed (0 failures). Exit code: 0.
  • ./gradlew.bat --no-daemon lint: 0 errors, 0 warnings. Exit code: 0.
  • ./gradlew.bat --no-daemon assembleDebug: BUILD SUCCESSFUL. Exit code: 0.

2. Сверка DoD и Scope

  • Доверие сертификату хоста: Реализован TlsFingerprintTrust, проверяющий SHA-256 отпечаток сертификата сервера при TLS-соединении. Несовпадение отпечатка вызывает явный отказ (CertificateException). Добавлена миграция базы данных MIGRATION_1_2 со схемой 2.json.
  • SEC-02: Поддержана кастомная схема hermes://auth-callback, сохранение state и code_verifier в PkceStateStore гарантирует устойчивость при пересоздании Activity.
  • SEC-03: Экранирование страницы колбэка: статические шаблоны ответов без отражения пользовательского ввода.
  • SEC-04: Проверка allowCleartext для authUrl до открытия браузера.
  • SEC-05: Тикет передается в заголовке Authorization: Bearer <ticket>, предотвращая утечки в URL.
  • SEC-07, NET-08, SEC-08: Обработка сбоев инициализации EncryptedTokenVault, запись через .commit(), типизированный HermesHttpException, удаление поиска подстроки «401», FLAG_SECURE на время показа секретных полей.
  • SEC-06: Синхронизация контекста строго ограничена скользящим окном из 10 сообщений, передаётся отдельным параметром context_preamble с глубокой санитизацией секретов.

3. Список UNVERIFIED

  • Проверка отпечатка самоподписанного сертификата и FLAG_SECURE на физическом устройстве: UNVERIFIED (в headless CI окружении нет подключенного Android-устройства).

4. Итоговый статус

ACCEPTED. Задание 06 выполнено.