authflow

package
v1.10.0 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 23 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MaxAssertionLifetime bounds an assertion's exp from now.
	MaxAssertionLifetime = 5 * time.Minute
	// AssertionSkew is the clock skew allowed on exp, nbf and iat.
	AssertionSkew = 30 * time.Second
)
View Source
const (
	ReasonAssertionInvalid   = "assertion_invalid"
	ReasonAssertionReplayed  = "assertion_replayed"
	ReasonCapabilityInvalid  = "capability_invalid"
	ReasonCapabilityExpired  = "capability_expired"
	ReasonCapabilityReplayed = "capability_replayed"
	ReasonDeviceKeyRevoked   = "device_key_revoked"
	ReasonKeyMismatch        = "key_mismatch"
	ReasonUserUnavailable    = "user_unavailable"
	ReasonRefused            = "refused"
)

Reasons a jwt-bearer refusal carries (OAuthError.Reason).

View Source
const (
	TokenTypeAccessToken = "urn:ietf:params:oauth:token-type:access_token"
	TokenTypeJWT         = "urn:ietf:params:oauth:token-type:jwt"
)

RFC 8693 token type identifiers.

View Source
const (
	OAuthInvalidRequest          = "invalid_request"
	OAuthInvalidClient           = "invalid_client"
	OAuthInvalidGrant            = "invalid_grant"
	OAuthUnauthorizedClient      = "unauthorized_client"
	OAuthUnsupportedGrantType    = "unsupported_grant_type"
	OAuthUnsupportedResponseType = "unsupported_response_type"
	OAuthInvalidScope            = "invalid_scope"
	OAuthInvalidTarget           = "invalid_target"
	OAuthAccessDenied            = "access_denied"
	OAuthLoginRequired           = "login_required"
	OAuthInteractionRequired     = "interaction_required"
	OAuthConsentRequired         = "consent_required"
	OAuthRequestNotSupported     = "request_not_supported"
	OAuthRequestURINotSupported  = "request_uri_not_supported"
	OAuthInvalidToken            = "invalid_token"
	OAuthInvalidDPoPProof        = "invalid_dpop_proof"
	OAuthUseDPoPNonce            = "use_dpop_nonce"
	OAuthUnsupportedTokenType    = "unsupported_token_type"
	OAuthServerError             = "server_error"
	OAuthTemporarilyUnavailable  = "temporarily_unavailable"
	// OAuthInvalidAuthorizationDetails is RFC 9396 §5's.
	OAuthInvalidAuthorizationDetails = "invalid_authorization_details"
)

OAuth error codes AuthKit answers.

View Source
const (
	ActionUpdateUsername       = "update_username"
	ActionRequestPasswordReset = "request_password_reset"
	ActionRequestVerification  = "request_verification"
)

ActionAvailability reports whether a cooldown-gated action is currently allowed; it rides on 429 error metadata. Action names carried by ActionAvailability.

View Source
const (
	MaxAuthorizationDetailsBytes = 8 << 10
)

RFC 9396 authorization_details bounds, as requested and as decided.

View Source
const SensitiveActionFreshAuthWindow = 15 * time.Minute

Variables

This section is empty.

Functions

func NarrowsAuthorizationDetails added in v1.10.0

func NarrowsAuthorizationDetails(granted, narrowed json.RawMessage) bool

NarrowsAuthorizationDetails reports whether every entry of narrowed is one of granted's, member order aside (numbers compare as written): a narrowing drops entries, never adds or changes one.

func NewTokenSet added in v1.0.2

func NewTokenSet(access, refresh string, exp time.Time) iam.TokenSet

NewTokenSet builds a Bearer TokenSet whose expires_in is derived from exp; an empty refresh token is none.

func NormalizeAuthMethods

func NormalizeAuthMethods(methods []string) []string

func NormalizePreferredLanguage

func NormalizePreferredLanguage(language string) (string, error)

NormalizePreferredLanguage is lang.Normalize for an account's stored preference: "" clears it, and a value naming no language is refused.

func ParseJWTBearerAssertion added in v1.10.0

func ParseJWTBearerAssertion(raw, clientID, tokenEndpoint string, now time.Time) (Assertion, *OAuthError)

ParseJWTBearerAssertion verifies raw for clientID at tokenEndpoint: its ES256 signature by the P-256 key its header carries (typ, when present, "JWT"), iss the client, a sub, aud the token endpoint alone, exp no further than MaxAssertionLifetime ahead, a jti of 16-128 characters, and a capability. The jti's replay is the caller's to check.

func RecentSignIn

func RecentSignIn(authTime time.Time, amr []string, mfa bool, now time.Time) bool

RecentSignIn reports whether a token's assurance clears the sensitive-action gate: signed in within SensitiveActionFreshAuthWindow and, for an account with a usable second factor (mfa), with that factor (amr otp or mfa). An account without one is never blocked for lacking it.

func SessionRevokeReasonFrom

func SessionRevokeReasonFrom(ctx context.Context) *string

SessionRevokeReasonFrom reads the reason WithSessionRevokeReason attached, or nil.

func ValidationErrorCode

func ValidationErrorCode(err error) errmodel.Code

ValidationErrorCode returns the identity-policy code err carries, or "" when err is not a validation failure.

func VerifyCapability added in v1.10.0

func VerifyCapability(raw, kid string, key ed25519.PublicKey, now time.Time) (Capability, *OAuthError)

VerifyCapability verifies raw's EdDSA signature by key, the device key kid, and its claims at now: typ devicekey.CapabilityType, a user sub, a sole aud, cnf.jkt alone, a jti of 16-128 characters, authorization_details, and exp no further than MaxCapabilityLifetime ahead. Whose key it is, the binding, the operations' types and the replay are the caller's to check.

func WithSessionRevokeReason

func WithSessionRevokeReason(ctx context.Context, reason SessionRevokeReason) context.Context

WithSessionRevokeReason annotates ctx so revoke paths can record a structured reason in the session log.

func WithSignInDevice added in v1.3.0

func WithSignInDevice(ctx context.Context, d SignInDevice) context.Context

WithSignInDevice attaches the request's device to ctx.

Types

type AccountRecoveryConfirmation

type AccountRecoveryConfirmation struct {
	Token     string    `json:"token"`
	ExpiresAt time.Time `json:"expires_at"`
	PurgeAt   time.Time `json:"purge_at"`
}

AccountRecoveryConfirmation is an opaque proof, never an access token or session. Confirmation restores this deletion generation without signing in.

type ActionAvailability

type ActionAvailability = errmodel.ActionAvailability

type Assertion added in v1.10.0

type Assertion struct {
	JKT        string
	Subject    string
	ID         string
	IssuedAt   time.Time
	ExpiresAt  time.Time
	Claims     map[string]json.RawMessage
	Capability string
}

Assertion is a verified jwt-bearer assertion: the workload key that signed it (JKT), its claims, and the capability it carries, unverified.

type AuthSessionEvent

type AuthSessionEvent struct {
	OccurredAt time.Time
	Issuer     string
	UserID     string
	SessionID  string
	Event      iam.SessionEventKind
	Method     *string
	Reason     *string
	IPAddr     *string
	UserAgent  *string
}

AuthSessionEvent is a best-effort, append-only session lifecycle record stored in Postgres (session_events, #245) and retained per Config.SessionEventRetention. issuer/user_id/session_id/event are required; method is typically set for SessionEventCreated and reason for SessionEventRevoked.

type Capability added in v1.10.0

type Capability struct {
	UserID               string
	DeviceKeyID          string
	Audience             string
	JKT                  string
	AuthorizationDetails json.RawMessage
	ID                   string
	IssuedAt             time.Time
	ExpiresAt            time.Time
	Claims               map[string]json.RawMessage
}

Capability is a verified capability.

type DeviceChallenge added in v1.3.0

type DeviceChallenge struct {
	Challenge   string
	Channel     string
	Destination string
	Channels    []string
}

DeviceChallenge is a sign-in from a new device past Config.SignIn.NewDevicesPerAccount: a code went to the account's proven Channel ("email" or "sms") at Destination, unmasked. Channels are the proven channels a resend may choose.

type DeviceKeyAuthResult

type DeviceKeyAuthResult struct {
	UserID      string
	AccessToken string
	ExpiresAt   time.Time
	DeviceKey   iam.DeviceKey
}

DeviceKeyAuthResult is a device key's sign-in: its account, access token and key.

type DeviceKeyChallenge

type DeviceKeyChallenge struct {
	ID        string
	Challenge string
	ExpiresAt time.Time
}

DeviceKey is the public projection of one native-client credential.

type DeviceKeySecondFactorRequired

type DeviceKeySecondFactorRequired struct{ Method string }

DeviceKeySecondFactorRequired is returned by FinishDeviceKeyEnrollment when the email code and key proof are valid but the account has a usable second factor that was not presented (#293). Method is a factor independent of the enrollment mailbox (totp, sms) or backup_code. The ceremony stays live for a retry carrying the code; for an SMS factor the code has just been sent.

func (*DeviceKeySecondFactorRequired) Error

type DeviceVerificationInput added in v1.3.0

type DeviceVerificationInput struct {
	UserID    string
	Challenge string
	Code      string
	UserAgent string
	IP        string
}

DeviceVerificationInput confirms a new device with its code.

type ExternalIdentity

type ExternalIdentity struct {
	Provider          string // provider slug (the configured name)
	Issuer            string
	Subject           string
	Email             string
	EmailVerified     bool
	PreferredUsername string
	DisplayName       string
}

ExternalIdentity is a provider-verified identity.

type ExternalLinkAuthorization

type ExternalLinkAuthorization struct {
	UserID          string
	SessionID       string
	AuthenticatedAt time.Time
}

ExternalLinkAuthorization records the fresh session that initiated linking. It is carried only in server-side browser state, never accepted from a callback.

type ExternalLoginInput

type ExternalLoginInput struct {
	Identity ExternalIdentity
	// Link authorizes a provider mutation only; it never creates a session.
	Link               *ExternalLinkAuthorization
	AccountInviteToken string
	// ReturnTo is where the browser flow began; the sign-in's continuations
	// carry it to their AuthResult.
	ReturnTo  string
	Event     string // session-created audit event, e.g. "oidc_login"
	UserAgent string
	IP        string
}

ExternalLoginInput is an external-identity login or link attempt.

type FactorEnrollmentMode

type FactorEnrollmentMode string

FactorEnrollmentMode distinguishes restricted enrollment grants from authenticated factor management.

const (
	// FirstFactorOnly permits a restricted grant to enroll only when no factor exists.
	FirstFactorOnly FactorEnrollmentMode = "first_factor_only"
	// AllowAdditionalFactors permits fresh authenticated users to add a new method.
	AllowAdditionalFactors FactorEnrollmentMode = "allow_additional_factors"
)

type FreshAuth added in v0.149.0

type FreshAuth struct {
	LastAuthenticatedAt               *time.Time `json:"last_authenticated_at"`
	StepUpRequiredForSensitiveActions bool       `json:"step_up_required_for_sensitive_actions"`
	StepUpRequiredInSeconds           int64      `json:"step_up_required_in_seconds"`
	AuthMethods                       []string   `json:"auth_methods"`
}

FreshAuth is a session's step-up state: when it last proved its user, and how long sensitive actions stay open without a step-up (0 once one is required).

type InviteRedemption

type InviteRedemption struct {
	GroupID string
	Persona iam.Persona
	Role    iam.Role
}

InviteRedemption is the group and role a redeemed invite link granted.

type IssuedSession

type IssuedSession struct {
	SessionID       string
	RefreshToken    string
	AccessToken     string
	AccessExpiresAt time.Time
}

IssuedSession is a freshly established refresh session plus its paired access token.

func (IssuedSession) TokenSet

func (s IssuedSession) TokenSet() iam.TokenSet

TokenSet is the wire shape of an IssuedSession.

type LinkedProvider added in v0.149.0

type LinkedProvider struct {
	Provider string    `json:"provider"`
	Email    *string   `json:"email"`
	LinkedAt time.Time `json:"linked_at"`
}

LinkedProvider is a sign-in provider linked to the account, with the email the provider reported.

type LoginChallengeInput

type LoginChallengeInput struct {
	UserID     string
	Challenge  string
	FactorID   string
	Code       string
	BackupCode bool
	UserAgent  string
	IP         string
}

LoginChallengeInput supplies the second proof; clients never supply AMR or first-factor provenance. Backup codes are independently stored recovery keys.

type LoginOutcome

type LoginOutcome struct {
	Recovery       *AccountRecoveryConfirmation
	Enrollment     *iam.TokenSet
	AllowedMethods []iam.TwoFactorMethod
	ReturnTo       string
	Created        bool
	Kind           LoginOutcomeKind
	UserID         string
	Reason         error
	Session        *IssuedSession
	Verification   *VerificationRequired
	Challenge      *TwoFactorChallenge
	Device         *DeviceChallenge
}

LoginOutcome is the result of a password login. Exactly one of Session, Verification and Challenge is set, per Kind; Reason is set for LoginRejected.

type LoginOutcomeKind

type LoginOutcomeKind string

LoginOutcomeKind is the closed set of ways a login attempt ends.

const (
	LoginProviderLinked LoginOutcomeKind = "provider_linked"
	LoginContactChanged LoginOutcomeKind = "contact_changed"
	// LoginSessionIssued: the caller is signed in; Session carries the tokens.
	LoginSessionIssued LoginOutcomeKind = "session_issued"
	// LoginVerificationRequired: the identifier still needs verifying; a fresh
	// code was just sent to Verification.Identifier over Verification.Channel.
	LoginVerificationRequired LoginOutcomeKind = "verification_required"
	// LoginTwoFactorRequired: the password verified; a second factor is now
	// pending (Challenge carries the issued challenge and the factor menu).
	LoginTwoFactorRequired LoginOutcomeKind = "2fa_required"
	// LoginTwoFAEnrollmentRequired: the password verified but the deployment
	// requires a second factor the user has not enrolled yet.
	LoginTwoFAEnrollmentRequired LoginOutcomeKind = "2fa_enrollment_required"
	// LoginDeviceVerificationRequired: a new device past the account's limit;
	// Device carries the code's challenge.
	LoginDeviceVerificationRequired LoginOutcomeKind = "device_verification_required"
	// LoginRejected: no session; Reason says why (ErrInvalidCredentials,
	// ErrUserBanned, ErrPasswordResetRequired).
	LoginRejected LoginOutcomeKind = "rejected"
)
const LoginRecoveryRequired LoginOutcomeKind = "account_recovery_required"

type MFAContinuationRequiredError

type MFAContinuationRequiredError struct {
	UserID    string
	SessionID string
	Reason    error
}

MFAContinuationRequiredError identifies the already-validated refresh session that needs a first-factor continuation. It never authorizes an arbitrary user.

func (*MFAContinuationRequiredError) Error

func (*MFAContinuationRequiredError) Unwrap

func (e *MFAContinuationRequiredError) Unwrap() error

type MFAFactor added in v1.1.0

type MFAFactor struct {
	ID          string
	UserID      string
	Method      string
	PhoneNumber *string
	// Email is the address an email factor was proven for; its codes go
	// there, never to the account's current address.
	Email        *string
	TOTPSecret   []byte
	LastTOTPStep *int64
	IsDefault    bool
	Enabled      bool
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

MFAFactor is a stored second factor; TwoFactorFactor is how the wire shows it.

type MFAStatus

type MFAStatus struct {
	Enabled        bool
	Satisfied      bool
	AllowedMethods []iam.TwoFactorMethod
}

type OAuthApprover added in v1.6.1

type OAuthApprover struct {
	UserID      string
	SessionID   string
	DeviceKeyID string
	AuthTime    int64
	AMR         []string
	ACR         string
}

OAuthApprover is the sign-in approving an authorization request: a refresh session (SessionID) or a device key (DeviceKeyID). A device-key sign-in keeps no session to read its assurance from, so AuthTime, AMR and ACR are its verified token's.

type OAuthAuthorization added in v1.5.0

type OAuthAuthorization struct {
	ClientID      string   `json:"client_id"`
	RedirectURI   string   `json:"redirect_uri"`
	State         string   `json:"state,omitempty"`
	Nonce         string   `json:"nonce,omitempty"`
	Scopes        []string `json:"scopes"`
	Resource      string   `json:"resource,omitempty"`
	CodeChallenge string   `json:"code_challenge"`
	Prompt        []string `json:"prompt,omitempty"`
	MaxAge        *int64   `json:"max_age,omitempty"`
	LoginHint     string   `json:"login_hint,omitempty"`
	// DPoPJKT binds the code to a DPoP key (RFC 9449 §10): its redemption
	// must prove that key.
	DPoPJKT string `json:"dpop_jkt,omitempty"`
	// AuthorizationDetails is the request's RFC 9396 authorization_details.
	AuthorizationDetails json.RawMessage `json:"authorization_details,omitempty"`
	CreatedAt            time.Time       `json:"created_at"`
	ExpiresAt            time.Time       `json:"expires_at"`
}

OAuthAuthorization is a validated authorization request waiting for its user: the authorize endpoint stores it, the SPA signs the user in and approves or declines it.

type OAuthClientCredentials added in v1.5.0

type OAuthClientCredentials struct {
	ClientID             string
	Resource             string
	Scopes               []string
	JKT                  string
	AuthorizationDetails json.RawMessage
}

OAuthClientCredentials is a client_credentials token request.

type OAuthCodeExchange added in v1.5.0

type OAuthCodeExchange struct {
	ClientID     string
	Code         string
	RedirectURI  string
	CodeVerifier string
	// Resource is the request's resource parameter; "" takes the authorized
	// one.
	Resource string
	// JKT is the thumbprint of the request's DPoP proof key; "" without
	// DPoP. The tokens are bound to it.
	JKT string
}

OAuthCodeExchange is an authorization_code token request from an authenticated (or public) client.

type OAuthEndSession added in v1.5.0

type OAuthEndSession struct {
	IDTokenHint           string
	ClientID              string
	PostLogoutRedirectURI string
	State                 string
}

OAuthEndSession is an RP-initiated logout request.

type OAuthError added in v1.5.0

type OAuthError struct {
	Code        string
	Description string
	// Status is the HTTP status for a direct (non-redirect) answer; 0 means
	// 400.
	Status int
	// Reason is a stable machine-readable cause beside Code ("reason"),
	// which the jwt-bearer grant sets.
	Reason string
}

OAuthError is an OAuth 2.0 protocol error (RFC 6749 §4.1.2.1, §5.2): the error code a client branches on and a human-readable description.

func CapabilityKeyID added in v1.10.0

func CapabilityKeyID(raw string) (string, *OAuthError)

CapabilityKeyID is the device key id a capability names (kid), before its signature is checked.

func CompactAuthorizationDetails added in v1.6.0

func CompactAuthorizationDetails(raw []byte) (json.RawMessage, *OAuthError)

CompactAuthorizationDetails checks raw's shape and returns it re-encoded from what was checked: a repeated member keeps only the value read.

func JWTBearerRefusal added in v1.10.0

func JWTBearerRefusal(reason, description string) *OAuthError

JWTBearerRefusal is invalid_grant with reason.

func NewOAuthError added in v1.5.0

func NewOAuthError(code, description string) *OAuthError

NewOAuthError builds an OAuthError.

func ParseAuthorizationDetails added in v1.6.0

func ParseAuthorizationDetails(raw string, allowed []string) (json.RawMessage, *OAuthError)

ParseAuthorizationDetails validates an authorization_details parameter against the types a client declares: a JSON array of objects, each with one of those types. It returns the array re-encoded; nil for "".

func (*OAuthError) Error added in v1.5.0

func (e *OAuthError) Error() string

func (*OAuthError) HTTPStatus added in v1.5.0

func (e *OAuthError) HTTPStatus() int

HTTPStatus is the status a direct answer carries.

type OAuthGrant added in v1.5.0

type OAuthGrant struct {
	ClientID      string   `json:"client_id"`
	RedirectURI   string   `json:"redirect_uri"`
	CodeChallenge string   `json:"code_challenge"`
	Nonce         string   `json:"nonce,omitempty"`
	Scopes        []string `json:"scopes"`
	Resource      string   `json:"resource,omitempty"`
	UserID        string   `json:"user_id"`
	SessionID     string   `json:"session_id"`
	DeviceKeyID   string   `json:"device_key_id,omitempty"`
	AuthTime      int64    `json:"auth_time"`
	AMR           []string `json:"amr"`
	ACR           string   `json:"acr"`
	DPoPJKT       string   `json:"dpop_jkt,omitempty"`
	// GrantID names the consented grant through its refreshes; Offline
	// grants outlive the sign-in, until the account's credentials change
	// (CredentialVersion). Decision is the host authorizer's at consent (nil
	// without one).
	GrantID           string              `json:"grant_id"`
	ApprovedAt        time.Time           `json:"approved_at"`
	Offline           bool                `json:"offline,omitempty"`
	CredentialVersion int64               `json:"credential_version,omitempty"`
	Decision          *OAuthGrantDecision `json:"decision,omitempty"`
}

OAuthGrant is what an authorization code stands for: the approved request and the sign-in that approved it.

type OAuthGrantDecision added in v1.6.0

type OAuthGrantDecision struct {
	Permissions          []string        `json:"permissions,omitempty"`
	AuthorizationDetails json.RawMessage `json:"authorization_details,omitempty"`
	MaxLifetime          time.Duration   `json:"max_lifetime,omitempty"`
	Claims               map[string]any  `json:"claims,omitempty"`
	Invoker              string          `json:"invoker,omitempty"`
}

OAuthGrantDecision is the host authorizer's decision a grant carries: permissions (nil for the defaults), authorization details, a lifetime cap and extra access-token claims; for jwt-bearer, its invoker.

type OAuthJWTBearer added in v1.10.0

type OAuthJWTBearer struct {
	ClientID  string
	Assertion string
	Resource  string
	Scopes    []string
	JKT       string
}

OAuthJWTBearer is a jwt-bearer token request: Assertion, and JKT, the key the request's DPoP proof proved ("" without one).

type OAuthRefresh added in v1.5.0

type OAuthRefresh struct {
	ClientID     string
	RefreshToken string
	// Scopes narrows the family's scopes; nil keeps them.
	Scopes   []string
	Resource string
	JKT      string
}

OAuthRefresh is a refresh_token token request.

type OAuthTokenExchange added in v1.5.0

type OAuthTokenExchange struct {
	ClientID           string
	SubjectToken       string
	SubjectTokenType   string
	RequestedTokenType string
	Resource           string
	Scopes             []string
	JKT                string
	// AuthorizationDetails is the request's RFC 9396 authorization_details.
	AuthorizationDetails json.RawMessage
}

OAuthTokenExchange is an RFC 8693 token exchange request: the user's AuthKit access token for an access token to a resource.

type OAuthTokens added in v1.5.0

type OAuthTokens struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int64  `json:"expires_in"`
	Scope        string `json:"scope,omitempty"`
	IDToken      string `json:"id_token,omitempty"`
	RefreshToken string `json:"refresh_token,omitempty"`
	// IssuedTokenType answers a token exchange (RFC 8693 §2.2.1).
	IssuedTokenType string `json:"issued_token_type,omitempty"`
	// AuthorizationDetails is what the access token was granted (RFC 9396
	// §7.1).
	AuthorizationDetails json.RawMessage `json:"authorization_details,omitempty"`
}

OAuthTokens is a token endpoint answer (RFC 6749 §5.1). Absent members are omitted, as the protocol expects.

type PasswordLoginInput

type PasswordLoginInput struct {
	Identifier string
	Password   string
	UserAgent  string
	IP         string
}

PasswordLoginInput is a password login attempt. Identifier is an email (contains "@"), an E.164 phone ("+…") or a username.

type PasswordlessLoginInput

type PasswordlessLoginInput struct {
	Identifier string
	Code       string
	Token      string
	UserAgent  string
	IP         string
}

PasswordlessLoginInput selects either a typed code or a link token, never both, and supplies request metadata for the resulting authentication.

type PasswordlessStartRequest

type PasswordlessStartRequest struct {
	Identifier         string
	Mode               string
	ReturnTo           string
	PreferredLanguage  string
	AccountInviteToken string
}

type PasswordlessStartResult

type PasswordlessStartResult struct {
	Sent    bool
	Channel string
	Code    string
	LinkURL string
}

type PendingRegistration

type PendingRegistration struct {
	Email             string
	Username          string
	PasswordHash      string
	PreferredLanguage string
}

PendingRegistration represents an unverified registration

type ProfileInput

type ProfileInput struct {
	UserID          string
	ClaimsUsername  string // fallback when the row carries no username
	AuthTime        time.Time
	StepUpSatisfied bool     // the presented token is fresh enough for sensitive actions
	AuthMethods     []string // the presented token's authentication methods (amr)
}

ProfileInput is what the transport knows that the engine does not: the verified claims' username, auth time and sensitivity.

type RegisterInput

type RegisterInput struct {
	Identifier         string
	Username           string
	Password           string
	PreferredLanguage  string
	AccountInviteToken string
	UserAgent          string
	IP                 string
}

RegisterInput is a native-user registration attempt: Identifier is an email or an E.164 phone; the account is password-backed.

type RegisterOutcome

type RegisterOutcome struct {
	Login    *LoginOutcome
	Kind     RegisterOutcomeKind
	Username string
	Email    *string
	Phone    *string
}

RegisterOutcome reports who was registered and what happens next.

type RegisterOutcomeKind

type RegisterOutcomeKind string

RegisterOutcomeKind is the closed set of ways a registration ends.

const (
	// RegisterSignedIn: the account exists; Login is its first sign-in (a
	// session, or the step it waits on).
	RegisterSignedIn RegisterOutcomeKind = "signed_in"
	// RegisterVerifyEmail / RegisterVerifyPhone: the registration is pending
	// until the code just sent to the identifier is confirmed.
	RegisterVerifyEmail RegisterOutcomeKind = "verify_email"
	RegisterVerifyPhone RegisterOutcomeKind = "verify_phone"
)

type RemovedMFARoleAssignment

type RemovedMFARoleAssignment struct {
	PermissionGroupID string
	Persona           iam.Persona
	Role              iam.Role
	RemovedAt         time.Time
}

type SessionFreshness

type SessionFreshness struct {
	LastAuthenticatedAt           time.Time
	TimeUntilStepUpRequired       time.Duration
	StepUpRequiredForSensitiveOps bool
	AuthMethods                   []string
	// MFAAuthenticatedAt is when the session last proved a second factor.
	MFAAuthenticatedAt time.Time
}

func (SessionFreshness) AssuranceClaims

func (f SessionFreshness) AssuranceClaims(secondFactor bool) (authTime int64, amr []string, acr string)

AssuranceClaims are the token's auth_time, amr and acr. A token claims otp/mfa only as of the session's last MFA proof. For an account with a second factor (secondFactor), auth_time is that proof, so a password re-auth never makes it fresh, and a session that never proved it claims no MFA. For an account without one (passkeys only), a later re-auth without MFA is fresh but no longer MFA (P5).

type SessionRevokeReason

type SessionRevokeReason string

SessionRevokeReason identifies why a session (or set of sessions) was revoked.

const (
	SessionRevokeReasonLogout               SessionRevokeReason = "logout"
	SessionRevokeReasonUserRevoke           SessionRevokeReason = "user_revoke"
	SessionRevokeReasonUserRevokeAll        SessionRevokeReason = "user_revoke_all"
	SessionRevokeReasonAdminRevoke          SessionRevokeReason = "admin_revoke"
	SessionRevokeReasonAdminRevokeAll       SessionRevokeReason = "admin_revoke_all"
	SessionRevokeReasonPasswordChange       SessionRevokeReason = "password_change"
	SessionRevokeReasonAdminSetPassword     SessionRevokeReason = "admin_set_password"
	SessionRevokeReasonContactChange        SessionRevokeReason = "contact_change"
	SessionRevokeReasonContactProven        SessionRevokeReason = "contact_proven"
	SessionRevokeReasonMFAReset             SessionRevokeReason = "mfa_reset"
	SessionRevokeReasonBanned               SessionRevokeReason = "banned"
	SessionRevokeReasonSoftDeleted          SessionRevokeReason = "soft_deleted"
	SessionRevokeReasonEvicted              SessionRevokeReason = "evicted"
	SessionRevokeReasonRefreshReuseDetected SessionRevokeReason = "refresh_reuse_detected"
)

type SignInDevice added in v1.3.0

type SignInDevice struct {
	// ID is "cookie:<hash>" for a browser's device cookie, else
	// "ip:<address>" (an IPv6 /64). Empty: unknown, and not limited.
	ID string `json:"id,omitempty"`
	// Issued is the device cookie this response sets ("cookie:<hash>")
	// beside an ip ID: the browser presents it next time.
	Issued string `json:"issued,omitempty"`
}

SignInDevice is where a sign-in comes from, for Config.SignIn's limits. The HTTP layer derives it from the request; the engine sees only hashes.

func SignInDeviceFrom added in v1.3.0

func SignInDeviceFrom(ctx context.Context) SignInDevice

SignInDeviceFrom is the device WithSignInDevice attached, or none.

func (SignInDevice) ByAddress added in v1.3.0

func (d SignInDevice) ByAddress() bool

ByAddress reports whether the device is known only by its client address.

type SolanaLinkedAccount

type SolanaLinkedAccount struct {
	Provider            string     `json:"provider"`
	Issuer              string     `json:"issuer"`
	Address             string     `json:"address"`
	Verified            bool       `json:"verified"`
	VerifiedAt          *time.Time `json:"verified_at"`
	PrimarySNSName      *string    `json:"primary_sns_name"`
	SNSResolutionStatus string     `json:"sns_resolution_status"`
	SNSResolvedAt       *time.Time `json:"sns_resolved_at"`
	SNSStale            bool       `json:"sns_stale"`
	SNSError            *string    `json:"sns_error"`
}

SolanaLinkedAccount is the AuthKit-owned normalized metadata for a SIWS-linked wallet.

type StepUpCredentials added in v1.1.0

type StepUpCredentials struct {
	Password     bool
	SecondFactor bool // an enabled second factor
	Passkey      bool
	Email, SMS   bool // a proven address a code can reach now
	Solana       bool // a linked wallet
	// Providers are the linked providers that prove a fresh sign-in.
	Providers []string
}

StepUpCredentials is what an account can re-authenticate with.

func (StepUpCredentials) Methods added in v1.1.0

func (c StepUpCredentials) Methods() []string

Methods lists the step-up methods that clear the sensitive-action gate. An account with a second factor steps up with it or a passkey, which is multi-factor itself; any other steps up with each way it signs in.

type StepUpRequired added in v0.149.0

type StepUpRequired struct {
	StepUpMethods []string          `json:"step_up_methods"`
	MaxAgeSeconds int64             `json:"max_age_seconds"`
	Factors       []TwoFactorFactor `json:"factors"`
}

StepUpRequired is step_up_required's metadata: the methods that clear the gate, the freshness window, and the second factors a "2fa" step-up can use.

type TwoFactorChallenge

type TwoFactorChallenge struct {
	Method      string
	Destination string // where the code went (email/phone), unmasked
	Challenge   string
	Factor      MFAFactor
	Factors     []MFAFactor
}

TwoFactorChallenge is the second-factor step a password login opened.

type TwoFactorEnrollInput

type TwoFactorEnrollInput struct {
	LoginChallenge string
	// SessionID is the caller's session; a confirmed code marks it 2FA-verified.
	SessionID   string
	UserAgent   string
	IP          string
	UserID      string
	Mode        FactorEnrollmentMode
	Method      string // "email" | "sms" | "totp"
	Code        string // email/SMS setup code or TOTP code; empty starts the method's setup
	PhoneNumber string
	MakeDefault bool
}

TwoFactorEnrollInput is one enrollment request: a setup to start (no Code), or the factor its Code proves to add.

type TwoFactorEnrollKind

type TwoFactorEnrollKind string

TwoFactorEnrollKind is the closed set of enrollment results.

const (
	TwoFactorEnrollCodeSent    TwoFactorEnrollKind = "code_sent"    // email/SMS setup code delivered
	TwoFactorEnrollTOTPStarted TwoFactorEnrollKind = "totp_started" // secret + otpauth URI handed out
	TwoFactorEnrollEnabled     TwoFactorEnrollKind = "enabled"
)

type TwoFactorEnrollOutcome

type TwoFactorEnrollOutcome struct {
	Login           *LoginOutcome
	Kind            TwoFactorEnrollKind
	Method          string
	Destination     string
	Secret          string
	OTPAuthURI      string
	Factor          MFAFactor
	BackupCodes     []string
	SessionVerified bool
}

TwoFactorEnrollOutcome carries the setup code's Destination for TwoFactorEnrollCodeSent, the TOTP material for TwoFactorEnrollTOTPStarted, and for TwoFactorEnrollEnabled the new Factor with the plaintext backup codes (shown once, the first factor's only). SessionVerified reports that the input session now holds 2FA assurance.

type TwoFactorEnrollmentScope

type TwoFactorEnrollmentScope struct {
	Mode       FactorEnrollmentMode
	HasFactors bool
}

TwoFactorEnrollmentScope is what an enrollment call may do: the factor slot policy and whether the account already holds a factor.

type TwoFactorFactor

type TwoFactorFactor struct {
	ID          string  `json:"id"`
	Method      string  `json:"method"`
	IsDefault   bool    `json:"is_default"`
	Destination *string `json:"destination"`
}

TwoFactorFactor is one second factor, the one shape sign-in, step-up and management share; each addresses it by ID. Destination is the masked address its codes go to (null for an authenticator app).

func StepUpFactors added in v1.1.0

func StepUpFactors(settings *TwoFactorSettings) []TwoFactorFactor

StepUpFactors lists the second factors a step-up can use: none unless 2FA is enabled.

func WireFactor added in v1.1.0

func WireFactor(f MFAFactor) TwoFactorFactor

WireFactor is f as the wire shows it, its code destination masked.

func WireFactors added in v1.1.0

func WireFactors(factors []MFAFactor) []TwoFactorFactor

WireFactors is WireFactor over factors, never nil.

type TwoFactorSettings

type TwoFactorSettings struct {
	UserID       string
	Enabled      bool
	Method       string // "email", "sms", or "totp"
	PhoneNumber  *string
	TOTPSecret   []byte
	LastTOTPStep *int64
	BackupCodes  []string // Hashed backup codes
	Factors      []MFAFactor
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

type TwoFactorStatus added in v1.1.0

type TwoFactorStatus struct {
	Enabled              bool                  `json:"enabled"`
	Factors              []TwoFactorFactor     `json:"factors"`
	AllowedMethods       []iam.TwoFactorMethod `json:"allowed_methods"`
	BackupCodesRemaining int                   `json:"backup_codes_remaining"`
}

TwoFactorStatus is the account's second factors and the methods it may enroll.

func NewTwoFactorStatus added in v1.1.0

func NewTwoFactorStatus(settings *TwoFactorSettings, allowed []iam.TwoFactorMethod) TwoFactorStatus

NewTwoFactorStatus is the account's second-factor state; nil settings is an account that never enrolled.

type UserProfile

type UserProfile struct {
	iam.User
	RootRole     *iam.Role            `json:"root_role"`
	Entitlements []string             `json:"entitlements"`
	HasPassword  bool                 `json:"has_password"`
	Providers    []LinkedProvider     `json:"providers"`
	SolanaWallet *SolanaLinkedAccount `json:"solana_wallet"`
	Naming       naming.State         `json:"naming"`
}

UserProfile is the caller's own account as GET /me and PATCH /me answer it: the account (iam.User), its root role, entitlements, sign-in methods, Solana wallet and rename state.

type UserSecurity

type UserSecurity struct {
	FreshAuth
	StepUpMethods []string        `json:"step_up_methods"`
	TwoFactor     TwoFactorStatus `json:"two_factor"`
}

UserSecurity is GET /me/security: the session's freshness, how the account can step up, and its second factors.

type VerificationInput

type VerificationInput struct {
	Identifier    string
	Code          string
	Token         string
	PasswordProof string
	UserID        string
	SessionID     string
	UserAgent     string
	IP            string
}

VerificationInput completes a delivered code/link. UserID and SessionID are supplied only from an authenticated host identity for contact changes. PasswordProof is a parked login's VerificationRequired.PasswordProof.

type VerificationRequired

type VerificationRequired struct {
	Identifier    string
	Channel       string // "email" | "phone"
	PasswordProof string
}

VerificationRequired names the contact channel a login is parked on. PasswordProof, when the login proved the account's password, is the single-use token that lets the confirmation keep it (VerificationInput).

Jump to

Keyboard shortcuts

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