seeds

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 10, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package seeds loads a module's declarative catalog seeds (permissions, roles, resource types, relationship types) from embedded YAML and syncs them idempotently into the global catalogs at boot. Seeds touch ONLY global catalogs — never tenant data (blueprint 06 §2 lifecycle SeedSync). Because the catalogs back authorization, they are written with platform privilege (app_platform / owner), never as app_rt (SEC-13/D-0026).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Sync

func Sync(ctx context.Context, db database.DBTX, b Bundle, invalidators ...SpineInvalidator) error

Sync upserts the bundle's catalog rows idempotently. It must run on a platform-privileged connection (the global catalogs are not app_rt-writable). Running twice is a no-op diff (ON CONFLICT DO UPDATE); tenant data is never touched.

invalidators, if any, are invoked AFTER every write succeeds so an in-process authz cache does not serve stale role/permission grants past the sync (CA-2). Pass the kernel's live cache (Kernel.AuthzCache) when it is non-nil; pass nothing when caching is off — the default — and Sync behaves exactly as before.

Types

type Bundle

type Bundle struct {
	Permissions       []PermissionSeed       `yaml:"permissions"`
	Roles             []RoleSeed             `yaml:"roles"`
	ResourceTypes     []ResourceTypeSeed     `yaml:"resource_types"`
	RelationshipTypes []RelationshipTypeSeed `yaml:"relationship_types"`
}

Bundle is the parsed, merged seed catalog for one or more modules.

func Load

func Load(src fs.FS, module string) (Bundle, error)

Load parses every *.yaml (and *.yml) file in src into one merged Bundle, strict-decoding so a typo (unknown key) fails the load. module is the owning module name: every declared key must be prefixed with "<module>." so a module cannot seed another module's catalog entries.

type PermissionSeed

type PermissionSeed struct {
	Key         string `yaml:"key"`
	Description string `yaml:"description"`
	Sensitive   bool   `yaml:"sensitive"`
	// GrantedVia declares the ReBAC rule fed into the authz registry.
	GrantedVia string `yaml:"granted_via"`
	// StepUp declares that this permission requires an elevated authentication
	// factor (MFA): an otherwise-allowed decision becomes a step-up challenge
	// when the actor's AMR carries no strong factor (roadmap S3). Propagated to
	// authz.Permission.StepUp at boot and persisted to permissions.step_up.
	StepUp bool `yaml:"step_up"`
	// StepUpAMR, when non-empty, narrows step-up to a SPECIFIC AMR subset for
	// this permission (e.g. ["hwk"] to require a hardware key specifically,
	// rather than any factor from the deployment's default strong-factor set).
	// Only meaningful alongside step_up: true (validated); propagated to
	// authz.Permission.StepUpPolicy.RequiredAMR at boot. NOT persisted —
	// permissions.step_up remains the plain bool; a richer per-permission AMR
	// policy is registry-declared (seed-driven, in-memory), not DB-persisted.
	// See kernel/seeds doc comment (package-level) and B8 backlog item for the
	// cheapest-correct-path rationale.
	StepUpAMR []string `yaml:"step_up_amr"`
	// StepUpChallenge, when set, is the factor/hint the HTTP gate advertises in
	// WWW-Authenticate for this permission's step-up challenge (e.g. "hwk"
	// alongside step_up_amr: [hwk]). Only meaningful alongside step_up: true.
	// Propagated to authz.Permission.StepUpPolicy.Challenge at boot. Not
	// persisted, same rationale as StepUpAMR.
	StepUpChallenge string `yaml:"step_up_challenge"`
}

PermissionSeed declares a permission in the catalog.

type RelationshipTypeSeed

type RelationshipTypeSeed struct {
	Key         string `yaml:"key"`
	SubjectKind string `yaml:"subject_kind"`
	ObjectKind  string `yaml:"object_kind"`
	Cardinality string `yaml:"cardinality"`
	Description string `yaml:"description"`
}

RelationshipTypeSeed declares a relationship type.

type ResourceTypeSeed

type ResourceTypeSeed struct {
	Key         string `yaml:"key"`
	Description string `yaml:"description"`
}

ResourceTypeSeed declares a resource type.

type RoleSeed

type RoleSeed struct {
	Key         string   `yaml:"key"`
	Name        string   `yaml:"name"`
	Permissions []string `yaml:"permissions"`
}

RoleSeed declares a platform-template role and the permissions it grants.

type SpineInvalidator

type SpineInvalidator interface{ InvalidateAll() }

SpineInvalidator drops an in-process authorization cache after a seed (authorization-spine) write commits. *authz.CachingStore satisfies it via its InvalidateAll method — declared here as a narrow local interface so this base package stays free of an authz import. A seed sync rewrites GLOBAL platform roles and their role_permissions, which any tenant's actors may hold and which the cache pre-joins into ActiveAssignments, so the WHOLE cache is dropped (not one tenant) — see CachingStore.InvalidateAll.

Jump to

Keyboard shortcuts

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