demesne

package module
v0.83.0 Latest Latest
Warning

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

Go to latest
Published: Sep 20, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

Demesne, Zanzibar-style authz framework compiled to RLS

Demesne


Write your authorization rules once, in a single spec file. Demesne compiles them into Postgres Row-Level Security, so the database enforces access on every query — a forgotten WHERE clause, a background job, or an ad-hoc psql session can't reach data the rules forbid.

It takes the idea behind Google's Zanzibar — a declarative schema of who-relates-to-what — but skips the separate authorization service. There's no Check API to call, no second datastore to keep in sync, no consistency tokens. The policy lives in the one place it can't be bypassed: the data path.

The problem

Authorization usually lives in application code — a service you call, or if checks spread across handlers. Both only protect the paths that remember to ask. Miss one and the rule isn't there.

Demesne moves the decision into Postgres, so access is a property of the data rather than a step in the request. One .demesne file compiles to two layers:

  • Row-Level Security — the enforcement floor. Demesne generates the policies and the trusted SECURITY DEFINER functions they call. Every query is filtered by the same rules, whether it comes from your app, a cron job, or a database console.
  • A verb gate — for actions RLS can't see. Some permissions aren't about rows ("can this user publish?"). For those, Demesne generates a Go and TypeScript capability map you check at the request boundary.

The same spec also produces the JWT claims your sessions carry. Change the spec, regenerate, and the database floor and the application code move together — nothing to hand-write and keep in sync.

How it works

A spec describes four things:

  • a topology — your tenancy shape, e.g. tenant → project;
  • the subjects that act — users, customers, staff;
  • the objects they act on — your tables;
  • the relations and permissions that connect them — ownership, roles, sharing, group membership.

From those, Demesne emits the RLS policies, the SECURITY DEFINER kernel, the verb-gate map, and the claims contract. Every trusted function is generated, so there's no opaque hand-written SQL to audit. CI byte-compares each generated artifact against a committed golden file, and asserts that every Can<Verb> point-check inlines the matching policy's USING clause verbatim — so the application surface cannot drift from the floor without failing the build. Set $DEMESNE_PG_URL and the suite additionally installs the emitted kernel in a real Postgres and checks the SQL agrees with the Go and TypeScript resolvers case for case. For a database you have already deployed to, demesne diff <spec> <dsn> --exit-code reports drift between the spec and the live policies.

import "github.com/foir-io/demesne"

spec, _ := demesne.Parse(src)      // text → AST
demesne.Validate(spec)             // static checks

rls, _    := spec.EmitRLS()        // Postgres RLS policies
pdp, _    := spec.EmitPDP()        // Go capability map
defs, _   := spec.EmitDefiners()   // the SECURITY DEFINER kernel
claims, _ := spec.ClaimsContract() // the JWT claims the policies read

Adopting Demesne on an existing database is a short loop: introspect the schema, scaffold a starter spec, edit it, emit the SQL, apply it as a migration. GUIDE.md walks through it end to end.

The spec language

examples/example.demesne is a complete worked spec — a small document app. The building blocks:

Block Declares
topology the tenancy hierarchy; a virtual root sits above tenancy
vocabulary permissions, presets, and a rank ladder
rolestore where role assignments live, so the role checks can be generated
subject who acts: where they sit in the hierarchy, how far they reach, how they're identified
object a governed table — its relations, permissions, and optional per-record sharing
grant a scoped, revocable, expiring grant of reach into part of the hierarchy

Permissions are a small boolean algebra over those terms — union, intersection, and fail-closed negation — so viewer and not banned or (owner or shared) and not banned compile straight to an RLS predicate. @holds(<perm>) gates a branch on the caller holding an admin permission, matched against the rolestore's materialized permission arrays at query time, so role edits change the floor without a re-emit.

A permission grants; a require constrains. Because Postgres ORs permissive policies together, every term in a permission line can only ever widen. require <verb> = <expr> emits the same predicate AS RESTRICTIVE, which Postgres ANDs with the permissive set — a floor under the permission rather than another branch beside it, per verb, and carried into the generated app surface as well as the policy. See require.demesne.

Spec introspection

The compiled spec is the single source of your vocabulary, so you can build a role-management or permission-admin UI from it without re-declaring the permission list. spec.Vocabularies() returns each declared vocabulary and its permissions, and marks each parameterized one: a permission that carries the open * model segment, like docs:read:* rather than a concrete docs:read. spec.ExpandedPresets(rolestore) maps each preset of that rolestore's vocabulary to its fully resolved permission set, and expands both + references and the = * wildcard. Demesne returns generic data. How you bucket, label, and lay it out is your UI's job.

for _, v := range spec.Vocabularies() {
	for _, p := range v.Permissions {
		// p.Name, p.Parameterized → drive a permission picker
	}
}
presets, _ := spec.ExpandedPresets("staff") // preset → resolved permissions, for a role editor

Worked examples

The patterns that are easy to get subtly wrong by hand are each a few lines of spec, and each ships with a test that asserts the generated policy actually enforces the intended reach:

Pattern Spec
Folder → document inheritance, unbounded nesting inheritance.demesne
Groups within groups (transitive membership) groups.demesne
Role-based access control rbac.demesne
viewer ∩ member − banned boolean.demesne
Narrowing a permission you cannot take back (AS RESTRICTIVE) require.demesne

Run them with go test . -run TestCanonical.

How it compares

Demesne is a Zanzibar-class relationship model, but it compiles into Postgres instead of running as a separate Check service. CAPABILITIES.md has the full matrix and an honest comparison with Zanzibar, Ory Keto, OpenFGA, Cerbos, and Oso — including where each of those is the better fit.

What to expect

  • Authorization, not authentication. Demesne reads the session your auth provider issues — Clerk, BetterAuth, Supabase Auth — and decides what each user can reach. Signing users in stays with your provider; Demesne sits alongside it.
  • Postgres only. Compiling to RLS is the whole idea; a Supabase deployment profile ships (SUPABASE.md).
  • A library and CLI, not a service — nothing extra to run or scale next to your database.
  • Every rule must be expressible as a SQL predicate. Reverse "who can see this?" queries are supported but deliberately conservative (fail-closed), not exhaustive.
  • No dependencies in the core. The engine module is standard-library only and never opens a connection; the CLI is a separate module that links a Postgres driver for its live-database commands.

Development

go build ./...
go vet ./...
go test ./...

License

Apache 2.0 — see LICENSE and NOTICE.

Documentation

Index

Examples

Constants

View Source
const ChangelogChannel = "demesne_authz_changelog"

Variables

This section is empty.

Functions

func CapabilityGateErr

func CapabilityGateErr(object, verb string) error

func DefinersSQL

func DefinersSQL(defs []GenFn) string

func MintClaimsValues

func MintClaimsValues(contract []string, values map[string]string) (string, error)

func MintClaimsValuesWithExtra

func MintClaimsValuesWithExtra(contract []string, values, extra map[string]string) (string, error)

func Validate

func Validate(s *Spec) error

func ZookieNowSQL

func ZookieNowSQL() string

Types

type Admit added in v0.83.0

type Admit struct {
	Ops  []string
	Expr []*Term
	Tree *PermNode
	Pos  Pos
}

type Affordance

type Affordance struct {
	Hint      AffordanceHint
	AsOf      Zookie
	Freshness Freshness
	Source    AffordanceSource
}

func ComposeAffordance

func ComposeAffordance(allowed bool, asOf Zookie, c Consistency) Affordance

func (Affordance) Render

func (a Affordance) Render() RenderHint

type AffordanceHint

type AffordanceHint int
const (
	HintUnknown AffordanceHint = iota
	HintLikely
	HintUnlikely
)

type AffordanceSource

type AffordanceSource int
const (
	SourceAsyncIndex AffordanceSource = iota
	SourceFloor
)

type AppCheck added in v0.71.0

type AppCheck struct {
	Verb     string
	CheckSQL string
}

AppCheck is one @check permission's point-check: its verb and the boolean SELECT.

type AppCheckSurface

type AppCheckSurface struct {
	Objects []AppObjectSurface
}

func (*AppCheckSurface) Object

func (a *AppCheckSurface) Object(name string) (AppObjectSurface, bool)

type AppObjectSurface

type AppObjectSurface struct {
	Object string
	Table  string
	PK     string

	FlatListFn string

	AsyncCheckSQL string

	EditCheckSQL string

	// Checks holds one point-check per @check permission (verb + SQL): compiled
	// predicates exposed as Can<Verb>, with no RLS policy.
	Checks []AppCheck
}

func (AppObjectSurface) CheckEditSQL

func (o AppObjectSurface) CheckEditSQL() string

func (AppObjectSurface) CheckManySQL

func (o AppObjectSurface) CheckManySQL() string

func (AppObjectSurface) CheckSQL

func (o AppObjectSurface) CheckSQL() string

func (AppObjectSurface) CheckVerbSQL added in v0.71.0

func (o AppObjectSurface) CheckVerbSQL(verb string) string

CheckVerbSQL returns the point-check SQL for a @check verb, or "" if the object has no @check permission of that name.

func (AppObjectSurface) ListResourcesFastSQL

func (o AppObjectSurface) ListResourcesFastSQL() string

func (AppObjectSurface) ListResourcesSQL

func (o AppObjectSurface) ListResourcesSQL() string

type ArgSrc

type ArgSrc struct {
	Claim string
	Col   string
}

type AsyncIndex

type AsyncIndex struct {
	Schema       string
	TableSchema  string
	Changelog    string
	Cursor       string
	Base         string
	GrantTable   string
	RecordCol    string
	KindCol      string
	PrincipalCol string
	DiscrimCol   string
	DiscrimVal   string
	IDType       string
}

func (AsyncIndex) AffordanceFnSQL

func (a AsyncIndex) AffordanceFnSQL() string

func (AsyncIndex) ApplyFnSQL

func (a AsyncIndex) ApplyFnSQL() string

func (AsyncIndex) RebuildFnSQL

func (a AsyncIndex) RebuildFnSQL() string

func (AsyncIndex) TableSQL

func (a AsyncIndex) TableSQL() string

func (AsyncIndex) WatermarkFnSQL

func (a AsyncIndex) WatermarkFnSQL() string

type ChangelogTrigger

type ChangelogTrigger struct {
	Schema       string
	TableSchema  string
	Changelog    string
	Table        string
	RecordCol    string
	KindCol      string
	PrincipalCol string
	DiscrimCol   string
}

func (ChangelogTrigger) FunctionSQL

func (c ChangelogTrigger) FunctionSQL() string

func (ChangelogTrigger) TriggerSQL

func (c ChangelogTrigger) TriggerSQL() string

type ClaimEntry

type ClaimEntry struct {
	Key      string
	Level    string
	Subjects []string
}

type ClaimsAccessor

type ClaimsAccessor struct {
	Setting string
	Cast    string

	Role string
	Pos  Pos
}

type ClosureTrigger

type ClosureTrigger struct {
	Schema      string
	TableSchema string
	Closure     string
	Ancestor    string
	Descendant  string
	Base        string
	BaseID      string
	BaseParent  string
}

func (ClosureTrigger) FunctionSQL

func (c ClosureTrigger) FunctionSQL() string

func (ClosureTrigger) TriggerSQL

func (c ClosureTrigger) TriggerSQL() string

type Column

type Column struct {
	Name     string
	DataType string
	Nullable bool
}

type Consistency

type Consistency interface {
	Level() ConsistencyLevel
	// contains filtered or unexported methods
}

func AtLeastAsFresh

func AtLeastAsFresh(z Zookie) Consistency

func FullyConsistent

func FullyConsistent() Consistency

func MinimizeLatency

func MinimizeLatency() Consistency

type ConsistencyLevel

type ConsistencyLevel int
const (
	LevelMinimizeLatency ConsistencyLevel = iota
	LevelAtLeastAsFresh
	LevelFullyConsistent
)

type CostClass

type CostClass int
const (
	Inline CostClass = iota
	Definer
	Closure
)

func (CostClass) String

func (c CostClass) String() string

type Decision

type Decision int
const (
	Allow Decision = iota

	Deny

	NotGoverned
)

func ComposeCan

func ComposeCan(pointGoverned, pointAllow bool, pdp Decision) Decision

func (Decision) String

func (d Decision) String() string

type DelegationCap

type DelegationCap struct {
	Allowed bool

	Unknown []string

	Excess []string
}

type EffectivePerms

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

func (EffectivePerms) Holds

func (e EffectivePerms) Holds(perm string) bool

func (EffectivePerms) Permissions

func (e EffectivePerms) Permissions() []string

type EffectiveRoles added in v0.63.0

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

func NewEffectiveRoles added in v0.63.0

func NewEffectiveRoles(keys ...string) EffectiveRoles

func ResolveRoles added in v0.63.0

func ResolveRoles(assignments []RoleAssignment, scope []string) EffectiveRoles

func (EffectiveRoles) Holds added in v0.63.0

func (e EffectiveRoles) Holds(roleKey string) bool

func (EffectiveRoles) Roles added in v0.63.0

func (e EffectiveRoles) Roles() []string

type ExportParameter added in v0.83.0

type ExportParameter struct {
	Column string
	Type   string
	Name   string
}

type External added in v0.78.0

type External struct {
	Name     string
	ArgTypes []string
	Pos      Pos
}

type ExternalArg added in v0.78.0

type ExternalArg struct {
	Col   string
	Claim string
	Lit   string
}

type FieldAccess added in v0.68.0

type FieldAccess struct {
	Object     string
	Principals []string
	Rules      []FieldAccessRule
}

func (*FieldAccess) RenderGo added in v0.68.0

func (fa *FieldAccess) RenderGo() string

func (*FieldAccess) RenderGrants added in v0.68.0

func (fa *FieldAccess) RenderGrants(table string) string

func (*FieldAccess) RenderTS added in v0.68.0

func (fa *FieldAccess) RenderTS() string

type FieldAccessRule added in v0.68.0

type FieldAccessRule struct {
	Field  string
	Read   []string
	Write  []string
	Column string
}

type FieldRule added in v0.68.0

type FieldRule struct {
	Name   string
	Read   []string
	Write  []string
	Column string
	Pos    Pos
}

type FieldScopeEntry

type FieldScopeEntry struct {
	Field string
	Scope string
	Pos   Pos
}

type FieldScopes

type FieldScopes struct {
	Site    string
	Entries []FieldScopeEntry
	Pos     Pos
}

type ForeignKey

type ForeignKey struct {
	Table, Column, RefTable, RefColumn string
}

type Freshness

type Freshness int
const (
	FreshnessUnknown Freshness = iota
	Stale
	CaughtUp
	FloorBacked
)

type Gate

type Gate struct {
	Verb     string
	Relation string
	Perm     string
	Pos      Pos
}

type GenFn

type GenFn struct {
	Name   string
	Schema string

	TableSchema string
	Sig         string
	Body        string

	Returns string

	RawBody bool
}

func (GenFn) ArgTypes

func (d GenFn) ArgTypes() string

func (GenFn) CreateSQL

func (d GenFn) CreateSQL() string

type Grant

type Grant struct {
	Name       string
	Level      string
	Table      string
	GranteeCol string
	LevelCol   string
	ActiveCol  string
	ExpiresCol string

	IDCol        string
	GrantedByCol string
	RevokedByCol string
	CreatedAtCol string

	// Verbs bounds which table ops the grant's reach is spliced into. Empty
	// means every op, which is what a grant carrying no `confers` clause gets,
	// so a spec written before the clause existed keeps its behaviour exactly.
	//
	// Without a bound the same reach predicate lands on select, insert, update
	// and delete alike, so a grant meant to let a holder READ what it reaches
	// also lets it rewrite and destroy it. That is rarely what a reach is for,
	// and it cannot be narrowed after the fact by the permission expression,
	// which never sees the reach.
	Verbs []string

	ExtraCols []string

	Named      string
	Scopes     []GrantScope
	ClaimKey   string
	ClaimValue string

	Pos Pos
}

func (*Grant) Confers added in v0.81.0

func (g *Grant) Confers(op string) bool

Confers reports whether the grant's reach applies to a table op. A grant that names no verbs confers all of them.

func (*Grant) EdgeTable

func (g *Grant) EdgeTable() string

func (*Grant) GranteeColumn

func (g *Grant) GranteeColumn() string

func (*Grant) Granularity

func (g *Grant) Granularity() GrantGranularity

type GrantGranularity

type GrantGranularity int
const (
	LevelReach GrantGranularity = iota

	RowReach
)

func (GrantGranularity) String

func (g GrantGranularity) String() string

type GrantScope added in v0.83.0

type GrantScope struct {
	Level   string
	Column  string
	Missing string
}

type GrantSurface

type GrantSurface struct {
	Name       string
	Level      string
	Table      string
	GranteeCol string
	LevelCol   string
	ActiveCol  string
	ExpiresCol string
	PK         string

	GrantedByCol string
	RevokedByCol string
	CreatedAtCol string

	ExtraCols []string
}

func (*GrantSurface) GrantInsert

func (g *GrantSurface) GrantInsert(grantID, granteeID, levelID, grantedBy string, expiresAt any, extra map[string]any) (string, []any)

func (*GrantSurface) ListSQL

func (g *GrantSurface) ListSQL() string

func (*GrantSurface) RevokeSQL

func (g *GrantSurface) RevokeSQL() string

type GrantUse added in v0.83.0

type GrantUse struct {
	Grant    string
	Via      string
	Bound    string
	Unscoped bool
	Ops      []string
	Pos      Pos
}

type GroupTrigger

type GroupTrigger struct {
	Schema      string
	TableSchema string
	Closure     string
	GroupCol    string
	MemberCol   string
	Edge        string
	EdgeMember  string
	EdgeGroup   string
}

func (GroupTrigger) FunctionSQL

func (g GroupTrigger) FunctionSQL() string

func (GroupTrigger) TriggerSQL

func (g GroupTrigger) TriggerSQL() string

type Guard

type Guard struct {
	Col string
	Op  string
	Val string
	Pos Pos
}

type HoldsResolver

type HoldsResolver struct {
	Assignments string
	KindCol     string
	KindVal     string
	SubjectCol  string
	ScopeCols   []string
	RevokedCol  string

	Plane      string
	PlaneDepth int

	RoleCol    string
	RolesTable string
	RolesID    string
	KeyCol     string

	PermsCol string

	Vocab *Vocabulary
}

func (*HoldsResolver) AssignmentsSQL

func (r *HoldsResolver) AssignmentsSQL() string

func (*HoldsResolver) GlobalAssignmentsSQL added in v0.76.0

func (r *HoldsResolver) GlobalAssignmentsSQL() string

func (*HoldsResolver) Resolve

func (r *HoldsResolver) Resolve(assignments []RoleAssignment, scope []string) (EffectivePerms, error)

func (*HoldsResolver) SelectedScopeCols added in v0.77.0

func (r *HoldsResolver) SelectedScopeCols() []string

func (*HoldsResolver) Vocabulary

func (r *HoldsResolver) Vocabulary() *Vocabulary

type Implication added in v0.76.0

type Implication struct {
	Perm string
	Set  []string
	Star bool
	Pos  Pos
}

type Level

type Level struct {
	Name    string
	Parents []string
	Virtual bool

	ScopeCol string

	ClaimKey string
	Pos      Pos
}

type MaterializedFlat

type MaterializedFlat struct {
	Schema      string
	TableSchema string
	Flat        string
	ObjTable    string
	ObjPK       string
	Col         string
	Closure     string
	GroupCol    string
	MemberCol   string
	Kind        string

	ClaimExpr string
	IDType    string
}

func (MaterializedFlat) FunctionSQL

func (m MaterializedFlat) FunctionSQL() string

func (MaterializedFlat) HasReverse

func (m MaterializedFlat) HasReverse() bool

func (MaterializedFlat) IndexesSQL

func (m MaterializedFlat) IndexesSQL() string

func (MaterializedFlat) MemberDefiner

func (m MaterializedFlat) MemberDefiner() GenFn

func (MaterializedFlat) ReconcileSQL

func (m MaterializedFlat) ReconcileSQL() string

func (MaterializedFlat) ResourcesDefiner

func (m MaterializedFlat) ResourcesDefiner() GenFn

func (MaterializedFlat) TableSQL

func (m MaterializedFlat) TableSQL() string

func (MaterializedFlat) TriggerSQL

func (m MaterializedFlat) TriggerSQL() string

type Membership

type Membership struct {
	Table     string
	IDCol     string
	FlagCol   string
	ActiveCol string
	ActiveVal string
}

type Object

type Object struct {
	Name  string
	Table string

	PK string

	PKCols []string
	Level  string

	Scoped         []string
	ScopeWildcards []string

	// ScopeWildcardVerbs bounds a wildcard to named table ops, keyed by level.
	// An absent or empty entry means every op, which is what a bare `wildcard`
	// gets, so a spec written before the clause existed keeps its behaviour.
	//
	// The distinction matters because a wildcard says two things at once that
	// are not equally safe. It says a row carrying NULL at this level belongs to
	// no instance of it, and it says such a row is in scope for a caller who
	// stands in one instance. Reading a row that belongs to everyone is the
	// point of a shared tier; WRITING one from inside a single instance is a
	// caller reaching outside the instance that confines it.
	ScopeWildcardVerbs map[string][]string

	ReachUses []GrantUse
	Admits    []*Admit
	Exports   []PermissionExport

	Relations []*Relation
	Perms     []*Perm
	Requires  []*Require
	Gates     []*Gate

	FieldPrincipals []string
	Fields          []*FieldRule

	Use  string
	Omit []string

	TrackOwner      bool
	TrackVisibility bool
	Pos             Pos
}

func (*Object) HasGrantStore

func (o *Object) HasGrantStore() bool

func (*Object) IsLevelEntity

func (o *Object) IsLevelEntity() bool

type ObjectChangelogTrigger

type ObjectChangelogTrigger struct {
	Schema       string
	TableSchema  string
	Changelog    string
	Table        string
	Rel          string
	PK           string
	OwnerIDCol   string
	OwnerKindCol string
	ModeCol      string
}

func (ObjectChangelogTrigger) FunctionSQL

func (c ObjectChangelogTrigger) FunctionSQL() string

func (ObjectChangelogTrigger) TriggerSQL

func (c ObjectChangelogTrigger) TriggerSQL() string

type PDP

type PDP struct {
	EmitSite   string
	Policy     map[string]string
	Ungoverned map[string]string
}

func (*PDP) Authorize

func (p *PDP) Authorize(procedure string, holds func(perm string) bool) Decision

func (*PDP) RenderGo

func (p *PDP) RenderGo(varName string) string

func (*PDP) RenderTS

func (p *PDP) RenderTS(varName string) string

type Perm

type Perm struct {
	Verb          string
	Expr          []*Term
	Tree          *PermNode
	Layers        []string
	Maps          string
	Guard         *Guard
	SelfCheck     string
	PredicateOnly bool
	Pos           Pos
}

func (*Perm) LayerTag

func (pm *Perm) LayerTag() string

type PermNode

type PermNode struct {
	Op   string
	Term *Term
	Kids []*PermNode
}

func (*PermNode) Leaves

func (n *PermNode) Leaves() []*Term

type PermissionExport added in v0.83.0

type PermissionExport struct {
	Verb   string
	Name   string
	Params []ExportParameter
	Pos    Pos
}

type PermissionInfo added in v0.64.0

type PermissionInfo struct {
	Name          string
	Parameterized bool
}

type Policy

type Policy struct {
	Object string
	Table  string
	Name   string
	Cmd    string
	Using  string
	Check  string

	Restrictive bool
}

type Pos

type Pos struct{ Line int }

type Preset

type Preset struct {
	Name  string
	Level string
	Set   []string
	Star  bool
	Pos   Pos
}

type Principal

type Principal struct {
	Subject string
	ID      string
	Scopes  map[string]string
}

type ProcEntry

type ProcEntry struct {
	Proc string
	Perm string
	Pos  Pos
}

type Procedures

type Procedures struct {
	EmitSite string
	Entries  []ProcEntry
	Pos      Pos
}

type Querier

type Querier interface {
	QueryRowContext(ctx context.Context, query string, args ...any) Row
	QueryContext(ctx context.Context, query string, args ...any) (Rows, error)
}

func FromSQL

func FromSQL(db SQLDB) Querier

type RLSResult

type RLSResult struct {
	Policies    []Policy
	Unsupported []string

	TableSchema string
}

func (*RLSResult) EnablementSQL

func (r *RLSResult) EnablementSQL() string

func (*RLSResult) GovernedTables

func (r *RLSResult) GovernedTables() []string

func (*RLSResult) PolicySQL

func (r *RLSResult) PolicySQL(role string) string

type ReachGrant

type ReachGrant interface {
	EdgeTable() string

	GranteeColumn() string

	Granularity() GrantGranularity
}

type Relation

type Relation struct {
	Name  string
	Types []string
	Repr  Repr
	Kind  string
	Pos   Pos
}

func (*Relation) CostClass

func (r *Relation) CostClass() CostClass

type RenderHint

type RenderHint bool

type Repr

type Repr interface {
	// contains filtered or unexported methods
}

type Require added in v0.78.0

type Require struct {
	Verb string
	Expr []*Term
	Tree *PermNode
	Pos  Pos
}

type ResourceAccessSurface

type ResourceAccessSurface struct {
	Table string

	ScopeCols []string

	ModeCol string
	// contains filtered or unexported fields
}

func (*ResourceAccessSurface) AccessorsSQL

func (r *ResourceAccessSurface) AccessorsSQL() string

func (*ResourceAccessSurface) GrantInsert

func (r *ResourceAccessSurface) GrantInsert(scope []string, resourceID, kind, principalID, access string) (string, []any)

func (*ResourceAccessSurface) GrantKindAllowed

func (r *ResourceAccessSurface) GrantKindAllowed(kind string) bool

func (*ResourceAccessSurface) IsReadMode

func (r *ResourceAccessSurface) IsReadMode(mode string) bool

func (*ResourceAccessSurface) ListGrantsArgs

func (r *ResourceAccessSurface) ListGrantsArgs(resourceID string) []any

func (*ResourceAccessSurface) ListGrantsSQL

func (r *ResourceAccessSurface) ListGrantsSQL() string

func (*ResourceAccessSurface) ModeSQL

func (r *ResourceAccessSurface) ModeSQL() string

func (*ResourceAccessSurface) RevokeDelete

func (r *ResourceAccessSurface) RevokeDelete(resourceID, kind, principalID, access string) (string, []any)

func (*ResourceAccessSurface) SetVisibilitySQL

func (r *ResourceAccessSurface) SetVisibilitySQL() string

type RoleAssignment

type RoleAssignment struct {
	Scope       []string
	RoleKey     string
	Permissions []string
}

type RoleAssignmentSurface

type RoleAssignmentSurface struct {
	Assignments string
	PK          string
	KindCol     string
	KindVal     string
	SubjectCol  string
	RoleCol     string
	ScopeCols   []string
	RevokedCol  string

	GrantedAtCol string
	GrantedByCol string
	RevokedByCol string

	ExtraCols []string

	RolesTable string
	RolesID    string
	KeyCol     string
	PermsCol   string
}

func (*RoleAssignmentSurface) AssignInsert

func (r *RoleAssignmentSurface) AssignInsert(assignmentID, subjectID, roleID string, scope []string, grantedBy string, extra map[string]any) (string, []any)

func (*RoleAssignmentSurface) AssignTouchInsert

func (r *RoleAssignmentSurface) AssignTouchInsert(assignmentID, subjectID, roleID string, scope []string, grantedBy string, extra map[string]any) (string, []any)

func (*RoleAssignmentSurface) ListForPrincipalSQL

func (r *RoleAssignmentSurface) ListForPrincipalSQL() string

func (*RoleAssignmentSurface) ListForRoleSQL

func (r *RoleAssignmentSurface) ListForRoleSQL() string

func (*RoleAssignmentSurface) RevokeSQL

func (r *RoleAssignmentSurface) RevokeSQL() string

type RoleStore

type RoleStore struct {
	Name        string
	Assignments string
	KindCol     string
	KindVal     string
	SubjectCol  string
	ScopeCols   []string
	Plane       string
	RoleCol     string
	RolesTable  string
	RolesID     string
	KeyCol      string
	RevokedCol  string

	PermsCol string

	IDCol        string
	GrantedAtCol string
	GrantedByCol string
	RevokedByCol string

	ExtraCols []string
	Pos       Pos
}

type Row

type Row interface {
	Scan(dest ...any) error
}

type Rows

type Rows interface {
	Next() bool
	Scan(dest ...any) error
	Close() error
	Err() error
}

type SQLDB

type SQLDB interface {
	QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)
}

type ScaffoldOptions

type ScaffoldOptions struct {
	MinContainerRefs int
}

type Schema

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

func NewSchema

func NewSchema() *Schema

func (*Schema) AddColumn

func (s *Schema) AddColumn(table, name, dataType string, nullable bool)

func (*Schema) AddForeignKey

func (s *Schema) AddForeignKey(table, column, refTable, refColumn string)

func (*Schema) Scaffold

func (sc *Schema) Scaffold(opts ScaffoldOptions) (string, error)

func (*Schema) Tables

func (s *Schema) Tables() []string

type Spec

type Spec struct {
	Topology    *Topology
	Vocabs      []*Vocabulary
	Subjects    []*Subject
	Objects     []*Object
	Procedures  []*Procedures
	Ungoverned  []*Ungoverned
	FieldScopes []*FieldScopes
	RoleStores  []*RoleStore
	Grants      []*Grant
	Templates   []*Template
	Externals   []*External
	Claims      *ClaimsAccessor

	DefinerSchema string

	TableSchema string

	Identifiers string
}

func Parse

func Parse(src string) (*Spec, error)

func (*Spec) AsyncCursorSQL

func (s *Spec) AsyncCursorSQL() string

func (*Spec) AsyncSQL

func (s *Spec) AsyncSQL() string

func (*Spec) BuildClaims

func (s *Spec) BuildClaims(p Principal) (map[string]string, error)

func (*Spec) ChangelogSQL

func (s *Spec) ChangelogSQL() string

func (*Spec) ChangelogTableSQL

func (s *Spec) ChangelogTableSQL() string

func (*Spec) ClaimsContract

func (s *Spec) ClaimsContract() ([]string, error)

func (*Spec) ClaimsContractEntries

func (s *Spec) ClaimsContractEntries() ([]ClaimEntry, error)

func (*Spec) ClaimsSetSQL

func (s *Spec) ClaimsSetSQL(local bool) string

func (*Spec) ConnectionRole

func (s *Spec) ConnectionRole() string

func (*Spec) DefinerNames

func (s *Spec) DefinerNames() ([]string, error)

func (*Spec) EmitAppSurface

func (s *Spec) EmitAppSurface() (*AppCheckSurface, error)

func (*Spec) EmitAsyncIndexes

func (s *Spec) EmitAsyncIndexes() []AsyncIndex

func (*Spec) EmitChangelogTriggers

func (s *Spec) EmitChangelogTriggers() []ChangelogTrigger

func (*Spec) EmitDefiners

func (s *Spec) EmitDefiners() ([]GenFn, error)

func (*Spec) EmitFieldAccess added in v0.68.0

func (s *Spec) EmitFieldAccess() (map[string]*FieldAccess, error)

func (*Spec) EmitFieldScopes

func (s *Spec) EmitFieldScopes() (map[string]map[string]string, error)

func (*Spec) EmitFramework

func (s *Spec) EmitFramework(pkg string) (string, error)

func (*Spec) EmitFrameworkTS

func (s *Spec) EmitFrameworkTS() (string, error)

func (*Spec) EmitGroupTriggers

func (s *Spec) EmitGroupTriggers() []GroupTrigger

func (*Spec) EmitMaterializedFlats

func (s *Spec) EmitMaterializedFlats() []MaterializedFlat

func (*Spec) EmitObjectChangelogTriggers

func (s *Spec) EmitObjectChangelogTriggers() []ObjectChangelogTrigger

func (*Spec) EmitPDP

func (s *Spec) EmitPDP() (map[string]*PDP, error)

func (*Spec) EmitRLS

func (s *Spec) EmitRLS() (*RLSResult, error)

func (*Spec) EmitSupabaseProfile

func (s *Spec) EmitSupabaseProfile() (string, error)

func (*Spec) EmitTS

func (s *Spec) EmitTS() (string, error)

func (*Spec) EmitTriggers

func (s *Spec) EmitTriggers() []ClosureTrigger

func (*Spec) ExpandedPresets added in v0.64.0

func (s *Spec) ExpandedPresets(rolestore string) (map[string][]string, error)
Example
s := exampleSpecForDoc()
presets, err := s.ExpandedPresets("staff")
if err != nil {
	panic(err)
}
names := make([]string, 0, len(presets))
for name := range presets {
	names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
	fmt.Printf("%s = %s\n", name, strings.Join(presets[name], " "))
}
Output:
tenant_owner = docs:publish docs:read docs:read:* docs:write
ws_editor = docs:publish docs:read docs:write
ws_viewer = docs:read

func (*Spec) FlatsSQL

func (s *Spec) FlatsSQL() string

func (*Spec) FreeColumns

func (s *Spec) FreeColumns(sub *Subject) ([]string, error)

func (*Spec) GrantSurface

func (s *Spec) GrantSurface(name string) (*GrantSurface, error)

func (*Spec) HoldsResolver

func (s *Spec) HoldsResolver(rolestore string) (*HoldsResolver, error)

func (*Spec) MintClaims

func (s *Spec) MintClaims(values map[string]string) (string, error)

func (*Spec) MintClaimsFor

func (s *Spec) MintClaimsFor(p Principal) (string, error)

func (*Spec) PinnedColumns

func (s *Spec) PinnedColumns(sub *Subject) (cols []string, virtualAnchor bool, err error)

func (*Spec) PointCheckSQL

func (s *Spec) PointCheckSQL(object string) (string, error)

func (*Spec) ReachGrants

func (s *Spec) ReachGrants() []ReachGrant

func (*Spec) RenderClaimsContractEntriesGo

func (s *Spec) RenderClaimsContractEntriesGo(varName string) (string, error)

func (*Spec) RenderClaimsContractGo

func (s *Spec) RenderClaimsContractGo(varName string) (string, error)

func (*Spec) RenderClaimsContractTS

func (s *Spec) RenderClaimsContractTS(varName string) (string, error)

func (*Spec) ResourceAccessSurface

func (s *Spec) ResourceAccessSurface(object string) (*ResourceAccessSurface, error)

func (*Spec) RoleAssignmentSurface

func (s *Spec) RoleAssignmentSurface(rolestore string) (*RoleAssignmentSurface, error)

func (*Spec) SessionSetupSQL

func (s *Spec) SessionSetupSQL(local bool) []string

func (*Spec) SetRoleSQL

func (s *Spec) SetRoleSQL(local bool) string

func (*Spec) TableCoverage

func (s *Spec) TableCoverage(dbTables []string) TableCoverage

func (*Spec) TriggersSQL

func (s *Spec) TriggersSQL() string

func (*Spec) ValidateAgainst

func (s *Spec) ValidateAgainst(sc *Schema) error

func (*Spec) Vocabularies added in v0.64.0

func (s *Spec) Vocabularies() []VocabularyInfo
Example
s := exampleSpecForDoc()
for _, v := range s.Vocabularies() {
	fmt.Println(v.Name)
	for _, p := range v.Permissions {
		fmt.Printf("  %s parameterized=%v\n", p.Name, p.Parameterized)
	}
}
Output:
staff
  docs:read parameterized=false
  docs:write parameterized=false
  docs:publish parameterized=false
  docs:read:* parameterized=true
member
  self:read parameterized=false
  self:write parameterized=false
platform
  platform:manage parameterized=false

type Subject

type Subject struct {
	Name       string
	Anchor     string
	Reach      string
	Identifies string
	Membership *Membership
	Roles      string
	RolesNone  bool
	ReachGrant string

	Binds string
	Pos   Pos
}

type TableCoverage

type TableCoverage struct {
	Governed   []string
	Referenced []string
	Ungoverned []string
}

type Template

type Template struct {
	Name  string
	Perms []*Perm
	Pos   Pos
}

type Term

type Term struct {
	Ident      string
	WalkVerb   string
	Builtin    string
	SessionRel string

	ExcludeRel string

	ModeCol   string
	ModeVal   string
	ModeScope string

	GrantRef string

	KindVal string
	SelfCol string

	WithinLevel    string
	WithinNullable bool

	HoldsPerm string

	ExternalFn   string
	ExternalArgs []ExternalArg

	Pos Pos
}

func (*Term) String

func (t *Term) String() string

type Topology

type Topology struct {
	Levels []*Level
	Pos    Pos
}

func (*Topology) AncestorPath

func (t *Topology) AncestorPath(name string) ([]*Level, error)

func (*Topology) AncestorPaths

func (t *Topology) AncestorPaths(name string) ([][]*Level, error)

func (*Topology) Chain

func (t *Topology) Chain() ([]*Level, error)

func (*Topology) LevelByName

func (t *Topology) LevelByName(name string) *Level

type UngovEntry

type UngovEntry struct {
	Proc   string
	Reason string
	Pos    Pos
}

type Ungoverned

type Ungoverned struct {
	EmitSite string
	Entries  []UngovEntry
	Pos      Pos
}

type ViaClosure

type ViaClosure struct {
	Closure       string
	AncestorCol   string
	DescendantCol string
	Base          string
	BaseID        string
	BaseParent    string
	Col           string

	Claim   string
	Missing string
}

type ViaColumn

type ViaColumn struct {
	Column     string
	DiscrimCol string
	DiscrimVal string
}

type ViaComposition

type ViaComposition struct {
	Table     string
	ChildCol  string
	ParentCol string
	KindCol   string
	KindVal   string
}

type ViaEdge

type ViaEdge struct {
	Table string
	Cols  []string
}

type ViaGrant

type ViaGrant struct {
	Table        string
	RecordCol    string
	KindCol      string
	PrincipalCol string
	AccessCol    string
	DiscrimCol   string
	DiscrimVal   string

	// The optional membership hop: a grant row whose KindCol equals
	// GroupKindVal names a GROUP in PrincipalCol, and admits every principal
	// the closure lists as that group's member. The closure/edge pair is the
	// same machinery `via group` uses (transitive, trigger-maintained), so a
	// spec may share one closure between an audience column and group grants.
	GroupKindVal    string
	GroupClosure    string
	GroupGroupCol   string
	GroupMemberCol  string
	GroupEdge       string
	GroupEdgeMember string
	GroupEdgeGroup  string

	Tracked bool

	Async bool
}

func (*ViaGrant) EdgeTable

func (e *ViaGrant) EdgeTable() string

func (*ViaGrant) GranteeColumn

func (e *ViaGrant) GranteeColumn() string

func (*ViaGrant) Granularity

func (e *ViaGrant) Granularity() GrantGranularity

type ViaGroup

type ViaGroup struct {
	Closure    string
	GroupCol   string
	MemberCol  string
	Edge       string
	EdgeMember string
	EdgeGroup  string
	Col        string

	Materialized bool
}

type ViaMemberIn

type ViaMemberIn struct {
	Level       string
	Principal   ArgSrc
	Scope       ArgSrc
	ReachedBy   bool
	ReachMember bool
}

type ViaObject

type ViaObject struct {
	Object string
	Verb   string
	Col    string
	Op     string
}

type ViaRole

type ViaRole struct {
}

type Vocabulary

type Vocabulary struct {
	Name         string
	Permissions  []string
	Implications []*Implication
	Presets      []*Preset
	Rank         []string
	Pos          Pos
}

func (*Vocabulary) CapGrant

func (v *Vocabulary) CapGrant(held, requested []string) DelegationCap

func (*Vocabulary) ExpandImplications added in v0.76.0

func (v *Vocabulary) ExpandImplications(perms []string) ([]string, error)

func (*Vocabulary) HasPermission added in v0.72.0

func (v *Vocabulary) HasPermission(perm string) bool

func (*Vocabulary) ImpliedPermissions added in v0.76.0

func (v *Vocabulary) ImpliedPermissions(perm string) ([]string, error)

func (*Vocabulary) PresetPermissions

func (v *Vocabulary) PresetPermissions(name string) ([]string, error)

func (*Vocabulary) PresetsAtOrAbove

func (v *Vocabulary) PresetsAtOrAbove(threshold string) []string

func (*Vocabulary) RankOf

func (v *Vocabulary) RankOf(preset string) (int, bool)

type VocabularyInfo added in v0.64.0

type VocabularyInfo struct {
	Name        string
	Permissions []PermissionInfo
}

type Zookie

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

func ParseZookie

func ParseZookie(s string) (Zookie, error)

func ZookieFromXid

func ZookieFromXid(x uint64) Zookie

func (Zookie) Reflects

func (watermark Zookie) Reflects(writer Zookie) bool

func (Zookie) String

func (z Zookie) String() string

Directories

Path Synopsis
cmd
demesne module
examples
pgx module

Jump to

Keyboard shortcuts

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