Help us shape the future of Go! Take the 2026 Go Developer Survey

postgres

package
v3.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 22, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package postgres persists a complete manifest in one PostgreSQL singleton row. New borrows pgxpool; Update uses one conditional SQL statement to match expected revision and store a newer manifest. It does not authorize publishers, run schema migrations, retry failures, invalidate caches or close the pool. Public revisions are uint64 but the schema uses signed bigint; select a compatible range. Driver responses materialize before policy.Decode byte admission. Database errors can contain sensitive diagnostics, and failures may require reconciliation when a write committed but response/decoding failed. No DB qualification is implied.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrInvalidAuthority denotes malformed scope, version, duration or handle.
	ErrInvalidAuthority = errors.New("invalid authorization authority input")
	// ErrAuthorityDenied covers both absent and mismatched authority, without
	// disclosing whether an unrelated principal exists.
	ErrAuthorityDenied = errors.New("authorization authority denied")
	// ErrAuthorityConflict denotes an initialization or expected-epoch CAS conflict.
	ErrAuthorityConflict = errors.New("authorization authority conflict")
	// ErrAuthorityOverflow is terminal; authority must never wrap or reset.
	ErrAuthorityOverflow = errors.New("authorization authority exhausted")
	// ErrAuthorityUnavailable redacts database, schema and corrupt-row failures.
	ErrAuthorityUnavailable = errors.New("authorization authority unavailable")
)
View Source
var (
	// ErrNilPool identifies authorization postgres pool is nil. Compare with errors.Is, not error text.
	ErrNilPool = errors.New("authorization postgres pool is nil")
	// ErrNotInitialized identifies authorization policy is not initialized. Compare with errors.Is, not error text.
	ErrNotInitialized = errors.New("authorization policy is not initialized")
	// ErrRevisionConflict identifies authorization policy revision conflict. Compare with errors.Is, not error text.
	ErrRevisionConflict = errors.New("authorization policy revision conflict")
	// ErrRevisionNotMonotonic identifies authorization policy revision is not monotonic. Compare with errors.Is, not error text.
	ErrRevisionNotMonotonic = errors.New("authorization policy revision is not monotonic")
)

Functions

func AuthorityGoMigration added in v3.1.0

func AuthorityGoMigration(version uint) (migrations.Migration, error)

AuthorityGoMigration adapts the separately allocated forward-only authority migration to the existing owned migrations library. Historical v1 bytes and legacy manifest APIs are unchanged; no implicit dependency on identity exists.

func GoMigration

func GoMigration() (migrations.Migration, error)

GoMigration binds the SQL to go-migrations/v2 default transaction policy; it creates a definition, not a database migration execution.

func RequireAuthority added in v3.1.0

func RequireAuthority[R AuthorityRows](ctx context.Context, q AuthorityQueryer[R], scope AuthorityScope, expected uint64, maximumDuration time.Duration) error

RequireAuthority compares exact current authority under a primary share lock retained until the original transaction owner commits/aborts. Missing or any unequal epoch denies, including a future expected value. No row/version is created or refreshed and no policy decision, proof or session is issued. The trusted native adapter must poison/abort its Work on every error, including ignored denial; passing an independent pool cannot prove protected admission.

Types

type AuthorityQueryer added in v3.1.0

type AuthorityQueryer[R AuthorityRows] interface {
	// Query honors the bounded context and returns an owned cursor to close.
	Query(context.Context, string, ...any) (R, error)
}

AuthorityQueryer supplies one trusted owner's synchronous query capability. The generic row type preserves narrower generation-bound cursors without importing identity or exposing raw connections. Protected operations require a real borrowed transaction, never a pool/autocommit or replica. The owner must fence participant scope/lifetime and abort/poison on any returned error. Methods below never retain this handle or begin/commit/rollback a transaction.

type AuthorityRecord added in v3.1.0

type AuthorityRecord struct {
	// Scope is the exact primary row identity, not caller-selected authority.
	Scope AuthorityScope
	// Version is its positive epoch; zero never represents initialized authority.
	Version uint64
}

AuthorityRecord is a structural primary projection of one positive uint64 epoch. It is neither a policy decision nor freshness evidence, and must not be promoted into a renewable positive-cache lease.

func AdvanceAuthority added in v3.1.0

func AdvanceAuthority[R AuthorityRows](ctx context.Context, q AuthorityQueryer[R], scope AuthorityScope, expected uint64, maximumDuration time.Duration) (AuthorityRecord, error)

AdvanceAuthority stages one exact expected-epoch successor under row locking. Role/statement/policy/entitlement mutation and required audit must share this transaction. Missing/stale scopes conflict; MaxUint64 fails terminally before SQL. Restore/import cannot reset authority. This is not a standalone admin workflow: caller authorization, immutable intent and recovery remain owned by the existing coordinator. A returned record is provisional, not commit proof.

func InitializeAuthority added in v3.1.0

func InitializeAuthority[R AuthorityRows](ctx context.Context, q AuthorityQueryer[R], scope AuthorityScope, maximumDuration time.Duration) (AuthorityRecord, error)

InitializeAuthority stages explicit trusted bootstrap at epoch one. Existing scopes return Conflict, including newer epochs: bootstrap never resets them. The returned projection is provisional until the owner proves commit. The owner must authorize bootstrap and abort on error; reads never call this API.

func (AuthorityRecord) Format added in v3.1.0

func (AuthorityRecord) Format(s fmt.State, _ rune)

Format hides internal scope/version correlation.

func (AuthorityRecord) MarshalJSON added in v3.1.0

func (AuthorityRecord) MarshalJSON() ([]byte, error)

MarshalJSON rejects accidental authority projection export.

type AuthorityRows added in v3.1.0

type AuthorityRows interface {
	// Next advances the borrowed cursor and reports whether a row is available.
	Next() bool
	// Scan copies the current row into supplied destinations without retaining them.
	Scan(...any) error
	// Err reports iteration failures after Next returns false.
	Err() error
	// Close drains or cancels this cursor without closing the owning transaction.
	Close()
}

AuthorityRows is the minimum synchronous borrowed cursor contract. Implemented by pgx.Rows and identity's generation-bound WorkRows. Close must drain or cancel the result without terminalizing the owning transaction.

type AuthorityScope added in v3.1.0

type AuthorityScope struct {
	// TenantID is the exact tenant isolation boundary, not a defaultable label.
	TenantID authorization.TenantID
	// PolicyNamespace is a trusted domain in which SubjectID is unambiguous.
	PolicyNamespace string
	// SubjectID is the exact lifecycle subject within tenant and namespace.
	SubjectID authorization.SubjectID
}

AuthorityScope identifies one lifecycle epoch independently of policy revision. Every component is an exact 1..128-byte UTF-8 opaque ID, with ASCII whitespace and controls forbidden. No normalization occurs. PolicyNamespace must select a domain in which SubjectID is unique across subject kinds; an untrusted Subject.Kind or attribute cannot select that domain. Zero is invalid.

func (AuthorityScope) Format added in v3.1.0

func (AuthorityScope) Format(s fmt.State, _ rune)

Format redacts internal correlation scope in diagnostics.

func (AuthorityScope) Key added in v3.1.0

func (s AuthorityScope) Key() (string, error)

Key returns a stable version-one session-vector binding, not an authorization decision or private identifier. SHA-256 hashes the fixed domain followed by the three exact UTF-8 components, each framed with its big-endian uint16 byte length, in tenant/namespace/subject order. The unpadded base64url digest fits bounded snapshot keys; owner lookups still compare all three original IDs. Hashing avoids ambiguous delimiter joins, not correlation or disclosure.

func (AuthorityScope) MarshalJSON added in v3.1.0

func (AuthorityScope) MarshalJSON() ([]byte, error)

MarshalJSON rejects accidental scope export.

func (AuthorityScope) Validate added in v3.1.0

func (s AuthorityScope) Validate() error

Validate checks the complete scope without reading or provisioning authority.

type AuthorityStore added in v3.1.0

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

AuthorityStore borrows a primary pool for structural reads only. Concurrent reads are safe; the caller retains pool shutdown ownership. Zero is invalid.

func NewAuthorityStore added in v3.1.0

func NewAuthorityStore(pool *pgxpool.Pool, maximumDuration time.Duration) (*AuthorityStore, error)

NewAuthorityStore requires a primary pool and finite 0..1-minute read budget. Earlier caller deadlines win. The constructor performs no IO or bootstrap.

func (*AuthorityStore) Get added in v3.1.0

Get reads the exact primary scope without locks or implicit initialization. Missing authority denies; corrupt/storage errors are redacted. Cancellation preserves context errors. No policy decision or validity lease is returned.

type Migration

type Migration struct {
	// Version is caller-owned migration ordering; SchemaMigration returns 1.
	Version uint
	// Name is the exact application label; do not place secrets in error-visible names.
	Name string
	// Up is forward SQL; SchemaMigration supplies singleton-table creation.
	Up string
	// Down is reverse SQL; SchemaMigration supplies a destructive table drop.
	Down string
}

Migration is caller-owned executable schema SQL metadata; it is not applied here.

func AuthoritySchemaMigration added in v3.1.0

func AuthoritySchemaMigration(version uint) (Migration, error)

AuthoritySchemaMigration appends opt-in scoped lifecycle epoch storage without altering the released v1 manifest schema. Allocate a permanent version later than every existing application migration (at least 2). It bootstraps no rows. Downgrade is deliberately absent: dropping/recreating authority could reset epochs and resurrect old artifacts. Restore must preserve all authoritative rows or use the platform's explicit compromise/invalidation procedure.

func SchemaMigration

func SchemaMigration() Migration

SchemaMigration returns version-1 singleton-table SQL. Down irreversibly drops policy data; caller migration policy owns transactions/deployment/rollback.

type Store

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

Store borrows a pgx query seam; construct with New, keep schema/pool lifecycle valid and use contexts with deadlines. The zero value is unusable.

func New

func New(pool *pgxpool.Pool) (*Store, error)

New borrows a non-nil pool without opening/migrating/closing it.

func (*Store) Load

func (store *Store) Load(ctx context.Context) (policy.Manifest, error)

Load reads/decodes the singleton manifest, mapping no rows to ErrNotInitialized. It trusts database content and does not cross-check JSON revision against the separate SQL revision column. Row materialization precedes parser admission; raw driver diagnostics remain caller-protected.

func (*Store) Update

func (store *Store) Update(
	ctx context.Context,
	expected authorization.Revision,
	next policy.Manifest,
) (policy.Manifest, error)

Update validates/encodes next, then conditionally writes one newer revision under expected (zero for initialization). No rows is conflict; raw query errors or post-write decode errors can leave commit state uncertain. Reconcile with Load before repeating unknown outcomes. Revisions must fit SQL bigint; caller graphs are borrowed during encode. No retry/invalidation is owned.

Jump to

Keyboard shortcuts

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