presentedcred

package
v0.2.0 Latest Latest
Warning

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

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

Documentation

Overview

Package presentedcred — читатель удостоверения, ПРЕДЪЯВЛЕННОГО самим вызывающим, на публичном слушателе (задача продукта #2077, приёмка KAN-AUTHN-1).

Зачем он существует

Личность на публичном слушателе производилась ровно двумя способами, и оба предполагают НАШУ инфраструктуру рядом: клиентский сертификат проверенного пира и личность, переданная разрешённым отправителем. В чужом облаке нет ни нашего края, чтобы передать, ни модульного сертификата у человека — арендатору нечем назваться. Этот читатель и есть третий способ: арендатор приходит обычным клиентом и предъявляет то, что мы сами ему выдали.

Внешней зависимости у проверки нет ПО ПОСТРОЕНИЮ

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

Отзыв читается НА ПРЕДЪЯВЛЕНИИ

Контроль, действующий на выдаче и не действующий на предъявлении, отзывом не является: он лишь не выдаёт нового, а предъявленное продолжает проходить до истечения срока. Это состояние НЕ СХОДИТСЯ САМО, и окно отзыва равнялось бы сроку токена, а не сроку, который мы выбрали. Здесь окно задаёт срок кеша положительного вердикта — величина ОПЕРАТОРА, объявленная им и видимая ему.

Отрицательный вердикт не кешируется: восстановленный доступ не ждёт истечения записи.

Отказ ОДИН

Все отказы аутентификации побайтово одинаковы, включая приложенные к ответу подробности. Различимый отказ здесь есть ОРАКУЛ: он сообщает предъявителю, какая половина предъявленного неверна. Поэтому производитель отказа в пакете ровно один — тринадцать вызовов `status.Error` по месту разошлись бы на первой же правке текста, и разошлись бы молча.

Подробность — какая именно проверка не сошлась — уходит ОПЕРАТОРУ, в журнал и измерители его установки, и никогда предъявителю.

Index

Constants

View Source
const MetadataKey = "authorization"

MetadataKey — ключ метаданных, которым удостоверение предъявляется.

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

View Source
const RefusalMessage = "credential is not accepted"

RefusalMessage — ЕДИНСТВЕННЫЙ текст отказа аутентификации.

Он не называет ни причины, ни поля, ни значения: предъявитель не обязан узнать, какая половина предъявленного неверна. Текст — часть контракта, и экспортирован затем, чтобы проба утверждала ЕГО, а не свою копию.

Variables

View Source
var (
	// ErrIssuerRequired — незаданный издатель означает «любой», то есть токен
	// любого происхождения принимался бы как наш.
	ErrIssuerRequired = errors.New("presentedcred: the issuer we accept as our own is not declared")
	// ErrAudienceRequired — незаданный адресат означает «любой»: токен, годный
	// для другой поверхности, проходил бы здесь.
	ErrAudienceRequired = errors.New("presentedcred: the audience of this listener is not declared")
	// ErrAlgorithmsRequired — пустой перечень означает «принимаем любую
	// подпись», и на этом перечне держится сверка заголовка с ключом.
	ErrAlgorithmsRequired = errors.New("presentedcred: the list of accepted signatures has no elements")
	// ErrAlgorithmUnknown — алгоритм вне закрытого словаря платформы.
	ErrAlgorithmUnknown = errors.New("presentedcred: accepted signature list names an algorithm outside the platform dictionary")
	// ErrKeysRequired — без собственного реестра ключей проверять подпись нечем.
	ErrKeysRequired = errors.New("presentedcred: no key registry is wired")
	// ErrRevocationsRequired — без авторитета отзыва контроль действовал бы
	// только на выдаче.
	ErrRevocationsRequired = errors.New("presentedcred: no revocation authority is wired")
	// ErrCacheTTLRequired — срок кеша И ЕСТЬ окно отзыва. Величина, которую
	// построение подставляет молча, предметом стража быть не может.
	ErrCacheTTLRequired = errors.New("presentedcred: the revocation cache lifetime is not declared")
)

Отказы ПОСТРОЕНИЯ. Каждый отдельный: неполная настройка означает читателя, который либо принимает лишнее, либо не принимает ничего, — и узналось бы это на первом запросе.

Functions

func Presented

func Presented(ctx context.Context) bool

Presented отвечает, приложил ли вызывающий удостоверение к ЭТОМУ запросу.

Зачем это спрашивают снаружи

Звено, решающее ЧТО ОТВЕТИТЬ не назвавшемуся, обязано отличать «не предъявлял вовсе» от «предъявил, и не сошлось»: первому отвечают «назовись», второму — единственным побайтово равным отказом. Различие есть свойство ЗАПРОСА, и узнаётся оно ровно здесь.

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

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

Неоднозначность (два предъявления разом) считается предъявлением: вызывающий приложил удостоверение, а то, что их два, — уже вопрос годности, и отвечает на него отказ читателя, а не этот предикат.

Types

type Config

type Config struct {
	// Issuer — издатель, которым установка объявила СЕБЯ.
	Issuer string
	// Audience — адресат ЭТОЙ поверхности. Токен, выданный для другой,
	// здесь не годится: тип и адресат — свойства поверхности предъявления.
	Audience string
	// AllowedAlgorithms — перечень принимаемых подписей, ОБЪЯВЛЕННЫЙ
	// установкой. Решение принимается по нему, а не по тому, что заявлено в
	// самом токене.
	AllowedAlgorithms []string
	// Keys — собственный реестр ключей.
	Keys KeySetSource
	// Revocations — авторитет отзыва.
	Revocations RevocationReader
	// RevocationCacheTTL — срок кеша ПОЛОЖИТЕЛЬНОГО вердикта, он же
	// объявленное окно отзыва.
	RevocationCacheTTL time.Duration
	// Clock — источник времени. Передаётся, а не берётся из окружения: без
	// этого обе половины окна отзыва наблюдаются выжиданием, а не
	// детерминированно.
	Clock func() time.Time
	// Logger — журнал ОПЕРАТОРА: сюда уходит причина отказа, которой нет в
	// ответе предъявителю.
	Logger *slog.Logger
	// TrustDomain — домен доверия установки: по нему опознаётся личность модуля
	// из сертификата пира. Приезжает величиной, а не берётся из сборки: пока он
	// был скомпилирован, установка меняла его только пересборкой, и правка
	// величины профиля давала сертификаты, которых эта сторона не признавала.
	//
	// Необъявленный домен — не отказ построения: читатель предъявленного
	// удостоверения работает и там, где личности модуля нет вовсе (внешний
	// клиент). Он лишь не опознаёт НИКОГО, и это фейл-клоуз. Отказ старта —
	// предмет стражи посадки, а не этого конструктора.
	TrustDomain grpcsrv.TrustDomain
}

Config — настройка читателя. Каждое поле ОБЯЗАТЕЛЬНО: незаданное здесь означает «не сужаем», а не «взять разумное».

type KeySetSource

type KeySetSource interface {
	PublishedSet(ctx context.Context) ([]domain.PublishedKey, error)
}

KeySetSource — источник публикуемого набора.

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

type Reader

type Reader struct {
	// contains filtered or unexported fields
}

Reader — читатель предъявленного удостоверения.

func New

func New(cfg Config) (*Reader, error)

New строит читателя. Неполная настройка — ОТКАЗ ПОСТРОЕНИЯ, а не умолчание.

Асимметрия цены, из которой это выведено: слишком строгая настройка даёт отказ В СТАРТЕ — видимый сразу, с именем настройки в тексте; слишком слабая даёт принимаемый чужой токен, не видимый никогда.

func (*Reader) DeclaredChecks

func (r *Reader) DeclaredChecks() []tokenpolicy.Check

DeclaredChecks — состав проверок ЭТОГО проверяющего.

Объявление существует затем, чтобы его можно было СВЕРИТЬ с единым перечнем, а не читать реализацию глазами. Запись, которой проверяющий не исполняет, отсюда нельзя: тогда объявление станет вторым местом об одном предмете, и разойдётся оно молча.

func (*Reader) DeclaredDeviations

func (r *Reader) DeclaredDeviations() []tokenpolicy.Deviation

DeclaredDeviations — обязательные проверки, которых читатель НЕ исполняет.

Перечень ПУСТ, и пуст осознанно: адресат и тип объявлены отступлением у авторитета отзыва, потому что он судит о состоянии токена У ИЗДАТЕЛЯ. Здесь поверхность предъявления и есть та, чьими свойствами адресат и тип являются, — отступления быть не может.

func (*Reader) Stats

func (r *Reader) Stats() Stats

Stats возвращает величины по исходам.

func (*Reader) StreamOver

StreamOver — то же на второй полосе.

Стримовых RPC у службы сегодня ноль, и полоса провязывается не ради них: полоса без читателя при полосе с читателем — различие, которого никто не принимал, и обнаружилось бы оно первым же стримовым RPC.

func (*Reader) UnaryOver

UnaryOver ставит читателя НАД парой извлечения личности, а не после неё.

Почему НАД, а не после — это не стиль, а единственная работающая форма

Пара извлечения на двух ветках из трёх снимает носитель личности явным снятием, и снятие имеет ПРИОРИТЕТ над любым последующим назначением: так устроен носитель платформы, и устроен намеренно — подделанная личность от непроверенного пира не должна просачиваться никаким «а потом мы её вернём». Читатель, поставленный ПОСЛЕ пары, назначил бы вызывающего, и назначение молча не доехало бы до обработчика: отказа нет, личности нет, а дальше отсечка анонима отвергает мутацию — по причине, которой в запросе не было.

Поэтому читатель прогоняет пару САМ и решает по её вердикту: полосы взаимно исключают друг друга (ось 8 решения), и решение о том, КТО звонит, принимается в одном месте, а не складывается из двух назначений.

Прежний путь при этом не тронут

Запроса БЕЗ предъявленного удостоверения читатель не касается вовсе: пара исполняется как исполнялась, и её ветки — доверенный отправитель, непроверенный пир, проверенный без переданной личности — работают ровно как прежде.

type RevocationReader

type RevocationReader = tokenrevocation.Reader

RevocationReader — хранилище отсечек отзыва.

type Stats

type Stats struct {
	Accepted    uint64
	Refused     uint64
	Unavailable uint64
}

Stats — величины по каждому исходу.

Отдаются СНИМКОМ, а не через порт наблюдателя: измерители читают их сами, и все три ряда печатаются всегда, включая нулевые. Ряд, появляющийся только вместе с первым событием, делает ноль невыразимым — отсутствующий ряд и нулевой выглядят одинаково у того, кто смотрит на график.

Jump to

Keyboard shortcuts

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