kaname

command
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2026 License: AGPL-3.0 Imports: 103 Imported by: 0

Documentation

Overview

audit_shipper_wiring.go — ВЫВОЗ журнала аудита control-plane.

Что здесь появилось

Приёмник. До него журнал писался четырьмя местами и не читался никем: строки копились с первого дня стенда, и «ноль доставленных за всю жизнь очереди» было верным описанием. Решение о том, ЧТО считать приёмником и почему им стал поток структурных записей службы, живёт в пакете `pkg/audit` — здесь оно не пересказывается, чтобы два места об одном предмете не разошлись.

Почему вывоз, а не общий дренаж

Общая оснастка дренажа доставляет НАМЕРЕНИЕ: пару «вид события + полезная нагрузка», отобранную из строки. Запись журнала — это строка ЦЕЛИКОМ: актор, второе лицо, предмет, область, арендатор. Доставленная через отбор, она приехала бы без того, ради чего журнал существует. Плюс идентификатор записи журнала — текстовый (`evt_…`), а клейм общего дренажа читает его целым числом, то есть эта очередь ему не адресуема вовсе.

bootstrap_token.go — сборка контура бутстрап-удостоверения (задача #1119, Ф4б эпика #896).

Почему отдельный файл композиционного корня

Контур собирает три части, и у каждой свой отказ: строка соответствия бутстрап-клиента, состав утверждений и НАШ подписант. Собранные в теле общего пуска, они растворяются среди двух десятков соседних провязок, и первая же неполная из них проходит обзор незамеченной.

Что здесь ГЛАВНОЕ

Ни одного поля, называющего внешнего поставщика. Бутстрап — единственное удостоверение, которым кластер поднимают с нуля, и после этой сборки свежий клон получает его, не дожидаясь, пока чужая сторона поднимется и узнает наш ключ.

catalog_snapshot_wiring.go — период, с которым снимок каталога перечитывает живые строки (kacho#1945).

Что этот период ЗНАЧИТ для арендатора

Это не настройка производительности, а ОБЪЯВЛЕННОЕ ОКНО: сколько времени снятый модуль продолжает приниматься правилом роли на пути запроса. После #1927 членство модуля отвечают строки `catalog_module`, но путь запроса читает их не по одной на запрос, а через снимок — иначе каждая проверка правила стала бы обращением к базе. Цена снимка — ограниченное отставание, и величина отставания есть эта ручка.

Почему ручка, а не константа

Соседние фоновые замеры держат период константой, и там это верно: их отставание не наблюдаемо арендатором. Здесь наблюдаемо — окном, в котором снятое право ещё действует, — а величину, которую видит оператор, за него не решают.

«Никогда» этой ручкой НЕВЫРАЗИМО, и это построение, а не запрет

`envDurationMS` возвращает умолчание на любом непозитивном и неразбираемом значении. Поэтому нуля петля не получает ни при какой посадке, и отдельного стража старта у величины нет: его предметом было бы состояние, которого не бывает. Незаданная ручка означает умолчание ниже, а НЕ «не обновлять» — различие несущее: пустое значение здесь пришлось бы читать как «не сужаем», то есть в опасную сторону.

client_token.go — приземление токен-эндпоинта платформы на живой путь выдачи (задача #898, приёмка F2 §9.1 п. 11).

Почему это отдельный файл композиционного корня

Эндпоинт собирает четыре части, и у каждой свой отказ: проверяющий утверждение, реестр, способный к утверждению, хранилище однократности и выдача нашим подписантом. Собранные в теле общего пуска, они растворяются среди двух десятков соседних провязок, и первая же неполная из них проходит обзор незамеченной.

Что здесь ГЛАВНОЕ

Эндпоинт получает ПРОИЗВОДСТВЕННОГО вызывающего. Проверяющий без него выглядит исправным ровно потому, что его пробы зелены: они подают ему то, что он умеет разобрать. Живой путь подаёт то, что присылает клиент.

env.go — env-driven helper used by the composition root.

Здесь стоял выбор поставщика решения о доступе, сборка клиента внешнего движка отношений, его сроки на операцию и перевод исходов его попыток в наблюдаемое. Ничего из этого нет: поставщик один и он не внешний — решение вычисляет реляционная форма в собственной базе службы, и «выбор адаптера» перестал быть вопросом, а не сменил умолчание.

grpc_register.go — registration of gRPC handlers onto public / internal servers. Pure wiring: no business logic, no env reads.

hooks_mux.go — HTTP mux composition for AuthN hooks listener. Hydra hooks (token + refresh), DPoP replay cache.

httpedgetls.go — HTTP-рёбра службы в боевой посадке обязаны нести TLS.

Предмет, и он появился ВМЕСТЕ С ВЫНОСОМ

Ручки транспорта у трёх HTTP-рёбер — вебхуки провайдера, скрейп и зеркало ключей проверки — объявлены кодом давно, но задавал их ЗОНТИЧНЫЙ чарт монорепо. Профиль ЭТОЙ службы их не объявляет, а адреса всех трёх приходят умолчанием процесса и потому непусты всегда: отдельно поставленная служба поднимала три слушателя ОТКРЫТЫМ ТЕКСТОМ, и заметить это было неоткуда — умолчание `Enable=false` означает «открытый текст», а не «выключено».

Цена каждого ребра названа отдельно, потому что она разная:

  • ВЕБХУКИ. По проводу идёт общий секрет провайдера — тот самый, которым обработчик отличает провайдера от постороннего. Снятый с провода, он позволяет звать заведение пользователя и обогащение токена от чужого имени;
  • ЗЕРКАЛО КЛЮЧЕЙ. Снятие аутентификации с этой поверхности — задокументированное исключение, и обосновано оно ТРЕМЯ вещами разом: внутренний Service, односторонняя TLS, только публичный материал. Без TLS предпосылка собственного исключения ложна: остаётся неаутентифицированный слушатель открытым текстом, чьи ключи плоскость данных реестра принимает как решающие, чью подпись верить;
  • СКРЕЙП. Счётчики процесса — внутренняя кардинальность, которую `security.md` держит вне публичной поверхности; открытый текст выносит её всякому, кто слушает сеть пода.

Почему у докерной полосы страж СВОЙ, а не эта функция

`requireRegistryTokenTLS` отказывает своим текстом, и текст этот несущий: по той ноге едет ПРИВАТНЫЙ КЛЮЧ ключа служебной учётки, у которого нет ни срока, ни ротации, — ущерб не ограничен ничем, в отличие от короткоживущего предъявителя. Свести обе функции значило бы либо потерять этот довод, либо повторить его здесь вторым местом об одном предмете. Отдельный страж с отдельной причиной — решение, а не дрейф.

Отказ называет ВСЕ рёбра сразу

Оператор чинит профиль один раз, а не по одному ребру за перезапуск: страж, останавливающийся на первом, продаёт три круга подъёма вместо одного.

ОБЪЯВЛЕННОЕ ИСКЛЮЧЕНИЕ — одно, и его область сужена ПОСТРОЕНИЕМ

У слушателя вебхуков открытый текст возможен, и основание у этого измерено, а не выведено: вызывающий ходит по открытому http и своего доверия не несёт, поэтому TLS здесь означал бы не защиту, а проваленный хук и неработающую выдачу токенов целиком.

Исключение обязано быть ОБЪЯВЛЕНО посадкой — умолчания у него нет: величина, которую построение подставляет само, предметом стража быть не может, он зелен при любом входе. И оно ЕДИНСТВЕННОЕ: у остальных рёбер ручки исключения нет ни в чарте, ни в описателе настроек, поэтому объявить им открытый текст нечем. Область сужена до одного слушателя построением, а не дисциплиной оператора.

Ребро, у которого транспорт объявлен И объявлено исключение из него, — ОТКАЗ: два правила об одном предмете говорят противоположное, и выбирать между ними молча процесс не вправе.

httpsurfaces.go — ОБЩАЯ ЧАСТЬ объявлений четырёх не-gRPC поверхностей iam.

Что здесь общее, а что нет — и почему граница именно такая

Общее — СРОКИ и имя процесса: они одинаковы у всех четырёх и были выписаны по месту четыре раза, то есть держались тем, что автор написал те же числа. Разъехавшиеся числа читались бы как осознанная разница, которой нет.

НЕ общее — имя поверхности, адрес, досягаемость, решение об аутентификации и транспорт. Их сводить нельзя: именно ими четыре поверхности и отличаются, и пара «досягаемость × аутентификация» — единственное, что профиль судит по существу. Помощник, подставляющий сюда умолчание, вернул бы решение о доступе, принятое никем.

identity_growth_wiring.go — фоновый замер НАКОПИТЕЛЬНОГО журнала личностей.

Что производит продукт и чего он не производит

Продукт производит СОБЫТИЯ: личность появилась, приглашение активировано. «Личностей за всё время N, из них M за последний час» — это СОСТОЯНИЕ, и его не производит никто, кроме периодического чтения журнала. Без него медленное накопление неотличимо от его отсутствия: обе картины молчат одинаково.

Что этот замер НЕ делает

Не мутирует таблицу, не участвует в пути запроса и не может уронить под: отказ чтения считается своей клеткой и цикл продолжается. Наблюдаемость — не гейт.

internalrestclientauth.go — внутренний REST-фронт в боевой посадке обязан требовать проверенного клиентского сертификата.

Предмет: рубеж у этой поверхности бывает ТОЛЬКО транспортный

Мультиплексор внутреннего фронта своего рубежа не заводит — это записано в его собственном объявлении и верно: сужающий сопоставитель заголовков не пропускает внутрь НИ ОДНОГО заголовка запроса, а к собственному gRPC-слушателю фронт идёт СВОИМ удостоверением. Значит о том, кто позвонил по HTTP, ниже по стеку не знает никто: слушатель судит сертификат ФРОНТА, а не вызывающего.

Отсюда следствие, ради которого этот страж и заведён: место, где решается «кому вообще позволено дотянуться до этой поверхности», у неё РОВНО ОДНО — рукопожатие. Односторонний транспорт оставляет этот вопрос без решателя, оставаясь на вид настроенным: шифрование есть, аутентификация сервера есть, вызывающий не назван ничем.

Почему довод публичного фронта сюда НЕ переносится

У публичного фронта односторонний режим верен и обоснован: до него дотягивается арендатор обычным HTTP-клиентом, клиентского сертификата он не носит, и требование предъявить его отвергло бы КАЖДОГО на рукопожатии. Вызывающего там называет предъявленное удостоверение, которое проверяет звено собственного слушателя.

У внутреннего фронта вызывающие — МОДУЛИ, называющиеся сертификатом (так сказано в объявлении самого фронта, и это его отличие от публичного). Довод «клиентского сертификата не носят» о них ложен, а предъявленное удостоверение внутренний слушатель не читает вовсе — его цепочка личности состоит из сертификата пира и переданной разрешённым отправителем личности. То есть перенесённый сюда довод не просто слаб: у него нет ни одной верной половины.

Почему запрашивающий режим не годится

`optional-mutual` сертификат ЗАПРАШИВАЕТ и проверяет, если предъявлен, но соединение без него пропускает. Сужает при таком режиме обработчик, который проверенного пира требует сам, — а у этой поверхности такого обработчика нет by construction (см. выше). Значит запрашивающий режим оставил бы ровно прежнее положение дел, добавив к нему вид настроенности.

Ручки исключения здесь НЕТ, и это область, а не недоделка

Исключение объявляют там, где у него есть предмет: у слушателя обратных вызовов провайдера личности он измерен — вызывающий ходит открытым текстом и своего доверия не несёт. Здесь предмета нет: всякий законный вызывающий этой поверхности — модуль с листом внутреннего удостоверяющего центра, а тот же центр уже подписывает материал, который профиль монтирует поду. Ручка без предмета есть заранее выданная слепая зона: следующая настоящая находка уехала бы под неё незамеченной.

Что этот страж НЕ утверждает

Он говорит о РУКОПОЖАТИИ и только о нём: кто вправе дотянуться до поверхности. О том, что происходит с запросом дальше — чьей личностью фронт представляется собственному слушателю и что решает пер-RPC политика вызывающего, — он не утверждает ничего, и это отдельный предмет.

invite_mail_wiring.go — дренаж очереди писем приглашения, возврат отравленных строк и наблюдаемость этой очереди.

Основание: приёмка sub-phase-ID-MAIL-1-mail-delivery-acceptance.md, Р23 и Р25; объём §10 пп. 20–21, порядок §11 шаг 8а.

ДВЕ ВЕЛИЧИНЫ ЖИВУТ В РАЗНЫХ МЕСТАХ, И ЭТО НЕ СЛУЧАЙНОСТЬ

Предел времени на ПОПЫТКУ принадлежит ОТПРАВИТЕЛЮ: он ограничивает один разговор с почтовым узлом и наблюдаем только на узле, который соединение принял и молчит. Число ПОВТОРОВ принадлежит ДРЕНАЖУ: оно ограничивает, сколько раз строка будет предъявлена отправителю. Величины разные, предметы разные, и подменять одну другой нельзя ни в какую сторону — «ограниченный повтор» без предела попытки ограничивает число попыток, каждая из которых вправе висеть вечно (`architecture.md` §«Per-call deadline на КАЖДОМ внешнем вызове»).

ТЕРПЕНИЕ ДРЕНАЖА БОЛЬШЕ ПРЕДЕЛА ПОПЫТКИ, И ЭТО ТРЕБОВАНИЕ

Если бы `ApplyTimeout` был меньше предела попытки, разговор обрывал бы ВСЕГДА дренаж, и предел отправителя не фигурировал бы ни в одном исходе — то есть величина была бы объявлена и не исполнялась бы никогда. Поэтому терпение выводится ИЗ предела попытки, а не назначается рядом с ним: два независимо выбранных числа разошлись бы молча.

Package main — single-purpose binary `kaname`. Этот binary обслуживает только `serve` (gRPC API + internal endpoint); миграции — отдельный binary `cmd/migrator` (cobra-based).

Thin entry-point. Responsibilities кратко: загрузить config, выбрать subcommand (только `serve` поддерживается), передать управление в runServe (см. serve.go). Все реальное wiring живет в:

  • serve.go — lifecycle (pools, listeners, parallel.ExecAbstract, shutdown)
  • wiring.go — composition (services struct + builders)
  • grpc_register.go — public/internal RPC registration
  • hooks_mux.go — HTTP hooks mux (Hydra token/refresh)
  • env.go — env-helpers (DSN mask, FGA timeouts)
  • listeners.go / governance_wiring.go / wiring.go — phase-specific wiring

outbox_metrics_wiring.go — сканеры СОСТОЯНИЯ очередей kaname.

Что производит дренаж и чего он не производит

Дренаж сообщает о СОБЫТИЯХ: строка применилась, строка отравилась, голова партиции висит дольше порога. Всё это уходит в лог. «В очереди лежит N строк, старейшей M секунд, из них K отравлено» — это СОСТОЯНИЕ, и его не производит никто, кроме периодического скана таблицы. Без него застрявшая очередь неотличима от пустой: обе молчат одинаково.

Почему именно эти две очереди и почему это не «на всякий случай»

`kaname.fga_outbox` — та самая очередь, через которую физически уходит КАЖДЫЙ отзыв прав: снятие привязки, удаление члена группы, delete-stale реконсайлера. Её собственная конфигурация дренажа подробно объясняет, почему запись и удаление одного tuple не коммутируют и чем грозит их перестановка — то есть утверждение о ПОРЯДКЕ там уже есть. Утверждения о ДОСТАВКЕ не было ни одного, и сводные величины его дать не могут: выдачи идут непрерывно, поэтому глубина мала и голова молода, что бы ни происходило со снятием. Различает их только `delivered_total{direction="withdrawal"}`.

`kaname.subject_change_outbox` доставляет инвалидацию кэша решений о доступе на шлюз. Недоставленная строка означает, что край продолжает отвечать по устаревшему вердикту — ровно тот эффект, ради предотвращения которого очередь и заведена. Разложение по направлению к ней не применяется; ПОЧЕМУ — сказано один раз в записи repohygiene.outboxDirectionSplitExempt, где перечень видов события машинно сверяется со словарём, закрытым миграцией. Здесь оно не пересказывается намеренно: пересказ того же вывода у соседней очереди уже пережил свой предмет и стал ложным, когда приехал второй вид события.

Что скан НЕ делает

Не мутирует таблицу, не участвует в пути запроса и не может уронить под: ошибки скана логируются и цикл продолжается. Наблюдаемость — не гейт.

ownfronthop.go — ЧЕМ собственный REST-фронт называется своему же слушателю, прочитанное из того сертификата, который он фактически предъявляет.

Предмет: величина обязана быть ТОЙ ЖЕ строкой, что увидит слушатель

Пер-RPC политика вызывающего сравнивает предъявленное имя целиком. Значит у величины есть ровно один правильный источник — клиентский лист фронта, — и ровно один правильный способ её из него достать: тот же отбор, которым имя извлекает слушатель (grpcsrv.TrustDomain.CertIdentity, первое имя URI в объявленном домене доверия).

Записанная второй раз — ручкой профиля, литералом в коде, образцом по соседям — она разошлась бы с проводом МОЛЧА: сертификат перевыпускается шаблоном чарта, а строка осталась бы прежней, и фронт снова начал бы получать отказ на каждом запросе. Именно так этот дефект и выглядел: обе стороны были защитимы порознь, неверен был их стык.

Почему домен доверия — АРГУМЕНТ

Домен объявляет установка, и вопрос «наше ли это имя» без него не задаётся. Спрашивается ТОТ ЖЕ домен, который слушатель предъявит разбору, — иначе две стороны сравнивали бы строки, признанные своими по разным правилам.

provider_compensation_wiring.go — дренаж очереди компенсаций частично исполненной саги «зарегистрировать OAuth-клиента у провайдера → закоммитить свою строку» + наблюдаемость этой очереди.

Почему это отдельный дренаж, а не ветка в fga_outbox: у той очереди другой предмет (наши tuple'ы), другой применитель и другой режим отказа. Общей у них остаётся МЕХАНИКА — corelib drainer: claim под FOR UPDATE SKIP LOCKED, at-least-once, backoff, poison-gate. Она переиспользуется, а не копируется.

provideradmincredential.go — административный контур к поставщику личности обязан нести ПАРУ: адрес и удостоверение, которым мы себя назовём.

Предмет: половина пары хуже отсутствия обеих

Контроль, обращающийся к соседу под своей личностью, объявлен настроенным ровно тогда, когда у него есть и адрес, и удостоверение. Объявить первое без второго значит завести контур, который отказывает ВСЕГДА и по одной и той же причине, — и отказывает молча: сосед отвечает «требуется предъявитель», наш клиент классифицирует это как невозможность получить ответ, и снаружи исправная служба выглядит недоступной.

Замер, из которого страж выведен (задача #2471): профилей, называющих АДРЕС административного контура, — шесть; профилей, объявляющих УДОСТОВЕРЕНИЕ к нему, — НОЛЬ. Ни один страж этой половины не судил вовсе.

Что этот страж судит, а что НЕТ — область названа, чтобы её не выводили

Он судит ПОЛОВИНУ ПАРЫ: оператор объявил, что контур возит предъявитель, а предъявитель не пришёл. Это состояние однозначно и чинится одним действием.

Он НЕ требует объявления как такового. Незаданная ручка означает «оператор не высказывался», и прежнее поведение (предъявитель не требуется) остаётся: потребовать высказывания здесь значило бы не пустить в старт каждый существующий стенд — то есть завести объявленную и неисполнимую посадку вместо той, которую чиним. Высказаться требует ЧАРТ, у которого есть, с кого спросить, и требование это чарт-местное: у зонтичного чарта своя полоса и свой владелец.

Почему неизвестное значение — отказ, а не «считаем, что не нужен»

Опечатка в значении ручки безопасности обязана останавливать старт: прочитанная как «не нужен», она даёт ровно то состояние, ради которого страж заведён, и выглядит при этом настроенной.

reconcile_outbox_metrics_wiring.go — скан СОСТОЯНИЯ очереди сверки прав (задача #2050, предикат 3).

Почему величины, а не строка журнала

Дренаж очереди сверки сообщает о СОБЫТИЯХ и делает это в лог: строка применилась, строка отказала, строка перешагнула порог. «В очереди лежит N строк, старейшей M секунд, из них K отравлено» — это СОСТОЯНИЕ, и его не производит никто, кроме периодического скана таблицы. Без него застрявшая очередь неотличима от пустой: обе молчат одинаково.

Для ЭТОЙ очереди вопрос острее, чем у соседей, и вот почему: отсечка у неё появилась вместе с учётом попыток (#2050). Строка, перешагнувшая порог, из клейма ВЫПАДАЕТ — то есть перестаёт и жаловаться. Величина `poisoned` — это единственное, что о ней говорит после того, как дренаж замолчал.

Предпосылка величин — у очереди ЕСТЬ доставка

Оба соседних скана были сняты, когда их очереди потеряли потребителя: возраст старейшей неотправленной на очереди без доставки растёт на ИСПРАВНОЙ службе, и тревога, которая звонит всегда, — это тревога, которую отключают первой. Здесь предпосылка держится: строки помечает отправленными живой дренаж (`seed.NewReconcileWorker` в `serve.go`), поэтому глубина падает, а возраст головы ограничен сверху.

Почему разложение по направлению ЗАДАНО, а не исключено

Очередь несёт ОБЕ половины, и у каждой есть производитель в прод-коде: `mirror.upsert` — материализация выдачи (17 мест), `mirror.delete` — снятие зеркала объекта, то есть НЕМЕДЛЕННЫЙ ОТЗЫВ. Сводные серии на такой очереди здоровы при полностью мёртвом снятии: выдачи идут непрерывно, поэтому глубина мала и голова молода, что бы ни происходило со второй половиной. «Работает» и «ни одного отзыва не доехало» дают ОДИНАКОВУЮ картину — различает их только разложение.

Словарь направлений повторяет словарь события ДОСЛОВНО, и это не совпадение: он закрыт ограничением применённой миграции (`resource_reconcile_outbox_event_valid`), а гейт дерева сверяет объявленное здесь с ним машинно. Второе написание разошлось бы молча.

retention.go — провязка фоновой уборки таблиц, чей рост задаёт внешний (задача #1292, приёмка `retention-sweep-has-a-caller.md`).

Предмет

Два уборщика по сроку были ОБЪЯВЛЕНЫ и не имели ни одного прод-вызывающего, у третьей таблицы уборщика не было вовсе. Восемь мест дерева при этом утверждали в настоящем времени, что сборщик работает: две строки применённой миграции, шапки двух методов, комментарий контракта, комментарий домена, шапка второй применённой миграции и записка архитектуры. Провязка делает все восемь истинными разом; впредь свойство держит гейт дерева `internal/repohygiene` `TestDeclaredRetentionSweepersHaveAProductionCaller`, а не этот комментарий.

Почему ОДНА петля на все предметы

Несколько петель — несколько расписаний об одном предмете, и они расходятся молча. Петля владеет реестром: добавление уборщика — одна запись, а не новая петля. Четвёртым предметом заведены окна темпа заведения аккаунтов (#1364), и добавление стоило ровно одной строки — ровно то, ради чего петля одна.

revocationauthority.go — авторитет отзыва НАШИХ токенов не выставляется на слушателе, который клиентского сертификата даже не запрашивает.

Предмет: обработчику, не имеющему чем отказать, отказывать нечем

Своя чеканка приносит с собой авторитет отзыва: поверхность, которой присылают предъявленный токен и которая отвечает, действует ли он ещё. Отзыв, читаемый только на выдаче, отзывом не является — предъявленное продолжало бы проходить до истечения срока, и это состояние не сходится само.

Авторитет обязан знать, КТО спрашивает. На слушателе, поднятом в режиме `server-tls-only`, сертификат не запрашивается вовсе, поэтому обработчик, требующий проверенного пира, не получает его НИ ПРИ КАКОМ входе: контроль присутствует, провязан, исполняется на каждом запросе — и не отказывает ни разу. Такая посадка не поднимается.

Почему обоснование, выданное НАБОРУ КЛЮЧЕЙ, сюда не переносится

С зеркала проверочных ключей аутентификация снята осознанно и задокументированно (security.md §AuthN+AuthZ ВЕЗДЕ): на проводе там только ПУБЛИЧНЫЙ материал, и спрашивать личность у того, кто пришёл за открытым ключом, незачем. Здесь по тому же проводу едет ПРЕДЪЯВЛЕННЫЙ ТОКЕН, и вопрос «кто спрашивает» — единственное, чем этот обработчик вообще располагает. Обоснование соседней поверхности того же слушателя на эту не распространяется, и перенесённое сюда оно ложно своей несущей половиной.

Почему запрашивающего режима ДОСТАТОЧНО, а взаимного не требуется

`optional-mutual` сертификат ЗАПРАШИВАЕТ и проверяет предъявленный, но соединение без него пропускает — и это здесь верно, потому что на ТОМ ЖЕ слушателе живёт набор проверочных ключей, который обязан оставаться доступным без сертификата: плоскость данных реестра ходит за ним, своего листа не имея. Взаимный режим отверг бы её на рукопожатии.

Сужает при запрашивающем режиме не транспорт, а обработчик, требующий проверенного пира сам, — и авторитет отзыва именно таков (`RequireClientCert: true` в его настройке). То есть пара «запрашивающий транспорт + требующий обработчик» и есть здесь полный рубеж, а не половина.

Почему это НЕ страж боевого режима

Условие не спрашивает посадку и спрашивать её не вправе: предмет приносит СВОЯ ЧЕКАНКА, а не выбор посадки. Стенд, включивший чеканку, получает ровно тот же отказ — и это верно: авторитет отзыва, не отказавший ни разу, вводит в заблуждение одинаково на любой посадке.

Что этот страж НЕ утверждает

Он говорит о РУКОПОЖАТИИ и только о нём: способен ли слушатель установить, кто пришёл. О том, кому именно позволено спрашивать об отзыве, решает обработчик, и это отдельный предмет.

serve.go — runServe: full lifecycle of the kaname binary. Wires pools → repos → services → gRPC servers + HTTP listeners + drainers, then runs them in parallel with a shared shutdown trigger driven by SIGTERM / SIGINT or any task error.

signing.go — сборка своей чеканки токенов в композиционном корне (задача #897).

Здесь и только здесь ключница, обёртка и подписант соединяются с конфигурацией: use-case знает порты, адаптеры знают базу, а кто с чем связан — решается один раз, в единственном месте сборки.

token_claims.go — ОДНА сборка состава утверждений для всех полос выдачи, чеканящих своим подписантом (задача #1119).

Почему это отдельная функция, а не по копии у каждой полосы

Полос, выпускающих токен НАШИМ подписантом, стало больше одной: токен-эндпоинт платформы и бутстрап-удостоверение. Пока сборка состава стоит по копии у каждой, различие между ними НЕ ЯВЛЯЕТСЯ НИЧЬЕЙ НАХОДКОЙ: оно не выражено и потому не может покраснеть, а разойдутся копии у ПРИНЦИПАЛА — чей токен выдан не той полосой.

wiring.go — composition-builder for the kaname service bundle. Holds the `services` struct (single composition point), buildServices (per-resource handler wiring), and buildAuthZServices (AuthorizeService), and the small adapter types they need.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL