Documentation
¶
Overview ¶
Package authzcascade — ДВЕРЬ РЕШЕНИЯ о доступе для собственных стражей iam.
───────────────────────────────────────────────────────────────────────────── ЧТО ЗДЕСЬ БЫЛО И ПОЧЕМУ ЭТОГО БОЛЬШЕ НЕТ
Пакет назывался каскадом потому, что каскад супер-доступа приходилось ДОСТРАИВАТЬ на пути запроса: внешний движок отношений знал только те кортежи, которые до него доехали очередью, поэтому отказ пересдавался ему второй раз — с «структурными фактами», прочитанными из закоммиченных строк iam и приложенными к вопросу как кортежи, действующие только на этот запрос.
Механизма нет. Решение принимает реляционная форма в собственной базе службы (`repo/kaname/pg/relverdict`): она поднимает цепь областей по своим таблицам тем же планом модели, из которого прежде компилировался ответ движка. Значит второй попытки нет не потому, что от неё отказались, а потому, что первая читает ровно те строки, которыми вторая её дополняла.
───────────────────────────────────────────────────────────────────────────── ЧТО ОСТАЛОСЬ И ПОЧЕМУ ИМЕННО ЗДЕСЬ
Client — одно значение, которое композиционный корень выдаёт КАЖДОМУ стражу.
Оно и есть причина, по которой страж не может спросить «мимо»: другого
значения в корне для него нет.
DerivableTypes — типы, чей структурный предок выводится из строки iam. Перечень
остаётся владельцем вопроса «о каком типе цепь областей обязана
высказаться», и его читает перепись источников звена
(`internal/scopesourcecensus`). Выписанный рядом второй перечень не
сдвинулся бы от нового типа и продолжал бы сторожить прежние.
Index ¶
- Variables
- type Asker
- type Client
- func (c *Client) BatchCheckWithContext(ctx context.Context, subject, relation string, objects []string, ...) ([]bool, error)
- func (c *Client) Check(ctx context.Context, subject, relation, object string) (bool, error)
- func (c *Client) CheckWithContext(ctx context.Context, subject, relation, object string, condCtx map[string]any) (bool, error)
- func (c *Client) CheckWithContextConsistent(ctx context.Context, subject, relation, object string, condCtx map[string]any) (bool, error)
- func (c *Client) DirectRelations(ctx context.Context, subject, objectType, objectID string, limit int) ([]string, error)
- func (c *Client) DirectRelationsMany(ctx context.Context, subject, objectType string, objectIDs []string, limit int) (map[string][]string, error)
- func (c *Client) FormReachable() bool
- func (c *Client) ListSubjects(ctx context.Context, objectType, objectID, relation string, pageSize int, ...) ([]string, string, error)
- func (c *Client) ListUsers(ctx context.Context, objectType, objectID, relation string, userTypes []string) ([]string, bool, error)
- func (c *Client) Sources(ctx context.Context, objectType, objectID, relation string) ([]string, error)
Constants ¶
This section is empty.
Variables ¶
var DerivableTypes = map[string]struct{}{
"iam_access_binding": {},
"account": {},
"project": {},
"iam_user": {},
"iam_group": {},
"iam_role": {},
"iam_service_account": {},
}
DerivableTypes — типы объектов модели прав, чей структурный предок выводится из закоммиченной строки kaname: у такой строки предок лежит КОЛОНКОЙ, поэтому чтение однозначно.
Экспортирован ради переписи источников звена цепи областей: она обязана высказаться о каждом таком типе, включая тип с нулём объектов, и берёт перечень у владельца, а не выписывает свой.
var ErrFormNotWired = fmt.Errorf("authzcascade: дверь решения собрана без формы — спросить не у кого")
ErrFormNotWired — дверь собрана без формы.
Отдельная ошибка, а не «нет»: тип, у которого источник ответа не провязан, отвечал бы отказом на КАЖДЫЙ вопрос, и снаружи это неотличимо от честного отказа модели.
Functions ¶
This section is empty.
Types ¶
type Asker ¶
type Asker interface {
// Allowed — вердикт об объекте. Ошибка означает «ответа нет».
Allowed(ctx context.Context, subject, objectType, objectID, relation string,
condCtx map[string]any) (bool, error)
// AllowedMany — вердикт о СТРАНИЦЕ объектов одного типа, одной читающей
// транзакцией: все объекты страницы видят один снимок базы.
AllowedMany(ctx context.Context, subject, objectType string, objectIDs []string,
relation string, condCtx map[string]any) ([]bool, error)
// SubjectsPage — кто держит отношение на объекте, страницей с курсором.
SubjectsPage(ctx context.Context, objectType, objectID, relation, afterID string,
limit int) (subjects []string, nextAfter string, err error)
// Sources — кого называют основания права на объекте (разбор «почему»).
Sources(ctx context.Context, objectType, objectID, relation string) ([]string, error)
// DirectRelations — какие отношения субъект уже держит на объекте (текст отказа).
DirectRelations(ctx context.Context, subject, objectType, objectID string,
limit int) ([]string, error)
// DirectRelationsMany — то же о СТРАНИЦЕ объектов одного типа, одним вопросом:
// хвост текста отказа платится на каждом отказанном объекте, а страница
// списка отказами и состоит.
DirectRelationsMany(ctx context.Context, subject, objectType string, objectIDs []string,
limit int) (map[string][]string, error)
}
Asker — реляционная форма, отвечающая на вопрос о доступе своей базой.
Объявлен ПОРТОМ, а не конкретным типом, по двум причинам: дверь остаётся переходником и не тянет за собой pgx, а проба может подставить форму, которая НЕ ОТВЕЧАЕТ, — иначе исход «форма не ответила» непроверяем, а он тут главный.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client — дверь решения поверх формы.
func Wrap ¶
Wrap собирает дверь.
nil-форма — законный вход только для пробы, которая о доступе не спрашивает вовсе: каждый вопрос к такой двери возвращает ОШИБКУ, а не «нет». Боевая посадка в этом состоянии находиться не должна, и это проверяет отказ в старте (`ownGateWiringComplaint`), а не надежда.
func (*Client) BatchCheckWithContext ¶
func (c *Client) BatchCheckWithContext( ctx context.Context, subject, relation string, objects []string, condCtx map[string]any, ) ([]bool, error)
BatchCheckWithContext — clients.RelationQueries / authzfilter.BatchObjectChecker.
Ответ той же длины и в порядке заданных объектов: верный, но переставленный вердикт отфильтровал бы страницу чужим ответом. Объекты разных типов в одной партии — ошибка, а не молчаливое разбиение: страница списка по построению однотипна, и партия, где это не так, означает ошибку вызывающего.
func (*Client) CheckWithContext ¶
func (c *Client) CheckWithContext( ctx context.Context, subject, relation, object string, condCtx map[string]any, ) (bool, error)
CheckWithContext — clients.RelationQueries / authzguard.ContextRelationChecker / authzfilter.ObjectChecker.
func (*Client) CheckWithContextConsistent ¶
func (c *Client) CheckWithContextConsistent( ctx context.Context, subject, relation, object string, condCtx map[string]any, ) (bool, error)
CheckWithContextConsistent — вопрос, которому нужен СВЕЖИЙ ответ.
У формы это тождество обычному вопросу, и это не упрощение: она читает ведущую базу службы, а «сильное чтение» существовало ровно затем, чтобы заставить чужое хранилище не отвечать со своей отстающей копии. Метод остаётся ИМЕНЕМ вопроса — вызывающий по-прежнему объявляет, что отставание ему недопустимо, — и перестаёт быть просьбой к чужому транспорту.
func (*Client) DirectRelations ¶
func (c *Client) DirectRelations( ctx context.Context, subject, objectType, objectID string, limit int, ) ([]string, error)
DirectRelations — какие отношения субъект уже держит на объекте.
func (*Client) DirectRelationsMany ¶
func (c *Client) DirectRelationsMany( ctx context.Context, subject, objectType string, objectIDs []string, limit int, ) (map[string][]string, error)
DirectRelationsMany — те же прямые отношения о СТРАНИЦЕ объектов одного типа.
Дверь остаётся переходником: она не собирает страницу из одиночных ответов, а передаёт вопрос форме целиком. Собирать её здесь значило бы завести второе место, знающее, во что обходится страница, — и оно бы разошлось с формой молча.
func (*Client) FormReachable ¶
FormReachable — есть ли у двери чем отвечать. Читает страж старта.
func (*Client) ListSubjects ¶
func (c *Client) ListSubjects( ctx context.Context, objectType, objectID, relation string, pageSize int, pageToken string, ) ([]string, string, error)
ListSubjects — clients.RelationQueries: кто держит отношение на объекте.
Курсор проходит НАСКВОЗЬ: страница без продолжения оставляет остаток недостижимым при живых правах.
func (*Client) ListUsers ¶
func (c *Client) ListUsers( ctx context.Context, objectType, objectID, relation string, userTypes []string, ) ([]string, bool, error)
ListUsers — access_binding.PrincipalLister: развёрнутый набор принципалов.
Второй результат — признак усечения У ИСТОЧНИКА. Форма его не производит: перечисление постранично и продолжаемо, поэтому неполного ответа, о котором нельзя спросить дальше, у неё не бывает. Признак остаётся в подписи, потому что его читает вызывающий, и всегда false — это ЧЕСТНОЕ значение, а не заглушка.
userTypes сужает по типу субъекта; пустой набор — «любой».