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

Сборка и поставка коннектора

Это руководство проведёт вас от нуля до подписанного стороннего коннектора, который оператор может подключить к control plane. SDK коннекторов распространяется под Apache-2.0 и ничего не импортирует из движка под AGPL, поэтому ваш коннектор — это ваш код под вашей лицензией, собранный в вашем репозитории.

То, что вы собираете, — обычная Go-программа: тип, реализующий sdk.SourceConnector (собирает факты, выдаёт наблюдения), sdk.OutputConnector (доставляет уведомления) или sdk.ContentSource (предоставляет документы и ссылки ACL управляемой базе знаний), упакованный как бинарник go-plugin, который движок запускает вне процесса и с которым общается по gRPC (взаимно аутентифицированный loopback, AutoMTLS). Сначала прочитайте подключение источника, чтобы понять модель коннектора — только наблюдение, минимальные данные, три вида наблюдений.

Предпочтительный интерфейс командной строки:

Окно терминала
# from the repository checkout root
go run ./cmd/olivares connector init acme.widget-audit \
--dir ~/olivares-connector-widget \
--module github.com/acme/olivares-connector-widget \
--template access-edge-source \
--plugin \
--sdk-path "$PWD/sdk"

Выберите один из пяти архетипов. Это преднастроенные варианты стабильных поверхностей SDK, а не новые контракты для авторов:

ШаблонОбъявленные поверхностиКогда использовать
content-sourceknowledge.documentДокументы для управляемого ingest знаний, включая внепроцессные источники содержимого.
access-edge-sourceobservation.edgeФакты об отношениях в графе доступа, идентичностях, SaaS и инфраструктуре.
output-sinknotify.sinkПолучатели уведомлений или заявок.
agent-surfaceobservation.edge, observation.findingАдаптеры runtime агентов, сообщающие рёбра доступа и находки.
model-providerobservation.cost, observation.edgeНаблюдения инвентаря, использования и стоимости провайдера; управление моделями остаётся в движке.

Старый отдельный генератор каркаса остаётся действительным и создаёт те же стабильные контракты для авторов:

Запустите это из checkout репозитория (пока не опубликованы первые публичные теги SDK, пакет разрешается через workspace, а -sdk-path указывает на sdk/ того checkout):

Окно терминала
# from the repository checkout root
go run ./sdk/scaffold/cmd/olivares-connector-new \
-dir ~/olivares-connector-widget \
-name acme.widget-audit \
-module github.com/acme/olivares-connector-widget \
-kind source -plugin \
-sdk-path "$PWD/sdk"

Вы получаете полноценный репозиторий: скелет коннектора, тест жизненного цикла, плагинный main, README со всем этим жизненным циклом и scripts/check-boundary.shту же проверку границы лицензии, что выполняет наш CI, но для вашего. -name — это ваш Descriptor.Name: глобально уникальный, с точками, <vendor>.<connector>.

Контракт вкратце (godoc на sdk.SourceConnector нормативен):

  • Open читает конфигурацию (объявленную в вашем Descriptor.ConfigFields; секреты — это ссылки, помеченные Secret: true, никогда не встраиваемые напрямую). Падайте здесь, а не в Gather.
  • Gather выдаёт наблюдения в Sink движка. Планированием владеет движок: пакетный источник делает свою работу и возвращает управление; потоковый источник блокируется до тех пор, пока не отменён ctx. Никогда не заводите собственный тикер.
  • Доставка осуществляется как минимум однократно; потребители выполняют дедупликацию по естественному ключу наблюдения. Не отслеживайте состояние доставки.
  • Минимальные данные: выдавайте ссылки и метаданные, никогда не полезную нагрузку, промпты или значения секретов.
  • Для content-source метод List возвращает ссылки, перечисление которых достаточно дёшево, Fetch возвращает тело одного документа, а опциональный DeltaContentSource добавляет живые изменения и обновление ACL. Плагины источников содержимого с этим опциональным интерфейсом автоматически объявляют content.delta; хосты не вызывают методы изменений, если эта возможность не объявлена.

Запустите свои тесты, затем докажите границу лицензии в своём CI:

Окно терминала
go test ./...
./scripts/check-boundary.sh # fails if anything links github.com/olivaresai/olivares/core

Соберите бинарник плагина, закрепите его digest и приложите аттестацию цепочки поставок как Sigstore-бандл. Control plane проверяет происхождение SLSA или аттестации SBOM (предикаты SPDX / CycloneDX) — подпишите собственным ключом (показано здесь) или keyless с идентичностью вашего CI:

Окно терминала
go build -trimpath -o widget-audit ./cmd/acme-widget-audit
sha256sum widget-audit
# keyed (the dev loop: trust your own public key)
cosign generate-key-pair
cosign attest-blob --key cosign.key \
--type slsaprovenance1 --predicate provenance.json \
--bundle widget-audit.sigstore.json widget-audit
# keyless alternative (CI): same command with --yes and an OIDC identity,
# or GitHub artifact attestations (gh attestation download produces the bundle).

Опубликуйте релиз на GitHub с бинарником, его sha256 и бандлом .sigstore.json — или отправьте те же артефакты в OCI-реестр командой oras push (аттестация как referrer). Версионируйте по semver; объявите ProtocolVersion, под который вы собирали (сегодня v1), в своём README.

5. Эксплуатация (что делают ваши пользователи)

Заголовок раздела «5. Эксплуатация (что делают ваши пользователи)»

Оператор размещает бинарник и бандл на хосте и закрепляет и digest, и доверие в конфигурации источников (OLIVARES_SOURCES_CONFIG):

{
"connector_trust": {
"trusted_keys": ["-----BEGIN PUBLIC KEY-----\n…acme's cosign.pub…\n-----END PUBLIC KEY-----\n"],
"allowed_predicates": ["https://slsa.dev/provenance/v1"]
},
"sources": [
{
"name": "widget-prod",
"tenant": "<tenant-id>",
"config": { "endpoint_ref": "" },
"plugin": {
"path": "/opt/olivares/plugins/widget-audit",
"sha256": "<the released digest>",
"bundle": "/opt/olivares/plugins/widget-audit.sigstore.json"
}
}
]
}

Допуск работает по принципу deny-closed, без лазеек: отсутствие якорей доверия, отсутствие бандла, несовпадение digest, недоверенный подписант или неверный тип предиката — всё это означает, что источник не подключён (загрузка сообщает почему). При успехе движок повторно хеширует бинарник при exec (go-plugin SecureConfig), так что проверенные байты — это исполняемые байты, а канал подпроцесса закреплён через AutoMTLS.

Плагины источников содержимого используют тот же корневой connector_trust и ту же форму plugin { path, sha256, bundle } для каждого источника в блоке конфигурации documents. Это полноценные внепроцессные источники содержимого для ingest знаний.

Якорь доверия обязателенconnector_trust без trusted_roots и без trusted_keys отвергается напрямую. Для keyless-подписи якорем является корень Fulcio (или приватного CA), поэтому оператор задаёт trusted_roots (корневой PEM, например из cosign initialize) плюс allowed_identities и allowed_issuers (оба, вместе — идентичность SAN и OIDC-issuer, которые должна нести подпись); заменяется только trusted_keys. Приведённый выше пример с «голым» ключом — самый простой якорь.

6. Получите сертификацию (опционально, но рекомендуется)

Заголовок раздела «6. Получите сертификацию (опционально, но рекомендуется)»

Две взаимодополняющие записи:

  • Сертификация в продукте — ваши пользователи курируют ваш коннектор как запись каталога (вид connector, модуль XIV) и фиксируют проверенный вердикт допуска по происхождению/SBOM против вашего выпущенного digest (POST /entries/{id}/admit); при включённом require_signed одобрение работает по принципу deny-closed по этому вердикту. См. модуль XIV.
  • Индекс проверенных коннекторов — отправьте свой коннектор для включения в список на Проверенные коннекторы: сопровождающие повторно проверяют ваш релиз (границу, подпись, происхождение, ревью минимальности данных) и вносят его в список. Индекс документирует проверку; он не является корнем доверия — операторы всё равно сами закрепляют вашу идентичность/ключ.

Принуждение по построению выполняется в движке: коннекторы не линкуют код управления и не могут от него отказаться. Движок привязывает средства контроля к настроенной идентичности источника (source_type, source_ref), применяет область источника, пересечение ACL, DLP/сканирование при извлечении, допуск и аудит, а Descriptor.Surfaces рассматривает только как рекомендательные метаданные — никогда как вход для принуждения.

Частные коннекторы — полноценный вариант. Можно хранить коннектор внутри организации, никогда не публиковать его и не вносить в открытые списки; он всё равно управляется, когда оператор закрепляет digest бинарника и корень доверия. Индекс проверенных коннекторов документирует сертификацию; он не является корнем доверия.

  • Внешнее подключение охватывает источники наблюдений и источники содержимого; output-коннектор собирается и поставляется идентично, но композиция уведомлений пока не загружает внешние output-плагины.
  • Внепроцессные модули недоступны (прото заморожен, host-связка намеренно не подключена).
  • Сумма-тип наблюдений запечатан: вы выдаёте рёбра, образцы стоимости и находки — с открытыми строковыми словарями — но не можете определять новые виды наблюдений.