Архитектура AutoGov

July 12, 2026 · View on GitHub

Документ описывает, как реализация соответствует архитектурным решениям ТЗ §4 и почему ядро спроектировано как платформа с плагинами (Требование ТЗ-0).

Поток данных

┌─────────┐   observations   ┌───────────┐   events    ┌────────────────┐
│  AGENT   │ ───────────────▶ │ Ingest API │ ─────────▶ │   Event Bus     │
│ (host)   │   mTLS/bearer    │  (dedup)   │            │  (pub/sub)      │
└─────────┘   outbound-only   └───────────┘             └───────┬────────┘
                                                                 │ observation.*
                                                         ┌───────▼────────┐
                                                         │ Module Runtime  │
                                                         │  M1 discovery   │
                                                         │  M2 honeynodes  │ (stub)
                                                         │  M3 selfhealing │ (stub)
                                                         │  M4 autodoc     │ (stub)
                                                         └───────┬────────┘
                    ┌───────────────┬────────────────────┬──────┘
                    ▼               ▼                     ▼
             ┌────────────┐  ┌────────────┐      finding.* events
             │ Asset Store │  │ Risk Engine│             │
             │ (inventory) │  │ (scoring)  │             ▼
             └────────────┘  └────────────┘      ┌──────────────┐
                    │                             │  Notifier     │──▶ SIEM / webhook / email
                    ▼                             └──────────────┘
          Web UI / Public API (RBAC + аудит)

Ключевые решения (ТЗ §4.2) и их реализация

Разделение «Агент ↔ Control Plane»

Агент (internal/agent) только собирает и нормализует данные; вся аналитика (скоринг, корреляция, модули) — в control plane. Это даёт лёгкий, аудируемый агент и позволяет добавлять модули M2–M4 без обновления агента.

Outbound-only агент, mTLS (ТЗ §4.2, §9)

Агент сам инициирует исходящее соединение (agent.ship); он не открывает портов (нет EXPOSE в Dockerfile.agent). mTLS: клиентский сертификат в agent.buildClient, проверка цепочки для /ingest в server.checkAgentAuth.

Событийная шина (ТЗ §4.2)

internal/bus — in-process pub/sub с одним детерминированным циклом доставки. Подписка по шаблону типа события (observation.*, finding.*, точное имя). Развязывает сбор от анализа и даёт точки расширения: M3 подпишется на workflow.error, M2 — на honeynode.access.

Плагинная модель (ТЗ-0)

internal/modules.Runtime + интерфейс Module:

type Module interface {
    Name() string
    Subscriptions() []string
    Handle(ctx, ev, *API) error
}

Модуль взаимодействует с платформой только через modules.API (Store + Bus + Logger + PublishFinding/PublishEvent). Он не имеет доступа к внутренностям ядра. Это и есть проверяемая граница: если будущему модулю понадобится менять ядро — контракт нарушен (ТЗ §6). Тест plugin_test.go показывает, что M2 встаёт на ту же шину/хранилище и выдаёт находку, ничего не меняя в ядре.

Многосигнальный детект (ТЗ §5.1)

Модуль discovery нормализует наблюдения от разных коллекторов в один и тот же Instance через детерминированный StableID. Разные коллекторы накапливаются в Instance.DetectedBy, а store.UpsertInstance объединяет сигналы (эскалирует exposure, берёт максимум confidence). Так один инстанс, увиденный и по файловой системе, и по сети, — это один актив с высокой уверенностью, а случайный контейнер с совпавшим портом (один слабый сигнал) — отсеивается (см. TestMultiSignalReducesFalsePositives).

Идемпотентность (ТЗ §8.2)

Каждое наблюдение получает ID один раз в момент сбора (collect.NewObservation). store.MarkEventSeen отбрасывает повторы (буфер дедупликации с обрезкой). Находки имеют стабильный ID на инстанс — повторный скан обновляет находку на месте, а не плодит дубли.

Privacy by design (ТЗ §7, §9)

  • Модель данных CredentialRef хранит Type/TargetSystem/Fingerprint, но не значение.
  • agent/sanitize.SplitEnv делит env на: имена (метаданные), секреты (имя→SHA-256-отпечаток, значение отброшено) и узкий allowlist несекретной конфигурации (DB_TYPE и т.п.) для целей детекта.
  • sanitize.Scrub вычищает высокоэнтропийные токены из свободных строк (cmdline, cron-команды) перед отправкой.

On-prem egress-guard (ТЗ §8.4)

notify.EgressGuard.Check в режиме onprem (без allow_external_egress) разрешает только приватные/loopback-адреса. Проверка выполняется при конструировании notify.Manager — конфиг с внешним syslog/webhook ломает старт, а не «молча» осуществляет трансграничную передачу.

Хранилище

internal/store — потокобезопасное хранилище со снапшотом state.json (атомарная запись через temp+rename) и append-only JSONL для аудита и сырых событий. Без внешней БД: одно-контейнерная установка для on-prem/air-gapped. Интерфейс узкий — SQL-бэкенд можно подставить позже без изменения модулей.

Что намеренно упрощено в MVP

  • Шина — in-process (для масштаба ТЗ §8.1 «до ~10 000 инстансов» достаточно); вынос в внешнюю очередь — точка расширения, контракт не меняется.
  • PDF-генератор минимальный (кириллица транслитерируется); машиночитаемый источник истины — JSON-отчёт.
  • M2–M4 — заглушки-контракты; полная реализация — Э3–Э4.