Перейти к содержимому

Обзор архитектуры

Эта страница объясняет, как устроена Olivares AI и почему. Это объяснение, а не руководство: оно даёт ментальную модель, необходимую для рассуждений об управляющем слое (control plane), прежде чем вы будете устанавливать, настраивать или расширять его. Пошаговые инструкции ищите в практических руководствах; точные контракты — в справочнике API и в справочнике событий.

Архитектура: поверхности агентов, источники аудита, узлы MCP и A2A и источники контента собираются тремя способами в один самостоятельно размещаемый бинарный файл Go со встроенной консолью, который несёт модули продукта, слой политик и принуждения и подписанный журнал доказательств поверх хранилища с областью видимости по арендатору; он обслуживает консоль, REST API, ограниченное подмножество gRPC, CLI и провайдер Terraform, а облачная плоскость управления (собрана, не развёрнута) и портал лицензий (развёрнут, выдача отключена) показаны как отдельные плоскости. Архитектура: поверхности агентов, источники аудита, узлы MCP и A2A и источники контента собираются тремя способами в один самостоятельно размещаемый бинарный файл Go со встроенной консолью, который несёт модули продукта, слой политик и принуждения и подписанный журнал доказательств поверх хранилища с областью видимости по арендатору; он обслуживает консоль, REST API, ограниченное подмножество gRPC, CLI и провайдер Terraform, а облачная плоскость управления (собрана, не развёрнута) и портал лицензий (развёрнут, выдача отключена) показаны как отдельные плоскости.

Платформенная модель: один движок, модули, коннекторы

Заголовок раздела «Платформенная модель: один движок, модули, коннекторы»

Olivares AI — это не инструмент одного назначения. Это модульная платформа в традиции Grafana, Backstage и управляющего слоя Kubernetes: один движок (ядро) плюс модули плюс коннекторы. Продукт охватывает каталог модулей — инвентаризация, сессии, карта доступа, governance, FinOps, оценки (evaluations), guardrails и другие, — но все они работают поверх единого общего движка.

Управляющее ограничение архитектуры — это правило «без перепроектирования» («no re-architecture»): движок спроектирован так, что любой модуль из каталога можно добавить, не трогая ядро и другие модули. Конкретно каждый новый модуль:

  1. Потребляет нормализованные события и данные из движка;
  2. Объявляет собственные сущности в общей модели данных;
  3. Предоставляет собственные конечные точки API и представления UI.

Ни один модуль не лезет во внутренности другого, и ни один из них не перекраивает ядро под себя. Движок заранее оплачивает издержки того, чтобы с первого дня быть многоарендным (multi-tenant), событийно-ориентированным и API-first, именно для того, чтобы широту можно было добавлять позже без перепроектирования. Тот же принцип объясняет порядок сборки — сначала движок CLI, веб поверх: CLI и есть движок и предоставляет всю функциональность через CLI и API; веб — это слой представления поверх того же API, без дублирования логики. Построение движка, а затем визуального лица поверх него — это не перепроектирование.

Отличающая возможность — карта доступа на чтение/запись с диффом разрешённого против наблюдаемого (permitted-versus-observed) — сама по себе является модулем (модуль III) поверх общей модели, а не отдельным конвейером. Именно это сохраняет платформу честной: флагманская функция подчиняется тем же правилам, что и всё остальное.

Движок (ядро, «Layer 0») — это набор общих подсистем, на которых держится всё остальное. Их восемь.

ПодсистемаЧто делаетПочему живёт в ядре
Сбор + шина событийПринимает вход OTLP и от коннекторов, нормализует его и распределяет события по модулямМодули реагируют на события без связанности друг с другом
SDK коннекторовСтабильный интерфейс коннектора ввода/вывода — опора для широтыТретьи стороны расширяют платформу без форка ядра
Среда выполнения модулейЗагружает и запускает модули: скомпилированные внутрипроцессно плюс внепроцессные плагиныДобавление модуля без перепроектирования или перекомпиляции ядра
Общая модель данныхМногоарендные сущности и связи, обслуживающие весь каталогЕдиная схема, которую все модули разделяют и расширяют
API (REST/gRPC) + manage-as-codeВся функциональность через API, плюс провайдер TerraformCLI и веб говорят через один API; панель управляется через GitOps
AuthN/Z + многоарендностьRBAC/ABAC, организации и арендаторы, изоляцияДооснащение правами и арендностью разорительно дорого — поэтому с первого дня
Аудит + целостностьЖурнал только-на-добавление (append-only), скреплённый хэш-цепочкойДоказуемость подделки сквозная, никогда не опциональна
Лицензия / права (entitlement)Офлайн-валидация лицензии по Ed25519Самообслуживаемая коммерция, работает в изолированной (air-gapped) среде

Несколько деталей, заслуживающих упоминания:

  • Среда выполнения модулей. Базовые модули компилируются в бинарный файл; внепроцессные модули и коннекторы запускаются как плагины через gRPC с использованием hashicorp/go-plugin. Это даёт изоляцию сбоев и позволяет добавлять модуль без перекомпиляции ядра.
  • Шина событий. По умолчанию внутрипроцессная (каналы Go). Распределённая привязка через NATS опциональна, не обязательна — одноузловые развёртывания её никогда не касаются.
  • Manage-as-code. API является контрактом-первоисточником; поверхность manage-as-code добавляет провайдер Terraform, чтобы сам управляющий слой можно было декларировать и держать под версионным контролем.
  • Аудит + целостность. Журнал только-на-добавление и скреплён хэш-цепочкой, с контрольными точками, подписанными Ed25519. Записи несут порядковый номер, предыдущий хэш, текущий хэш и подпись — и никогда не несут PII. Журнал покидает узел двумя путями: конечная точка экспорта по pull выдаёт CEF, LEEF, syslog, OTLP (полный, готовый к отправке запрос экспорта; otlp_envelope — его точный псевдоним, а простая проекция LogRecord — отдельный токен otlp_log_record) или OCSF, а push — реальный, как только настроена подписка на событие audit.recorded — доставляет каждую опечатанную запись не менее одного раза по надёжному транспорту. См. как пересылать аудит в Splunk.
  • Лицензия. Валидация офлайн, с использованием Ed25519, и движок не делает ни одного лицензионного обращения — что и делает работу в изолированной среде возможной. Единственная команда, которая выходит в сеть, — olivares upgrade: по умолчанию она загружает из GitHub-релизов публичного репозитория, а с --enterprise — из воркера лицензий (licenses.olivares.ai), если только --endpoint не направит её на ваше собственное зеркало или --bundle не установит из принесённого комплекта.

Подробности аутентификации и авторизации (непрозрачные bearer-токены, токен установки при первой загрузке, точка принятия решения по политикам — policy decision point) см. в модели безопасности; здесь они приводятся в сводном виде только там, где архитектура от них зависит.

Единая многоарендная схема обслуживает весь каталог. Каждая базовая сущность несёт tenant_id, а изоляция обеспечивается на уровне запроса/строки. Базовые сущности охватывают организации и арендаторов, агентов, сессии, модели и провайдеров, серверы MCP, навыки и инструменты, ресурсы (базы данных, серверы, хранилища, API), идентичности, политики, записи о затратах, результаты оценок, находки (findings), события аудита, статус работоспособности и развёртывания — и, центрально, AccessEdge.

Каждый модуль регистрирует собственные сущности и связи через реестр типов и таблицы на уровне модуля, не ломая ядро. Это и есть механизм, лежащий в основе правила «без перепроектирования» на уровне данных.

Хранилище начинается как SQLite (чистый Go-драйвер modernc, так что бинарному файлу не нужен CGO и он работает в изолированной среде) для одноузловых развёртываний и переходит к Postgres с защитой на уровне строк (row-level security) для многоарендности и масштаба.

Модуль III: карта доступа как представление над моделью

Заголовок раздела «Модуль III: карта доступа как представление над моделью»

Флагманский модуль — это карта доступа на чтение/запись и её дифф разрешённого против наблюдаемого (permitted-versus-observed) — дрейф наименьших привилегий (least-privilege drift). Критическая архитектурная мысль в том, что это представление над общей моделью данных, а не отдельная схема. Карта материализуется из сущностей AccessEdge, а сам AccessEdge несёт обе стороны — разрешённую и наблюдаемую, вместе с источником сигнала и уровнем уверенности. Поэтому дифф — это запрос над той же многоарендной моделью, которую использует любой другой модуль.

Карта работает по принципу read-first: она наблюдает из логов, OpenTelemetry и (как запасной механизм) eBPF — она никогда не находится в пути данных вызовов агента. Она также минимизирует данные: хранит связь (агент читает/пишет ресурс), но никогда полезные данные, секреты или PII. Эта асимметрия преднамеренна — высокий сигнал, низкий риск.

Кооперативный путь, скрещённый с нативным аудитом хранилища

Заголовок раздела «Кооперативный путь, скрещённый с нативным аудитом хранилища»

Точность достигается скрещиванием двух независимых видов свидетельств:

  • Кооперативный путь — Claude Code и агенты эмитят телеметрию через OpenTelemetry (OTLP), дополненную интроспекцией MCP инструментов и ресурсов, которые предоставляет сервер. Приёмник OTLP — часть базового сбора и по умолчанию слушает на петлевом интерфейсе (loopback). См. подключение Claude Code.
  • Нативный аудит хранилища — хранилище говорит вам, что произошло на самом деле. pgAudit классифицирует READ против WRITE дословно в Postgres; CloudTrail обнажает readOnly для S3; эквивалентный нативный аудит существует для других движков.

Когда кооперативный путь и собственный аудит хранилища сходятся в оценке ребра, у вас есть подтверждённая связь чтения/записи.

Запасной механизм eBPF, недоверенные аннотации и многоуровневое покрытие

Заголовок раздела «Запасной механизм eBPF, недоверенные аннотации и многоуровневое покрытие»

Три дополнительных свойства делают карту достоверной, а не наивной:

  • eBPF / Tetragon — некооперативный запасной механизм. Для путей, которые не кооперируют, наблюдатель на уровне ядра даёт истину в первой инстанции о намерении чтения/записи на уровне процесса и хоста. Он работает вне контроля агента (защита от уклонения), но слеп к полезным данным TLS — и это нормально, потому что карте нужна только связь, а не содержимое.
  • Аннотации MCP недоверенные. Подсказки MCP read-only / destructive — полезный сигнал, но сама спецификация MCP гласит, что клиенты должны считать их недоверенными. Поэтому карта подтверждает их по другим источникам и никогда не доверяет аннотации в одиночку.
  • Покрытие многоуровневое, и продукт это сообщает. Некоторые хранилища чисты для пассивного наблюдения (SQL-базы, объектные хранилища, склады данных); некоторые потеряны (Mongo, векторные базы); а некоторые невозможно наблюдать пассивно (Redis, SQLite, D1). Карта показывает уровни уверенности (атрибутировано против приблизительно), а не притворяется точностью, которой у неё нет.

Просмотр графа доступа — это привилегированное действие: ограничено арендатором, доступно роли editor и выше (никогда самой низкой роли viewer), и каждое чтение аудируется. Маршруты карты — граф и результат дрейфа — не входят в стабильный базовый контракт; они опубликованы в отдельном beta-справочнике маршрутов модулей (обслуживается по адресу /openapi.beta.json), а их формы на уровне полей живут в типизированных интерфейсах Go и TypeScript. Результат сравнения разрешённого с наблюдаемым доступен по маршруту drift движка (/v1/m/accessmap/drift); отдельной конечной точки diff нет. Стабильная базовая REST-поверхность — 53 пути, отрисованных из собственного контракта продукта OpenAPI 3.1 — документирована в справочнике API. Полный список модулей см. в каталоге модулей.

Один и тот же бинарный файл поддерживает несколько топологий. Одно ограничение действует во всех них: слой данных (data plane) — коллекторы — всегда работает на инфраструктуре заказчика. Именно это делает возможными приватность и работу в изолированной среде. Обязательной телеметрии нет, а исходящий трафик управляющей плоскости по умолчанию отсутствует. За периметр заказчика выходит только то, что сам заказчик настроил для передачи наружу: обращения к API его моделей, подключённые им выходы SIEM/webhook и внешний поставщик эмбеддингов, если заказчик его настроил.

По умолчанию. Один статический бинарный файл Go несёт движок CLI, веб-UI, встроенный через go:embed (раздаваемый с того же origin, что и API), и SQLite в качестве хранилища. Вы поставляете один артефакт и самостоятельно его размещаете. Это та топология, что стоит за туториалом zero-to-graph и руководством по самостоятельному размещению.

Для многохостовых, масштабируемых и многоарендных владений: коллекторы на краю пушат в центральное ядро через gRPC со взаимным TLS, хранилище становится Postgres (с защитой на уровне строк), а шина событий работает на NATS. У коллекторов нет входящего слушателя — они пушат, а не обслуживают, — что удерживает поверхность атаки на краю минимальной.

В этой топологии всё работает локально с нулевым исходящим трафиком: хранилище локальное, лицензия валидируется офлайн. olivares upgrade — единственная команда, которая иначе обратилась бы к нам, — здесь устанавливает из перенесённого бандла (--bundle), а не из канала обновлений. См. установку в изолированной среде.

Размещённый управляющий слой есть в дорожной карте. Но даже тогда ограничение сохраняется: коллекторы по-прежнему работают на инфраструктуре заказчика, и размещён только управляющий слой. Это на стадии проектирования.

Две границы формируют архитектуру помимо топологии времени выполнения:

  • Граница коннектора. Коннектор никогда не импортирует из ядра — он зависит только от SDK. Это не даёт сторонним коннекторам загрязнять ядро и сохраняет границу лицензии чистой.
  • Граница лицензии. Ядро, модули и веб распространяются под AGPL-3.0-only; SDK и коннекторы — под Apache-2.0; корпоративный уровень коммерческий. Граница коннектора, описанная выше, и есть то, что делает разделение Apache/AGPL принудительно исполнимым в коде. См. open core и лицензирование.

Архитектура безопасна по дизайну: наблюдение read-first (низкий, асимметричный риск), коллекторы только-на-пуш без входящего слушателя, взаимный TLS между коллектором и ядром, минимум данных (рёбра, никогда полезные данные), доказуемость подделки через журнал только-на-добавление, скреплённый хэш-цепочкой, многоарендная изоляция, укоренённая в модели данных, и самостоятельное размещение без обязательной телеметрии и без исходящего трафика управляющей плоскости по умолчанию. За периметр заказчика выходит только то, что сам заказчик настроил для передачи наружу: обращения к API его моделей, подключённые им выходы SIEM/webhook и внешний поставщик эмбеддингов, если заказчик его настроил. Полный анализ — включая то, как защищается каждая граница доверия и что явно вне области охвата — живёт в модели безопасности и модели угроз.