Documentation
¶
Overview ¶
Package postgres persists session credentials through Foundry-owned PostgreSQL models and explicit migrations. It borrows an existing pool and never migrates or connects during construction.
Index ¶
- Constants
- func Migrations() []migrate.Definition
- type Backend
- func (b *Backend) Confirm(ctx context.Context, address session.Address, identity model.Identity, ...) (value.Optional[session.Record], error)
- func (b *Backend) ConfirmedWithin(ctx context.Context, address session.Address, identity model.Identity, ...) (bool, error)
- func (b *Backend) ConsumePendingIn(ctx context.Context, tx *database.Tx, address session.Address, ...) error
- func (b *Backend) Create(ctx context.Context, address session.Address, creation session.Creation) (session.Record, error)
- func (b *Backend) CreateBefore(ctx context.Context, address session.Address, creation session.Creation, ...) (session.Record, error)
- func (b *Backend) CreateChecked(ctx context.Context, address session.Address, creation session.Creation, ...) (session.Record, error)
- func (b *Backend) List(ctx context.Context, address session.Address, identity model.Identity, ...) ([]session.Record, error)
- func (b *Backend) Lookup(ctx context.Context, address session.Address, hash session.Digest, touch bool) (value.Optional[session.Record], error)
- func (b *Backend) Prune(ctx context.Context, address session.Address, limit int) (uint64, error)
- func (b *Backend) ResumeActor(ctx context.Context, address session.Address, expected session.Record, ...) (value.Optional[session.Record], error)
- func (b *Backend) Revoke(ctx context.Context, address session.Address, hash session.Digest) (bool, error)
- func (b *Backend) RevokeAll(ctx context.Context, address session.Address, identity model.Identity) (uint64, error)
- func (b *Backend) RevokeAllIn(ctx context.Context, tx *database.Tx, address session.Address, ...) (uint64, error)
- func (b *Backend) RevokeID(ctx context.Context, address session.Address, identity model.Identity, ...) (bool, error)
- func (b *Backend) RevokeOthers(ctx context.Context, address session.Address, identity model.Identity, ...) (uint64, error)
- func (b *Backend) Rotate(ctx context.Context, address session.Address, old, next session.Digest) (value.Optional[session.Record], error)
- type Config
Constants ¶
const ( MigrationOrigin migrate.Origin = "foundry.sessions" CreateSessions migrate.ID = "000001_create_sessions" AddSessionState migrate.ID = "000002_session_device_confirmation" AddImpersonator migrate.ID = "000003_session_impersonation" ValidateState migrate.ID = "000004_validate_session_state" Introduced migrate.Version = "v0.1.0" )
Variables ¶
This section is empty.
Functions ¶
func Migrations ¶
func Migrations() []migrate.Definition
Migrations returns owned historical definitions. Run them explicitly in the same schema as Config.Schema using the ordinary migration runner. No existing table/data is dropped or reset, and construction never auto-synchronizes schema.
Types ¶
type Backend ¶
type Backend struct {
// contains filtered or unexported fields
}
Backend persists authoritative sessions in PostgreSQL using a borrowed database pool.
func (*Backend) Confirm ¶
func (b *Backend) Confirm(ctx context.Context, address session.Address, identity model.Identity, id model.ID[session.Record]) (value.Optional[session.Record], error)
Confirm stamps confirmed_at on one live, fully authenticated session of the subject with a conditional UPDATE, then returns its current record.
func (*Backend) ConfirmedWithin ¶
func (b *Backend) ConfirmedWithin(ctx context.Context, address session.Address, identity model.Identity, id model.ID[session.Record], within time.Duration) (bool, error)
ConfirmedWithin reports whether the live session confirmed its password at or after now-within, using this backend's clock.
func (*Backend) ConsumePendingIn ¶
func (b *Backend) ConsumePendingIn(ctx context.Context, tx *database.Tx, address session.Address, expected session.Record) error
ConsumePendingIn deletes only the exact, still-live pending credential under its subject lock. The caller already holds model/factor locks. Pool ownership and schema restoration follow the shared savepoint boundary. Nothing commits.
func (*Backend) Create ¶
func (b *Backend) Create(ctx context.Context, address session.Address, creation session.Creation) (session.Record, error)
Create atomically creates a session under the subject lock and enforces credential capacity.
func (*Backend) CreateBefore ¶
func (b *Backend) CreateBefore(ctx context.Context, address session.Address, creation session.Creation, deadline temporal.DateTime, check func(context.Context, *database.Tx) error) (session.Record, error)
CreateBefore uses ordinary creation and rechecks the existing credential's deadline after insertion, before the transaction returns to commit. Expiry rolls back the inserted credential and all joined factor/consumption writes.
func (*Backend) CreateChecked ¶
func (b *Backend) CreateChecked(ctx context.Context, address session.Address, creation session.Creation, check func(context.Context, *database.Tx) error) (session.Record, error)
CreateChecked runs check before credential locks and creates the session in the same transaction, without retries.
func (*Backend) List ¶
func (b *Backend) List(ctx context.Context, address session.Address, identity model.Identity, limit int) ([]session.Record, error)
List reads the subject's live sessions in one statement without locking the subject, so listing never blocks issuance or request authentication.
func (*Backend) Lookup ¶
func (b *Backend) Lookup(ctx context.Context, address session.Address, hash session.Digest, touch bool) (value.Optional[session.Record], error)
Lookup is the per-request read path: one schema-qualified statement joins the session and its subject without a transaction or row lock, so parallel requests, listings, pruning and revocation never serialize on the subject. Expiry is checked against the clock sampled after the read. A sliding session records activity only when it is older than TouchInterval, with one conditional UPDATE that cannot revive a removed, rotated or expired row. A revocation committing concurrently with this read applies from the next scope.
func (*Backend) Prune ¶
Prune deletes at most limit expired sessions of this address in one set-based, index-backed statement. Rows locked by concurrent work are skipped, and expiry is rechecked on the row actually deleted, so a session touched meanwhile survives. Subject rows remain for serialization.
func (*Backend) ResumeActor ¶
func (b *Backend) ResumeActor(ctx context.Context, address session.Address, expected session.Record, next session.Digest, check func(context.Context, *database.Tx) error) (value.Optional[session.Record], error)
ResumeActor rotates the exact live actor session in place after impersonation. The check runs first in the transaction; the subject and row are then locked in the order shared by every session writer, and the record is revalidated against expected before its secret is replaced.
func (*Backend) Revoke ¶
func (b *Backend) Revoke(ctx context.Context, address session.Address, hash session.Digest) (bool, error)
Revoke atomically deletes the session matching hash and reports whether it existed.
func (*Backend) RevokeAll ¶
func (b *Backend) RevokeAll(ctx context.Context, address session.Address, identity model.Identity) (uint64, error)
RevokeAll atomically removes the subject's sessions and returns the count.
func (*Backend) RevokeAllIn ¶
func (b *Backend) RevokeAllIn(ctx context.Context, tx *database.Tx, address session.Address, identity model.Identity) (uint64, error)
RevokeAllIn returns a provisional count: only the caller's outer transaction can commit. It rejects a transaction from another pool and scopes schema changes inside a savepoint. The original standalone method reuses the same row logic.
func (*Backend) RevokeID ¶
func (b *Backend) RevokeID(ctx context.Context, address session.Address, identity model.Identity, id model.ID[session.Record]) (bool, error)
RevokeID locks the subject and removes the identified session, reporting whether it existed.
func (*Backend) RevokeOthers ¶
func (b *Backend) RevokeOthers(ctx context.Context, address session.Address, identity model.Identity, keep model.ID[session.Record]) (uint64, error)
RevokeOthers removes every session of the subject except keep, under the subject lock. A missing subject has nothing to revoke.
type Config ¶
Config explicitly selects the schema used by both migrations and runtime. Clock is server-side application time, sampled after taking a subject lock. Instances sharing a store need synchronized clocks. Tests may inject testkit.Clock.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the public schema and system clock.