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 ¶
- Variables
- func AuthorityGoMigration(version uint) (migrations.Migration, error)
- func GoMigration() (migrations.Migration, error)
- func RequireAuthority[R AuthorityRows](ctx context.Context, q AuthorityQueryer[R], scope AuthorityScope, ...) error
- type AuthorityQueryer
- type AuthorityRecord
- type AuthorityRows
- type AuthorityScope
- type AuthorityStore
- type Migration
- type Store
Constants ¶
This section is empty.
Variables ¶
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 = errors.New("authorization authority unavailable") )
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
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
func (s *AuthorityStore) Get(ctx context.Context, scope AuthorityScope) (AuthorityRecord, error)
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
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 (*Store) Load ¶
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.