authz

package
v1.0.0-alpha.21 Latest Latest
Warning

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

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

Documentation

Overview

Package authz holds dialect-independent Wave 1 authz persistence helpers: lifecycle projection (multi-write), membership-edge Filter schema, and catalog row mapping from compiler mutations.

Index

Constants

This section is empty.

Variables

View Source
var ErrListFilterRequired = service.ErrListFilterRequired

ErrListFilterRequired is returned when a management list runs without an AuthzListFilter (or unrestricted / one-shot skip marker) on the context.

View Source
var ErrSKTeamProjectScope = errors.New("authz: sk_team grants for team-bound permissions must be team-scoped")

ErrSKTeamProjectScope is returned when an sk_team_ grant for a team-bound permission is minted with project scope.

View Source
var MembershipEdgeSchema = database.NewSchema(map[domain.AuthzMembershipEdgeField]database.FieldBinding[domain.AuthzMembershipEdge]{
	domain.AuthzMembershipEdgeFieldProjectID: {
		SQLName:  "project_id",
		Accessor: func(e *domain.AuthzMembershipEdge) any { return e.ProjectID },
		Coerce:   database.CoerceString,
	},
	domain.AuthzMembershipEdgeFieldMemberType: {
		SQLName:  "member_type",
		Accessor: func(e *domain.AuthzMembershipEdge) any { return e.MemberType.String() },
		Coerce:   database.CoerceString,
	},
	domain.AuthzMembershipEdgeFieldMemberID: {
		SQLName:  "member_id",
		Accessor: func(e *domain.AuthzMembershipEdge) any { return e.MemberID },
		Coerce:   database.CoerceString,
	},
	domain.AuthzMembershipEdgeFieldSetType: {
		SQLName:  "set_type",
		Accessor: func(e *domain.AuthzMembershipEdge) any { return e.SetType.String() },
		Coerce:   database.CoerceString,
	},
	domain.AuthzMembershipEdgeFieldSetID: {
		SQLName:  "set_id",
		Accessor: func(e *domain.AuthzMembershipEdge) any { return e.SetID },
		Coerce:   database.CoerceString,
	},
	domain.AuthzMembershipEdgeFieldCreatedAt: {
		SQLName:  "created_at",
		Accessor: func(e *domain.AuthzMembershipEdge) any { return e.CreatedAt },
		Coerce:   database.CoerceTime,
	},
})

MembershipEdgeSchema binds authz_membership_edges filter fields for all dialects.

Functions

func EmptyToNil

func EmptyToNil(s string) *string

EmptyToNil returns nil for empty strings (SQL NULL for optional columns).

func ExpressionEdgeKind

func ExpressionEdgeKind(k compiler.TermKind) (string, error)

ExpressionEdgeKind returns the authz_expression_edges.kind CHECK value for a compiler term.

func ParseExpressionEdgeKind

func ParseExpressionEdgeKind(kind string) (compiler.TermKind, error)

ParseExpressionEdgeKind maps an authz_expression_edges.kind column value to TermKind.

func PersistedCatalogFromDomain

func PersistedCatalogFromDomain(catalog *domain.AuthzCatalog) (compiler.PersistedCatalog, error)

PersistedCatalogFromDomain maps a loaded domain catalog projection into the compiler-shaped rows used by persist round-trip tests.

func RequireManagementListFilter

func RequireManagementListFilter(ctx context.Context) error

RequireManagementListFilter is the #838 tripwire: compileList and hand-built lists (ListUsers) must not SELECT the world if the HTTP filter was forgotten. Unrestricted nested lists are checked first so they do not consume Allow's one-shot skip.

func UserCreated

func UserCreated(ctx context.Context, rsi service.ResourceScopeStatements, edges service.AuthzMembershipEdgeStatements, projectID, userID, initialTeamID string) error

UserCreated dual-writes user RSI and an optional initial team membership edge.

func UserDeactivated

func UserDeactivated(ctx context.Context, edges service.AuthzMembershipEdgeStatements, projectID, userID string) error

UserDeactivated clears all membership edges for the user (RSI is kept).

func UserDeleted

func UserDeleted(ctx context.Context, rsi service.ResourceScopeStatements, edges service.AuthzMembershipEdgeStatements, projectID, userID string) error

UserDeleted clears membership edges and the user resource scope.

func ValidateAssignment

func ValidateAssignment(a *domain.AuthzAssignment) error

ValidateAssignment rejects sk_team_ + project-scope grants for team-bound object types (user, team, team_membership, event). Call from every dialect's CreateAuthzAssignment before INSERT.

func WriteActiveSystemCatalogID

func WriteActiveSystemCatalogID(w ArgWriter, env Env)

WriteActiveSystemCatalogID emits SELECT id for the active system catalog.

func WriteCheckAuthz

func WriteCheckAuthz(w ArgWriter, env Env, params domain.AuthzCheckParams)

WriteCheckAuthz emits SELECT (allowed), (foothold) in one round-trip.

func WriteHasAuthzProjectFoothold

func WriteHasAuthzProjectFoothold(w ArgWriter, env Env, projectID string, principalType domain.AuthzPrincipalType, principalID string)

WriteHasAuthzProjectFoothold emits SELECT (foothold).

func WriteListAuthzExistsPredicate

func WriteListAuthzExistsPredicate(w ArgWriter, env Env, outerResourceIDExpr string, params domain.AuthzListObjectsParams)

WriteListAuthzExistsPredicate emits the per-row visibility test for a management list. outerResourceIDExpr is a raw SQL column reference (e.g. "zitadel_nextgen.teams.id").

The constant arms are lifted out of the correlated subquery by the distributive law, so a planner evaluates them once rather than per listed row:

EXISTS(base AND (C OR Q))  ==  (C AND EXISTS(base)) OR EXISTS(base AND Q)

`C AND EXISTS(base)` is required, not cosmetic: an object with no RSI row must stay invisible even when C is true, so C alone can never grant it.

func WriteListAuthzObjectIDs

func WriteListAuthzObjectIDs(w ArgWriter, env Env, params domain.AuthzListObjectsParams)

WriteListAuthzObjectIDs emits SELECT resource_id … ORDER BY resource_id.

Types

type ArgWriter

type ArgWriter interface {
	WriteString(string)
	WriteArg(any)
}

ArgWriter is satisfied by each dialect's statementCompiler.

type CatalogRows

type CatalogRows struct {
	Relations  []RelationRow
	References []RelationReferenceRow
	Edges      []ExpressionEdgeRow
	Closure    []ClosureRow
}

CatalogRows are storage-ready rows derived from compiler.CatalogMutations.

func BuildCatalogRows

func BuildCatalogRows(catalogID string, mutations compiler.CatalogMutations) (CatalogRows, error)

BuildCatalogRows maps compiler mutations into typed insert rows.

type ClosureRow

type ClosureRow struct {
	CatalogID      string
	FromObjectType string
	FromRelation   string
	ToObjectType   string
	ToRelation     string
	Depth          int
}

ClosureRow is one authz_relation_closure insert.

type Env

type Env struct {
	// Schema is table qualifier including trailing dot, or empty (e.g. "zitadel_nextgen.").
	Schema string
	// Now emits the dialect clock compared to expires_at.
	Now func(ArgWriter)
}

Env adapts shared resolver SQL to one dialect (schema prefix + clock).

type ExpressionEdgeRow

type ExpressionEdgeRow struct {
	CatalogID          string
	ObjectType         string
	Relation           string
	Kind               string
	SourceObjectType   *string
	SourceRelation     *string
	TuplesetObjectType *string
	TuplesetRelation   *string
	Position           int
}

ExpressionEdgeRow is one authz_expression_edges insert.

type RelationReferenceRow

type RelationReferenceRow struct {
	CatalogID   string
	ObjectType  string
	Relation    string
	RefType     string
	RefRelation string
	Wildcard    bool
	Condition   string
	Position    int
}

RelationReferenceRow is one authz_relation_references insert.

type RelationRow

type RelationRow struct {
	CatalogID  string
	ObjectType string
	Relation   string
	Kind       string
}

RelationRow is one authz_relations insert.

Jump to

Keyboard shortcuts

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