Documentation
¶
Overview ¶
Package mfa owns typed TOTP/recovery factors and model-first factor management. Its manager rechecks passwords, locks models before factors, applies a separate MFA throttle, and persists replay/consumption with model changes and credential revocation. PostgreSQL stores encrypted TOTP secrets through explicit migrations. Management never issues authenticated credentials. TOTP uses six-digit HMAC-SHA1 with a 30-second period; inputs and results preserve model and factor types.
Index ¶
- Constants
- func ProvisioningURI(key TOTPSecret, issuer, account string) (secret.String, error)
- type Action
- type Address
- type Backend
- type Change
- type Config
- type Enrollment
- func (e Enrollment[M]) CreatedAt() temporal.DateTime
- func (e Enrollment[M]) ExpiresAt() temporal.DateTime
- func (Enrollment[M]) Format(s fmt.State, _ rune)
- func (e Enrollment[M]) ID() EnrollmentID[M]
- func (e Enrollment[M]) Secret() TOTPSecret
- func (e Enrollment[M]) Subject() M
- func (e Enrollment[M]) URI() secret.String
- type EnrollmentID
- type Factors
- func (f *Factors[M, K]) Confirm(ctx context.Context, password auth.PasswordResult[M, K], id EnrollmentID[M], ...) (RecoveryCodes[M], error)
- func (f *Factors[M, K]) Disable(ctx context.Context, password auth.PasswordResult[M, K], response Response) (M, error)
- func (f *Factors[M, K]) Enroll(ctx context.Context, password auth.PasswordResult[M, K]) (Enrollment[M], error)
- func (f *Factors[M, K]) HasEnrolledFactor(_ context.Context, subject M) (bool, error)
- func (f *Factors[M, K]) Prune(ctx context.Context, limit int) (uint64, error)
- func (f *Factors[M, K]) Reencrypt(ctx context.Context, password auth.PasswordResult[M, K], response Response) error
- func (f *Factors[M, K]) RegenerateRecovery(ctx context.Context, password auth.PasswordResult[M, K], response Response) (RecoveryCodes[M], error)
- func (f *Factors[M, K]) RetireIn(ctx context.Context, parent *database.Tx, reference model.Reference[M, K]) (M, error)
- func (f *Factors[M, K]) Validate() error
- func (f *Factors[M, K]) Verifier(response Response) (auth.SecondFactor[M, K], error)
- func (f *Factors[M, K]) WithObserver(observer Observer[M, K]) (*Factors[M, K], error)
- type Model
- type Notice
- type Observer
- type Record
- type RecoveryCode
- func (RecoveryCode) Format(s fmt.State, _ rune)
- func (RecoveryCode) JSONContract() contract.JSON[RecoveryCode]
- func (RecoveryCode) LogValue() slog.Value
- func (RecoveryCode) MarshalJSON() ([]byte, error)
- func (c RecoveryCode) Secret() secret.String
- func (c *RecoveryCode) UnmarshalJSON(data []byte) error
- func (c RecoveryCode) Validate() error
- type RecoveryCodes
- type RecoveryHash
- type Response
- type Rotation
- type RotationBackend
- type RotationCursor
- type Store
- type StoredCiphertext
- type TOTPCode
- func (TOTPCode) Format(s fmt.State, _ rune)
- func (TOTPCode) JSONContract() contract.JSON[TOTPCode]
- func (TOTPCode) LogValue() slog.Value
- func (TOTPCode) MarshalJSON() ([]byte, error)
- func (c TOTPCode) Secret() secret.String
- func (c *TOTPCode) UnmarshalJSON(data []byte) error
- func (c TOTPCode) Validate() error
- type TOTPSecret
- type TransactionalBackend
Constants ¶
const DefaultRecoveryCodes = 10
const MaxEnrollmentLifetime = time.Hour
const MaxPrune = 128
const MaxRecoveryCodes = 16
const MaxRotationBatch = 256
MaxRotationBatch bounds the factors examined by one ReencryptStale call.
Variables ¶
This section is empty.
Functions ¶
func ProvisioningURI ¶
func ProvisioningURI(key TOTPSecret, issuer, account string) (secret.String, error)
ProvisioningURI constructs the otpauth URI for an authenticated enrollment response or local QR renderer. The URI contains the TOTP secret; never pass it to a remote QR-generation service, analytics or logging. Issuer/account labels must be nonempty, bounded, colon-free UTF-8 without control characters.
Types ¶
type Action ¶
type Action string
Action identifies an MFA security observation, never a credential or authority.
type Address ¶
type Address struct {
Namespace keyspace.Namespace
Provider auth.ProviderName
Model string
}
Address is the persistence boundary. A model/provider shares one TOTP factor across its guards; guard names do not create independent factor enrollments.
func (Address) SubjectKey ¶
SubjectKey returns the subject's opaque key within the validated MFA address.
type Backend ¶
type Backend interface {
// Within prepares the model lock, reads the factor and applies one change in an owned
// transaction without retries.
Within(context.Context, Address, model.Identity, func(context.Context, *database.Tx) error, func(context.Context, *database.Tx, value.Optional[Record], temporal.DateTime) (Change, error)) (value.Optional[Record], error)
// Prune deletes at most limit expired pending factors without acquiring model locks.
Prune(context.Context, Address, int) (uint64, error)
}
Backend owns one read-committed transaction. Within invokes prepare exactly once to lock the application model BEFORE reading/locking the factor record. That model lock serializes creation even when no factor row exists. It then calls change once with owned state and server time, validates its result and deadline, persists it and commits. Callback errors, panic/Goexit or cancellation roll back all database changes. Never suppress failures, detach callbacks, retry mutations or acquire model locks after factor/credential locks.
Callbacks use only the supplied transaction for database writes. The runtime may consult its bounded MFA lockout store before protected writes; external effects (email, publishing) require an outbox. After-commit failure may retain a Committed database outcome; an error is not permission to retry blindly. Prune deletes only expired pending factors and acquires no model locks.
type Change ¶
type Change struct {
// contains filtered or unexported fields
}
Change explicitly selects replacement or removal. Zero is invalid. Before adds a strict pre-commit deadline, used to prevent late enrollment confirmation.
func (Change) Next ¶
Next returns an owned clone of the replacement record, or omission for a removal or undefined change.
type Config ¶
type Config struct {
Namespace keyspace.Namespace
Issuer string
EnrollmentLifetime time.Duration
Window int
RecoveryCodes int
MaxConcurrent int
Timeout time.Duration
}
Config declares the MFA namespace, issuer, enrollment and verification policy, and operation bounds.
func DefaultConfig ¶
DefaultConfig returns default enrollment, TOTP-window, recovery-code and operation bounds for namespace and issuer.
type Enrollment ¶
type Enrollment[M any] struct { // contains filtered or unexported fields }
Enrollment is returned only after the pending encrypted factor commits. Secret and URI are explicit disclosure boundaries for the enrolled account.
func (Enrollment[M]) CreatedAt ¶
func (e Enrollment[M]) CreatedAt() temporal.DateTime
CreatedAt returns the enrollment's creation time.
func (Enrollment[M]) ExpiresAt ¶
func (e Enrollment[M]) ExpiresAt() temporal.DateTime
ExpiresAt returns the pending enrollment's confirmation deadline.
func (Enrollment[M]) Format ¶
func (Enrollment[M]) Format(s fmt.State, _ rune)
Format writes the label "MFA enrollment" without exposing the value.
func (Enrollment[M]) ID ¶
func (e Enrollment[M]) ID() EnrollmentID[M]
ID returns the model-owned enrollment identifier.
func (Enrollment[M]) Secret ¶
func (e Enrollment[M]) Secret() TOTPSecret
Secret exposes the enrollment's TOTP key for authenticated delivery.
func (Enrollment[M]) Subject ¶
func (e Enrollment[M]) Subject() M
Subject returns the enrollment's model snapshot without cloning it.
func (Enrollment[M]) URI ¶
func (e Enrollment[M]) URI() secret.String
URI exposes the secret provisioning URI for authenticated delivery.
type EnrollmentID ¶
type EnrollmentID[M any] struct { // contains filtered or unexported fields }
EnrollmentID preserves the model type. Parsing identifies a pending factor; it does not authenticate or authorize confirmation.
func ParseEnrollmentID ¶
func ParseEnrollmentID[M any](text string) (EnrollmentID[M], error)
ParseEnrollmentID parses a nonzero enrollment identifier retaining model ownership.
func (EnrollmentID[M]) IsZero ¶
func (id EnrollmentID[M]) IsZero() bool
IsZero reports whether the enrollment identifier is uninitialized.
func (EnrollmentID[M]) JSONContract ¶
func (EnrollmentID[M]) JSONContract() contract.JSON[EnrollmentID[M]]
JSONContract describes the model-owned enrollment identifier as a UUID string.
func (EnrollmentID[M]) MarshalJSON ¶
func (id EnrollmentID[M]) MarshalJSON() ([]byte, error)
MarshalJSON preserves the public enrollment identifier; it is not a secret or proof. The model owner remains part of its Go type and generated contract.
func (EnrollmentID[M]) String ¶
func (id EnrollmentID[M]) String() string
String returns the enrollment identifier's text representation.
func (*EnrollmentID[M]) UnmarshalJSON ¶
func (id *EnrollmentID[M]) UnmarshalJSON(data []byte) error
UnmarshalJSON clears the receiver and parses a bounded JSON string as a nonzero enrollment identifier.
type Factors ¶
type Factors[M model.Identifiable, K any] struct { // contains filtered or unexported fields }
Factors owns one model/provider's TOTP factor across guards. A separate typed MFA throttle is mandatory; never reuse the password-attempt declaration.
func New ¶
func New[M model.Identifiable, K any](store *Store, provider auth.Provider[M, K], binding Model[M, K], attempts lockout.Throttle[K]) (*Factors[M, K], error)
New validates the store, provider, model callbacks and lockout throttle and creates a typed factor binding.
func (*Factors[M, K]) Confirm ¶
func (f *Factors[M, K]) Confirm(ctx context.Context, password auth.PasswordResult[M, K], id EnrollmentID[M], code TOTPCode) (RecoveryCodes[M], error)
Confirm accepts only a TOTP code for the current unexpired enrollment. The accepted step, recovery hashes, model flag and all credential revocations commit together. The result is not an authenticated proof or a login response.
func (*Factors[M, K]) Disable ¶
func (f *Factors[M, K]) Disable(ctx context.Context, password auth.PasswordResult[M, K], response Response) (M, error)
Disable requires a rechecked password, current TOTP/recovery factor and domain permission. Factor removal, model mutation and credential revocation share tx.
func (*Factors[M, K]) Enroll ¶
func (f *Factors[M, K]) Enroll(ctx context.Context, password auth.PasswordResult[M, K]) (Enrollment[M], error)
Enroll replaces only an unconfirmed enrollment. The password result is rechecked under the model lock. An enabled/confirmed factor must be verified and disabled first; an ordinary session or bare model reference cannot enroll.
func (*Factors[M, K]) HasEnrolledFactor ¶
HasEnrolledFactor reports the model's stored enabled state. It implements auth.EnrolledFactors for PasswordLogin.WithSecondFactor and performs no I/O.
func (*Factors[M, K]) Prune ¶
Prune removes a bounded batch of expired, unconfirmed enrollments only. Confirmed factors and application models are never deleted by maintenance.
func (*Factors[M, K]) Reencrypt ¶
func (f *Factors[M, K]) Reencrypt(ctx context.Context, password auth.PasswordResult[M, K], response Response) error
Reencrypt requires password/factor verification, preserves the enrollment ID and recovery set (apart from the code used), and encrypts with the active key. It does not change MFA policy or issue credentials. Retain old keys until every stored factor has migrated; this operation cannot recover a lost key.
func (*Factors[M, K]) RegenerateRecovery ¶
func (f *Factors[M, K]) RegenerateRecovery(ctx context.Context, password auth.PasswordResult[M, K], response Response) (RecoveryCodes[M], error)
RegenerateRecovery verifies a current factor, replaces the complete recovery set and revokes registered credentials atomically. No old recovery code survives.
func (*Factors[M, K]) RetireIn ¶
func (f *Factors[M, K]) RetireIn(ctx context.Context, parent *database.Tx, reference model.Reference[M, K]) (M, error)
RetireIn is an explicitly authorized administrative operation for account retirement. It locks the existing model, removes its pending/confirmed factor, clears Enabled and invalidates every registered credential in the supplied transaction. Delete/retire the domain model in that same transaction AFTER this call. It accepts disabled accounts; it does not bypass a missing model or authenticate the caller. Enforce an administrative policy before invoking it.
Unlike Disable this does not require the retiring user's password/factor or CanDisable permission. Never expose it as an unauthenticated self-service endpoint. Returned state is provisional until outer commit. Rollback restores model, factor and credentials. Do not reuse account keys without retirement.
func (*Factors[M, K]) Verifier ¶
func (f *Factors[M, K]) Verifier(response Response) (auth.SecondFactor[M, K], error)
Verifier binds one typed TOTP/recovery response for Sessions.CompleteMFA or Tokens.CompleteMFA. It performs no I/O and grants no authority. Completion locks/resolves the current model once, checks its eligibility and enabled factor, consumes the pending credential and verifies the second factor in the credential creation transaction. A failure rolls back all provisional writes.
func (*Factors[M, K]) WithObserver ¶
WithObserver returns an immutable view. Register at most once; callbacks must respect cancellation and shared-state concurrency. Notices are not delivery receipts: outbox durability begins only when the enclosing transaction commits.
type Model ¶
type Model[M model.Identifiable, K any] struct { Lock func(context.Context, *database.Tx, K) (value.Optional[M], error) Enabled func(M) bool SetEnabled func(context.Context, *database.Tx, M, bool) (M, error) AccountLabel func(M) (string, error) CanDisable func(context.Context, M) (bool, error) Invalidate func(context.Context, *database.Tx, M) error }
Model maps stored fields and normal generated mutations to MFA. Lock uses a generated ForUpdate query on the supplied transaction and preserves K. SetEnabled returns the complete updated model and must preserve identity. Invalidate joins tx (for example auth.Revocations.Invalidate) and revokes every registered credential guard. CanDisable enforces required-factor domain policy. Link the factors to login with PasswordLogin.WithSecondFactor(factors): an enrolled model then always requires MFA, whatever RequiresMFA returns. Callbacks must not commit, retry, send external messages or acquire other pools.
type Notice ¶
Notice exposes only the affected typed reference and action. It contains no model snapshot, password, factor secret, submitted code or credential. The initiator remains attribution.FromContext(ctx); affected subject is not actor.
type Observer ¶
type Observer[M any, K any] struct { Changed func(context.Context, *database.Tx, Notice[M, K]) error Rejected func(context.Context, Notice[M, K]) error }
Observer maps MFA observations to application-owned event DTOs. Changed runs inside the mutation transaction: use events.Topic.Enqueue for durable dispatch, events.Topic.AfterCommit for process-local dispatch, or audit through this tx. Never perform external I/O there. Failure rolls back factor/model/credentials. Rejected is an immediate, process-local observation of a nonmatching factor or confirmed lockout. The enclosing mutation rolls back; do not persist a rejection through that transaction. No callback runs for malformed input, absent/inactive factors, missing models or infrastructure failures. Rejected errors remain causes of the denial and cannot turn it into success.
type Record ¶
type Record struct {
ID model.ID[Record]
Address Address
Subject model.Identity
Ciphertext encryption.Ciphertext
CreatedAt temporal.DateTime
PendingUntil value.Optional[temporal.DateTime]
ConfirmedAt value.Optional[temporal.DateTime]
LastStep value.Optional[int64]
RecoveryHashes []RecoveryHash
}
Record is the trusted storage-adapter boundary, never a transport DTO. A pending record has an expiry but no confirmation, replay step or recovery hashes. A confirmed record has no pending expiry. ID changes on reenrollment.
func (Record) LogValue ¶
LogValue returns a factor label without exposing stored secrets or metadata.
func (Record) MarshalJSON ¶
MarshalJSON encodes the redaction marker without exposing the value.
type RecoveryCode ¶
type RecoveryCode struct {
// contains filtered or unexported fields
}
RecoveryCode is a distinct canonical 256-bit random factor encoded as 43 unpadded base64url characters. It is not a password, TOTP code or proof. Only the digest is persisted; consumption must be atomic with factor completion.
func ParseRecoveryCode ¶
func ParseRecoveryCode(raw secret.String) (RecoveryCode, error)
ParseRecoveryCode checks recovery-secret syntax without verifying that the code is stored or unused.
func (RecoveryCode) Format ¶
func (RecoveryCode) Format(s fmt.State, _ rune)
Format writes the redaction marker without exposing the value.
func (RecoveryCode) JSONContract ¶
func (RecoveryCode) JSONContract() contract.JSON[RecoveryCode]
JSONContract describes recovery-code input as a JSON string; ordinary output remains redacted.
func (RecoveryCode) LogValue ¶
func (RecoveryCode) LogValue() slog.Value
LogValue returns the redaction marker without exposing the value.
func (RecoveryCode) MarshalJSON ¶
func (RecoveryCode) MarshalJSON() ([]byte, error)
MarshalJSON encodes the redaction marker without exposing the value.
func (RecoveryCode) Secret ¶
func (c RecoveryCode) Secret() secret.String
Secret explicitly exposes the recovery-secret wrapper for delivery.
func (*RecoveryCode) UnmarshalJSON ¶
func (c *RecoveryCode) UnmarshalJSON(data []byte) error
UnmarshalJSON clears the receiver and parses a bounded JSON string as a recovery code.
func (RecoveryCode) Validate ¶
func (c RecoveryCode) Validate() error
Validate checks recovery-code syntax without verifying stored validity.
type RecoveryCodes ¶
type RecoveryCodes[M any] struct { // contains filtered or unexported fields }
RecoveryCodes exposes an owned slice only after the factor mutation commits. Ordinary serialization cannot disclose the private collection or model.
func (RecoveryCodes[M]) Codes ¶
func (r RecoveryCodes[M]) Codes() []RecoveryCode
Codes returns a copy of the issued recovery-code slice for explicit delivery.
func (RecoveryCodes[M]) Format ¶
func (RecoveryCodes[M]) Format(s fmt.State, _ rune)
Format writes the label "issued MFA recovery codes" without exposing the value.
func (RecoveryCodes[M]) ID ¶
func (r RecoveryCodes[M]) ID() EnrollmentID[M]
ID returns the model-owned enrollment identifier associated with the codes.
func (RecoveryCodes[M]) Subject ¶
func (r RecoveryCodes[M]) Subject() M
Subject returns the model snapshot associated with code issuance without cloning it.
type RecoveryHash ¶
type RecoveryHash struct {
// contains filtered or unexported fields
}
RecoveryHash is a redacted SHA-256 digest of a high-entropy RecoveryCode, sharing the credential-hash implementation used by sessions and tokens. Encoded is an explicit persistence boundary, never an authentication proof.
func ParseRecoveryHash ¶
func ParseRecoveryHash(encoded string) (RecoveryHash, error)
ParseRecoveryHash restores a recovery digest from its hexadecimal persistence encoding.
func (RecoveryHash) Encoded ¶
func (h RecoveryHash) Encoded() string
Encoded exposes the recovery digest's hexadecimal persistence representation.
func (RecoveryHash) Format ¶
func (RecoveryHash) Format(s fmt.State, _ rune)
Format writes the redaction marker without exposing the value.
func (RecoveryHash) IsZero ¶
func (h RecoveryHash) IsZero() bool
IsZero reports whether the recovery digest is uninitialized.
func (RecoveryHash) LogValue ¶
func (RecoveryHash) LogValue() slog.Value
LogValue returns the redaction marker without exposing the value.
func (RecoveryHash) MarshalJSON ¶
func (RecoveryHash) MarshalJSON() ([]byte, error)
MarshalJSON encodes the redaction marker without exposing the value.
type Response ¶
type Response struct {
// contains filtered or unexported fields
}
Response is an explicit choice of TOTP or recovery factor. Enrollment confirmation accepts only TOTPCode and cannot receive this alternative.
func RecoveryResponse ¶
func RecoveryResponse(code RecoveryCode) (Response, error)
RecoveryResponse validates code and selects recovery-code verification.
func TOTPResponse ¶
TOTPResponse validates code and selects TOTP verification.
type Rotation ¶
type Rotation struct {
Reencrypted uint64
Changed uint64
Failed uint64
Next RotationCursor
Done bool
}
Rotation reports one bounded batch. Reencrypted counts committed replacements; Changed counts factors that changed concurrently (a later run re-examines them if still stale); Failed counts envelopes that could not be decrypted with the retained keys. Done reports that no stale factor remained after Next when the batch was read.
type RotationBackend ¶
type RotationBackend interface {
// StaleCiphertexts returns at most limit factors whose envelope was not
// produced by the active key, ordered by Owner and strictly after the
// cursor (empty starts from the beginning).
StaleCiphertexts(ctx context.Context, active encryption.KeyID, after string, limit int) ([]StoredCiphertext, error)
// ReplaceCiphertext stores next only while the factor still has the same
// owner, generation and envelope. False means it changed concurrently.
ReplaceCiphertext(ctx context.Context, stored StoredCiphertext, next encryption.Ciphertext) (bool, error)
}
RotationBackend is the storage contract for password-free key rotation across every address sharing the store. Implementations never load domain models.
type RotationCursor ¶
type RotationCursor struct {
// contains filtered or unexported fields
}
RotationCursor resumes rotation after the last examined factor. The zero value starts from the beginning. It is opaque and not a model reference.
func (RotationCursor) IsZero ¶
func (c RotationCursor) IsZero() bool
IsZero reports whether the cursor has no rotation owner.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store borrows a transactional backend and immutable encryption keyring. One store bounds work across all model bindings. Construction performs no I/O.
func NewStore ¶
NewStore validates and borrows the backend and keyring and creates bounded factor-operation admission.
func (*Store) ReencryptStale ¶
func (s *Store) ReencryptStale(ctx context.Context, after RotationCursor, limit int) (Rotation, error)
ReencryptStale re-encrypts up to limit stored factors under the keyring's active key, for key rotation, without any user's password or domain model. Each replacement is conditional on the factor's generation and envelope, so it is safe alongside logins and management. The secret, generation, replay step and recovery hashes are unchanged, and no credential is revoked. Envelopes whose key is no longer retained are reported as Failed and skipped. Counts committed before an error are returned with it.
type StoredCiphertext ¶
type StoredCiphertext struct {
Owner string
Generation model.ID[Record]
Ciphertext encryption.Ciphertext
}
StoredCiphertext is one stored factor envelope selected for key rotation. It carries the opaque subject key and factor generation that bind the envelope's encryption context, never a model, identity or plaintext.
type TOTPCode ¶
type TOTPCode struct {
// contains filtered or unexported fields
}
TOTPCode preserves six ASCII digits, including leading zeroes. It is a typed unverified input. No trimming, Unicode digit conversion or truncation occurs.
func ParseTOTPCode ¶
ParseTOTPCode requires exactly six ASCII digits without checking their cryptographic validity.
func (TOTPCode) JSONContract ¶
JSONContract describes TOTP input as a JSON string; ordinary output remains redacted.
func (TOTPCode) MarshalJSON ¶
MarshalJSON encodes the redaction marker without exposing the value.
func (*TOTPCode) UnmarshalJSON ¶
UnmarshalJSON clears the receiver and parses a bounded JSON string as six ASCII digits.
type TOTPSecret ¶
type TOTPSecret struct {
// contains filtered or unexported fields
}
TOTPSecret is a canonical unpadded uppercase base32 160-bit secret. Only Secret deliberately reveals it for encrypted persistence or authenticated enrollment delivery. Plain database storage and ordinary response serialization are not supported. This type does not promise memory erasure.
func GenerateTOTPSecret ¶
func GenerateTOTPSecret() (TOTPSecret, error)
GenerateTOTPSecret creates a cryptographically random 160-bit key, returning fault.Internal if randomness fails.
func ParseTOTPSecret ¶
func ParseTOTPSecret(encoded secret.String) (TOTPSecret, error)
ParseTOTPSecret requires a canonical unpadded uppercase base32 encoding of a 160-bit key.
func (TOTPSecret) Format ¶
func (TOTPSecret) Format(s fmt.State, _ rune)
Format writes the redaction marker without exposing the value.
func (TOTPSecret) LogValue ¶
func (TOTPSecret) LogValue() slog.Value
LogValue returns the redaction marker without exposing the value.
func (TOTPSecret) MarshalJSON ¶
func (TOTPSecret) MarshalJSON() ([]byte, error)
MarshalJSON encodes the redaction marker without exposing the value.
func (TOTPSecret) Secret ¶
func (s TOTPSecret) Secret() secret.String
Secret explicitly exposes the encoded key wrapper for encrypted persistence or enrollment delivery.
func (TOTPSecret) Validate ¶
func (s TOTPSecret) Validate() error
Validate checks the key's canonical base32 encoding and length.
type TransactionalBackend ¶
type TransactionalBackend interface {
// WithinIn applies the model-before-factor mutation contract within the caller-owned
// transaction, without committing it.
WithinIn(context.Context, *database.Tx, Address, model.Identity, func(context.Context, *database.Tx) error, func(context.Context, *database.Tx, value.Optional[Record], temporal.DateTime) (Change, error)) (value.Optional[Record], error)
}
TransactionalBackend joins the credential creation transaction. It verifies exact pool ownership, uses a savepoint, restores schema settings and never commits. The same model-before-factor ordering and callback rules apply.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package command supplies the explicit MFA key-rotation operation.
|
Package command supplies the explicit MFA key-rotation operation. |
|
Package postgres stores encrypted MFA factors through explicit migrations and generated model queries.
|
Package postgres stores encrypted MFA factors through explicit migrations and generated model queries. |