config

package
v1.6.1 Latest Latest
Warning

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

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

Documentation

Overview

Package config is the one definition of AuthKit's host configuration: Config (plain data), Deps (everything that reaches outside the process), the Roles builder and MigrateOptions. The root package re-exports each type under the same name (authkit.Config is config.Config), so these field docs are the ones hosts read. Normalize applies every default and rule once.

Index

Constants

View Source
const (
	DefaultOAuthRefreshTokenTTL = 12 * time.Hour
	MaxOAuthRefreshTokenTTL     = 30 * 24 * time.Hour
)

DefaultOAuthRefreshTokenTTL is AuthorizationServerConfig.RefreshTokenTTL's default; MaxOAuthRefreshTokenTTL its ceiling.

View Source
const (
	DefaultAPIPath = "/api"
	// APIVersion is the version segment AuthKit owns beneath APIPath: the
	// JSON API is {BasePath}{APIPath}/v1. A breaking change mounts /v2 beside
	// it.
	APIVersion                 = "/v1"
	DefaultPasswordMinLength   = 8
	DefaultPasswordMaxLength   = 128
	PasswordMaxLengthCeiling   = 1024
	DefaultUsernameMinLength   = 4
	DefaultUsernameMaxLength   = 30
	UsernameMaxLengthCeiling   = 64
	DefaultRenameInterval      = 72 * time.Hour
	DefaultFormerNameRetention = 90 * 24 * time.Hour

	DefaultDelegatedTTLFloor   = time.Minute
	DefaultDelegatedTTLDefault = 15 * time.Minute
	DefaultDelegatedTTLCeiling = time.Hour

	DefaultAccountsPerDevice    = 5
	DefaultAccountsPerAddress   = 20
	DefaultNewDevicesPerAccount = 10
)

Defaults Normalize applies.

View Source
const DefaultOAuthAccessTokenTTL = 5 * time.Minute

DefaultOAuthAccessTokenTTL is AuthorizationServerConfig.AccessTokenTTL's default and ceiling.

View Source
const MaxOAuthClientAccessTokenTTL = 15 * time.Minute

MaxOAuthClientAccessTokenTTL is OAuthClientConfig.AccessTokenTTL's ceiling.

Variables

This section is empty.

Functions

func AuthorizationServerEnabled added in v1.5.0

func AuthorizationServerEnabled(a AuthorizationServerConfig) bool

AuthorizationServerEnabled reports whether the authorization server is on.

func CompileRoles

func CompileRoles(r *Roles) (*rbac.Schema, error)

CompileRoles checks the declared model and compiles it, once, into the schema the engine authorizes against; nil is root-only.

func MountPath

func MountPath(field, p string) (string, error)

MountPath normalizes a configured path: surrounding space and trailing slashes are dropped, so "/" is "" (root).

func NormalizeSchema

func NormalizeSchema(raw string) (string, error)

NormalizeSchema trims and validates a PostgreSQL schema name, defaulting to "profiles". The name is spliced into SQL text, so this is the injection guard.

func OAuthClientAccessTTL added in v1.6.0

func OAuthClientAccessTTL(a AuthorizationServerConfig, c OAuthClientConfig) time.Duration

OAuthClientAccessTTL is the lifetime of access tokens minted for c.

func OAuthClientAllows added in v1.5.0

func OAuthClientAllows(c OAuthClientConfig, grant OAuthGrantType) bool

OAuthClientAllows reports whether c may use grant.

func OAuthClientConfidential added in v1.5.0

func OAuthClientConfidential(c OAuthClientConfig) bool

OAuthClientConfidential reports whether c authenticates with a secret.

func OAuthClientRefreshTTL added in v1.6.0

func OAuthClientRefreshTTL(a AuthorizationServerConfig, c OAuthClientConfig) time.Duration

OAuthClientRefreshTTL bounds a refresh token family of c.

func OIDCScope added in v1.5.0

func OIDCScope(scope string) bool

OIDCScope reports whether scope is one AuthKit itself defines.

func ParseCIDRs

func ParseCIDRs(kind string, cidrs []string) ([]netip.Prefix, error)

ParseCIDRs parses proxy ranges.

Types

type APIKeysConfig

type APIKeysConfig struct {
	// Prefix brands generated keys (one per deployment): lowercase
	// alphanumeric, 1-16 characters. Empty gives the bare "st_" marker.
	Prefix string
	// MaxTTL caps how far ahead a key may expire; a later or absent expiry is
	// capped at creation. 0 means no cap.
	MaxTTL time.Duration
}

APIKeysConfig configures opaque permission-group-owned machine credentials.

type AuthorizationServerConfig added in v1.5.0

type AuthorizationServerConfig struct {
	// Clients are the registered OAuth clients. None leaves the
	// authorization server off.
	Clients []OAuthClientConfig
	// Resources are the resource servers access tokens may be minted for
	// (RFC 8707 resource indicators).
	Resources []ResourceServerConfig
	// AccessTokenTTL is the lifetime of the RFC 9068 access tokens it mints.
	// 0 defaults to 5 minutes, the most allowed.
	AccessTokenTTL time.Duration
	// RefreshTokenTTL bounds a refresh token family: rotation never extends
	// it, and the client signs the user in again (prompt=none) after it.
	// 0 defaults to 12 hours; at most 30 days. A family also ends with the
	// sign-in it was issued from.
	RefreshTokenTTL time.Duration
}

AuthorizationServerConfig declares the OAuth clients this deployment signs users in for and the resource servers it mints access tokens for. Clients and resources are configuration only: there is no dynamic registration. Every client is first-party: a signed-in user is never asked to consent.

type Config

type Config struct {
	// Schema is the PostgreSQL schema AuthKit's tables live in. Empty defaults
	// to "profiles". Deployments that must not share accounts on one database
	// use different schemas; deployments that share accounts use the same one
	// (see TokenConfig.AccountIssuers). It must match ^[a-z_][a-z0-9_]*$ (max 63
	// bytes).
	Schema string

	// Token is the JWT issuing/verification contract and session limits.
	Token TokenConfig
	// SignIn limits how sign-ins spread across accounts and devices: one
	// person signing in and out of many accounts, and one account shared by
	// many people. The zero value is on, with generous limits.
	SignIn SignInConfig
	// Keys controls signing-key resolution when Deps.KeySource is nil.
	Keys KeysConfig
	// Frontend describes host-owned frontend routes used for absolute URLs.
	Frontend FrontendConfig
	// Registration controls verification policy and public self-registration.
	Registration RegistrationConfig
	// Password is the rule every password write enforces. The zero value is
	// the default policy: 8..128 characters, no composition rules, common
	// passwords rejected. Published by GET {api}/capabilities.
	Password PasswordPolicy
	// Username is the username rule: length, and whether and how often users
	// may rename themselves. Published by GET {api}/capabilities.
	Username UsernameConfig
	// TwoFactor configures MFA.
	TwoFactor TwoFactorConfig
	// Passkeys configures WebAuthn/FIDO2 passkey ceremonies.
	Passkeys PasskeyConfig
	// DeviceKeys enables the refreshless native-client device-key surface.
	// Off by default: enrollment is an email-code login, so hosts opt in
	// explicitly before RouteDeviceKeys is mounted or the engine issues
	// enrollment or login challenges.
	DeviceKeys DeviceKeysConfig
	// APIKeys configures opaque permission-group-owned machine credentials.
	APIKeys APIKeysConfig
	// Delegated configures the delegated-token mint route: the audience
	// allowlist and the TTL floor/default/ceiling. The zero value leaves the
	// route unmounted.
	Delegated DelegatedConfig
	// AuthorizationServer makes this deployment an OAuth 2.0 authorization
	// server and OpenID provider for its registered clients: they sign users
	// in here and receive tokens for registered resource servers. The zero
	// value leaves it off and its routes unmounted.
	AuthorizationServer AuthorizationServerConfig
	// Invitations turns invitations off. The zero value leaves them on.
	Invitations InvitationsConfig
	// Roles is the permission model: personas, their permissions and roles
	// (NewRoles). Nil is root-only.
	Roles *Roles
	// RemoteApplications declares the remote applications root controls, as
	// the whole set: New registers each one and disables any this deployment
	// declared at an earlier boot and no longer does. A removed application
	// is disabled, not deleted: its tokens stop at once, and it keeps its
	// roles for when it is declared again. Nil leaves the stored applications
	// alone. Applications registered through an operation
	// (Client.UpsertRemoteApplication, the bootstrap manifest) or declared by
	// a deployment sharing the account store are never touched.
	RemoteApplications []RemoteApplicationConfig
	// Languages declares the supported languages: the HTTP surface negotiates
	// the request's among them, and messages fall back to Default.
	Languages LanguageConfig

	// SolanaNetwork turns on Sign In With Solana for one chain; the zero value
	// leaves it off. Solana Name Service resolution is built in.
	SolanaNetwork iam.SolanaNetwork

	// SenderHealthInterval is how often Start re-runs the senders'
	// CheckHealth; 0 defaults to five minutes.
	SenderHealthInterval time.Duration

	// SessionEventRetention is how long session-event history rows
	// (sign-ins and revocations, with IP and user agent: personal data) are
	// kept. 0 defaults to 365 days; a negative value keeps them forever.
	SessionEventRetention time.Duration

	// River configures AuthKit's background jobs.
	River RiverConfig

	// HTTP configures the HTTP surface. Nil keeps the Client headless:
	// operations and Verifier only.
	HTTP *HTTPConfig
}

Config is the host configuration: plain data and policy. Everything that reaches outside the process (the pool, senders, keys, providers, hooks) is in Deps. authkit.New normalizes it once; authkit.Migrate reads Schema and River from the same value.

func Normalize

func Normalize(c Config, d Deps) (Config, error)

Normalize applies every default and checks every rule of c and d, once: authkit.New calls it and hands the result to the engine and the HTTP layer. It returns a normalized copy; normalizing that copy again changes nothing.

type CredentialPerms

type CredentialPerms struct {
	Resource
	Read   iam.Perm // list the group's API keys
	Manage iam.Perm // mint, revoke and re-role them
}

CredentialPerms are the credential permissions, registered with APIKeys or RemoteApplications.

type DelegatedConfig

type DelegatedConfig struct {
	// AllowDPoP allows binding to a browser key. The authorizer must handle
	// requests with iam.DelegationRequest.JWKThumbprint set and no
	// certificate.
	AllowDPoP bool
	// Audiences is the allowlist: requested audiences must be a subset, and an
	// empty request receives the whole list. Empty disables the route.
	Audiences []string
	// TTLFloor, TTLDefault and TTLCeiling bound the minted TTL, also of
	// Client.MintDelegatedAccessToken; unset fields default to 60s, 15m and
	// 1h (always, when the route is off), and 0 < floor <= default <= ceiling
	// must hold.
	TTLFloor   time.Duration
	TTLDefault time.Duration
	TTLCeiling time.Duration
}

DelegatedConfig configures the delegated-token mint route (POST {api}/delegated/token). AuthKit owns the mint mechanics (audience subset, TTL clamp, sender binding, grant check); the host supplies the authorizer (Deps.DelegatedAuthorization).

type Deps

type Deps struct {
	// Postgres is the durable store, required by every host-facing
	// constructor. It also holds AuthKit's short-lived auth state (codes,
	// ceremonies, attempt counters), shared by every replica.
	Postgres *pgxpool.Pool

	// KeySource signs and publishes tokens. Nil resolves keys from
	// Config.Keys. Hosts never handle the private key: they hand AuthKit a
	// source that signs.
	KeySource keys.Source
	// Providers are the external identity providers: provider.Google,
	// Apple, Discord and GitHub, or provider.OIDC and OAuth2 for any other.
	Providers []provider.Provider

	// Email delivers email. Nil means no email: flows that need one fail
	// unless Config.Registration.AllowMissingSenders is set. Start runs its
	// CheckHealth now and every Config.SenderHealthInterval; while it fails,
	// email flows are unavailable (Client.EmailAvailable).
	Email EmailSender
	// SMS delivers text messages, like Email (Client.SMSAvailable).
	SMS SMSSender

	// Entitlements returns the names of users' active entitlements (billing
	// tiers), keyed by user id; ids without any are absent. Admin views show
	// them all; Config.Token.EntitlementAllowlist selects which go into access
	// tokens.
	Entitlements func(ctx context.Context, userIDs []string) (map[string][]string, error)
	// EntitlementHolders returns the ids of the users who hold entitlement,
	// for ListUsers' Entitlement filter. Nil makes that filter fail with
	// iam.ErrEntitlementFilterUnavailable.
	EntitlementHolders func(ctx context.Context, entitlement string) ([]string, error)

	// OnEvent receives account and group changes (iam.Event) durably through
	// River: recorded in the change's transaction, delivered after commit at
	// least once, in order per user (per group for group events). A failure
	// is retried with backoff up to an hour apart and holds back that
	// subject's later events. It must be idempotent on Event.ID, ignore kinds
	// it does not know and never run in the change's transaction. Every
	// account issuer with OnEvent receives the account events. Events are
	// recorded from the first start of a deployment that sets it.
	OnEvent func(context.Context, iam.Event) error
	// OnPurge erases the host's data of a deleted account before AuthKit
	// purges the account, 30 days after its deletion. It runs durably through
	// River on every account issuer, and the purge waits until each has
	// succeeded; a failure is retried. It must be idempotent and honor
	// cancellation.
	OnPurge func(context.Context, iam.UserDeletion) error

	// OAuthGrants decides every grant of the authorization server: at
	// consent, token exchange and client credentials, and at every refresh.
	// Nil grants the defaults. Required when a client declares
	// AuthorizationDetailsTypes.
	OAuthGrants iam.OAuthGrantAuthorizer
	// DelegatedAuthorization decides delegated-token mints: its grant is the
	// complete authority AuthKit signs. Required when
	// Config.Delegated.Audiences is set.
	DelegatedAuthorization iam.DelegationAuthorizer
	// NameAdmission is the host's side-effect-free username policy for
	// account creation and renames; an error refuses the name.
	NameAdmission func(context.Context, iam.NameAdmissionRequest) error

	// Redis shares rate-limit counters across replicas; it holds no other
	// AuthKit state. Without it, and while it fails, each process counts on
	// its own with the same limits.
	Redis redis.UniversalClient
	// ClientIP extracts the client address, replacing the proxy handling of
	// HTTPConfig.
	ClientIP func(*http.Request) string
	// Wrap decorates every API and browser-OIDC handler at mount time.
	Wrap func(iam.Route, http.Handler) http.Handler
}

Deps is everything AuthKit reaches outside the process through: the store, keys, identity providers, senders and the host's hooks. Senders are provider objects; every hook is a func, so bind one late with a closure when it needs the Client first.

type DeviceKeysConfig

type DeviceKeysConfig struct {
	// Enabled mounts RouteDeviceKeys and lets the engine run enrollment and
	// login ceremonies.
	Enabled bool
}

DeviceKeysConfig controls the native-client device-key surface.

type EmailSender added in v0.149.0

type EmailSender interface {
	Send(ctx context.Context, msg iam.EmailMessage) error
	// CheckHealth reports, without sending, whether email can be delivered
	// now: nil when healthy, or when the provider can't tell.
	CheckHealth(ctx context.Context) error
}

EmailSender delivers email; adapters/twilio.NewEmail returns one.

type FormerNamesConfig

type FormerNamesConfig struct {
	// Mode is FormerNamesFinite (the default), FormerNamesForever or
	// FormerNamesImmediate.
	Mode FormerNamesMode
	// Duration is how long a finite reservation lasts; 0 defaults to 90 days.
	Duration time.Duration
}

FormerNamesConfig keeps a renamed-away username reserved for its owner, and resolving to them, for a while.

type FormerNamesMode

type FormerNamesMode string

FormerNamesMode says how long a former username stays reserved.

const (
	// FormerNamesFinite reserves it for FormerNamesConfig.Duration.
	FormerNamesFinite FormerNamesMode = "finite"
	// FormerNamesForever reserves it for good.
	FormerNamesForever FormerNamesMode = "forever"
	// FormerNamesImmediate frees it at once.
	FormerNamesImmediate FormerNamesMode = "immediate"
)

type FrontendConfig

type FrontendConfig struct {
	// BaseURL builds absolute links (password reset, verification, invites).
	// Empty defaults to Token.Issuer when that is a URL.
	BaseURL string
	// OIDCReturnPath is the SPA route AuthKit redirects to after it finishes a
	// browser sign-in with an identity provider (not the provider callback,
	// which AuthKit owns). Empty defaults to "/login/callback".
	OIDCReturnPath string
	// VerifyPath receives scanner-safe verification link landings. Empty
	// defaults to "/verify".
	VerifyPath string
	// PasswordResetPath receives scanner-safe password reset link landings.
	// Empty defaults to "/reset".
	PasswordResetPath string
	// PasswordlessPath receives passwordless sign-in links. Empty defaults to
	// "/passwordless".
	PasswordlessPath string
	// InvitePath receives group invitation links (?code=…); the SPA posts the
	// code to the redeem route. Empty defaults to "/accept-invite".
	InvitePath string
	// AuthorizePath receives an OAuth client's sign-in request
	// (?authorization=…) when the authorization server is on: the SPA signs
	// the user in, then approves the request through the API. Empty defaults
	// to "/authorize".
	AuthorizePath string
}

FrontendConfig describes host-owned frontend routes.

type HTTPConfig

type HTTPConfig struct {
	// Groups selects the mounted route groups. Nil mounts the default API
	// surface plus browser OIDC; non-nil mounts exactly the named groups.
	Groups []iam.RouteGroup
	// BasePath roots the whole surface. Empty derives it from Token.Issuer's
	// path ("https://example.com/auth" gives "/auth"); when the issuer is a
	// URL a set value must equal that path, because verifiers find JWKS at
	// the issuer plus iam.JWKSPath. Serve the paths unchanged: no StripPrefix
	// in front.
	BasePath string
	// APIPath is the JSON API's prefix beneath BasePath; AuthKit adds the
	// version segment, /v1, after it. Empty means "/api"; "/" puts /v1 right
	// beneath BasePath.
	APIPath string
	// PublicURL is where clients reach BasePath when a proxy in front changes
	// the origin or the path, such as "https://shop.example.com/sso". DPoP
	// proofs sent to the delegated-token route must name PublicURL plus the
	// route's path beneath BasePath. Empty defaults to Token.Issuer's origin
	// plus BasePath.
	PublicURL string
	// Exclude drops routes the host serves itself, named as iam.Route.Pattern
	// names them ("GET /.well-known/jwks.json"). An entry matching no route is
	// an error.
	Exclude []string
	// RefreshCookie delivers the rotating refresh token as an HttpOnly cookie
	// (iam.RefreshCookieName) instead of a JSON field. Browser mounts only:
	// the SPA and this handler must share an origin.
	RefreshCookie bool

	// RateLimits overlays bucket limits onto authkit.DefaultRateLimits;
	// unknown buckets are refused. Limits are in memory and per process unless
	// Deps.Redis shares them.
	RateLimits map[string]RateLimit
	// RedisKeyPrefix namespaces the rate-limit keys in Deps.Redis so
	// deployments can share one Redis. Empty derives "authkit:<schema>:".
	RedisKeyPrefix string

	// TrustedProxies are the CIDRs of reverse proxies whose X-Forwarded-For
	// is honoured.
	TrustedProxies []string
	// CloudflareProxies are Cloudflare's egress ranges: X-Forwarded-For plus
	// CF-Connecting-IP. Set them only where Cloudflare fronts an origin locked
	// down to it.
	CloudflareProxies []string
	// DirectPeerIP asserts nothing sits in front: RemoteAddr is the client.
	DirectPeerIP bool
}

HTTPConfig configures the HTTP surface: one handler serving the JSON API, browser OIDC and JWKS, every route beneath BasePath:

{BasePath}{APIPath}/v1/...           JSON API
{BasePath}/oidc/{provider}/...       browser OIDC
{BasePath}/.well-known/jwks.json     JWKS

Exactly what sits in front of AuthKit must be declared (TrustedProxies, CloudflareProxies, DirectPeerIP or Deps.ClientIP), or every client shares one proxy's per-IP rate-limit bucket.

type InvitationsConfig added in v1.3.0

type InvitationsConfig struct {
	// Disabled turns them off: no invitation is issued or honoured. The
	// invitation routes are not mounted, GET {api}/capabilities reports
	// invitations.enabled false, and CreateInvitation, redeeming a code and
	// registering with one return iam.ErrInvitationsDisabled. Listing and
	// revoking earlier invitations still work. Registration.NativeUserMode
	// "invite_only" cannot be combined with it.
	Disabled bool
}

InvitationsConfig controls invitations: invite links and emailed invitations into a group, and emailed invitations to register.

type KeysConfig

type KeysConfig struct {
	// Path is the directory holding keys.json (hot-reloaded on rotation) and
	// totp.key. Empty defaults to /vault/auth. With no keys.json, New fails
	// unless AllowEphemeralDevKeys or VerifyOnly is set.
	Path string
	// AllowEphemeralDevKeys generates an RSA signing key when Path holds no
	// keys.json, and a TOTP key when it holds no totp.key: in memory, or
	// written to Path when it is set so restarts reuse them. Development only.
	AllowEphemeralDevKeys bool
	// VerifyOnly builds AuthKit with no signer: minting returns
	// iam.ErrSigningNotConfigured, verification and permission reads work, and
	// JWKS serves an empty set. Key resolution is skipped.
	VerifyOnly bool
}

KeysConfig controls signing-key resolution when Deps.KeySource is nil. AuthKit reads no environment variables: binaries read their environment once and set these fields.

type LanguageConfig

type LanguageConfig struct {
	// Supported are the languages requests may select; empty accepts any.
	Supported []string
	// Default is the language when neither the account nor the request
	// chooses one; empty defaults to "en".
	Default string
}

LanguageConfig declares the supported languages as two-letter codes. The zero value is English only.

type MemberPerms

type MemberPerms struct {
	Resource
	Read   iam.Perm // see who holds which role, and the role catalog
	Manage iam.Perm // give someone a role, change it or take it away; invites
}

MemberPerms are a persona's built-in membership permissions.

type MigrateOptions

type MigrateOptions struct {
	// RuntimePool is the pool AuthKit will run with, as a less privileged
	// database user: Migrate grants that user runtime access. Both pools must
	// reach the same database. Nil provisions no runtime privileges.
	RuntimePool *pgxpool.Pool
}

MigrateOptions configures authkit.Migrate beyond what Config declares.

type OAuthClientConfig added in v1.5.0

type OAuthClientConfig struct {
	// ID is the client_id: 1-128 characters of letters, digits, '.', '_',
	// '-' and ':'.
	ID string
	// Name is shown to the user while they sign in for it; empty uses ID.
	Name string
	// SecretSHA256 makes the client confidential: the lowercase hex SHA-256
	// of its secret, which must be at least 32 random bytes. AuthKit never
	// holds the secret. Empty makes the client public (a browser or native
	// app), which must use PKCE and DPoP and cannot use client credentials.
	SecretSHA256 string
	// RedirectURIs are the exact redirect_uri values the client may use:
	// absolute https URLs, or http on a loopback host, without a fragment.
	RedirectURIs []string
	// PostLogoutRedirectURIs are the exact post_logout_redirect_uri values
	// RP-initiated logout may return to; the same rules apply.
	PostLogoutRedirectURIs []string
	// GrantTypes are the grants the client may use. Empty allows
	// authorization_code.
	GrantTypes []OAuthGrantType
	// Resources are the resource identifiers (ResourceServerConfig.ID) the
	// client may request tokens for. A request names one with the resource
	// parameter; with none, the access token is good for userinfo only.
	Resources []string
	// Permissions are a client-credentials client's own grants, as grant
	// patterns: its tokens carry them within the resource's ceiling.
	Permissions []string
	// Origins are browser origins ("https://admin.example.com") the client
	// calls the token endpoint from, besides its redirect URIs' origins: a
	// host frontend using token exchange.
	Origins []string
	// AuthorizationDetailsTypes are the RFC 9396 authorization_details types
	// the client may request ("machine_publication"). The host's grant
	// authorizer (Deps.OAuthGrants) decides each request, so declaring any
	// needs one.
	AuthorizationDetailsTypes []string
	// Offline lets the client request offline_access: its refresh tokens
	// stand on the grant, not the sign-in, so they keep working after the
	// user signs out, until the grant's lifetime ends, it is revoked
	// (Client.RevokeOAuthGrant) or the authorizer refuses a refresh. It
	// needs the refresh_token grant.
	Offline bool
	// KeyBound pins every grant of the client to a DPoP key: an
	// authorization request must name it (dpop_jkt), and every token request
	// must prove it, so each token is bound to that key.
	KeyBound bool
	// AccessTokenTTL overrides AuthorizationServerConfig.AccessTokenTTL for
	// the client, up to 15 minutes; 0 keeps the server's.
	AccessTokenTTL time.Duration
	// RefreshTokenTTL overrides AuthorizationServerConfig.RefreshTokenTTL
	// for the client, up to 30 days; 0 keeps the server's.
	RefreshTokenTTL time.Duration
}

OAuthClientConfig registers one OAuth client.

func FindOAuthClient added in v1.5.0

func FindOAuthClient(a AuthorizationServerConfig, id string) (OAuthClientConfig, bool)

FindOAuthClient returns the registered client with id.

type OAuthGrantType added in v1.5.0

type OAuthGrantType string

OAuthGrantType is an OAuth 2.0 grant type a client may use.

const (
	// GrantAuthorizationCode is the authorization code grant with PKCE.
	GrantAuthorizationCode OAuthGrantType = "authorization_code"
	// GrantRefreshToken issues rotating refresh tokens with the code grant.
	GrantRefreshToken OAuthGrantType = "refresh_token"
	// GrantTokenExchange is RFC 8693 token exchange: a frontend trades the
	// user's AuthKit access token for a resource's access token.
	GrantTokenExchange OAuthGrantType = "urn:ietf:params:oauth:grant-type:token-exchange"
	// GrantClientCredentials is a confidential client acting for itself.
	GrantClientCredentials OAuthGrantType = "client_credentials"
)

type PasskeyConfig

type PasskeyConfig struct {
	RPID             string
	RPDisplayName    string
	Origins          []string
	UserVerification string
}

PasskeyConfig configures the WebAuthn relying party. Empty fields derive from Frontend.BaseURL.

type PasswordPolicy

type PasswordPolicy struct {
	MinLength        int
	MaxLength        int
	RequireUppercase bool
	RequireLowercase bool
	RequireDigit     bool
	RequireSymbol    bool
	// AllowCommon admits passwords on AuthKit's embedded common-password
	// blocklist, which the zero value refuses.
	AllowCommon bool
}

PasswordPolicy is the password rule, NIST SP 800-63B-style by default. Lengths count Unicode code points; 0 defaults to 8 and 128, and MaxLength is at most 1024. Composition rules are opt-in: uppercase, lowercase and digit use Unicode categories, and a symbol is any rune that is neither a letter nor a digit.

func NormalizePassword

func NormalizePassword(out PasswordPolicy) (PasswordPolicy, error)

NormalizePassword returns the policy with its zero lengths defaulted.

type PersonaDef

type PersonaDef struct {
	Persona iam.Persona
	// Owner is the role every persona has: it holds All(). Root's also holds
	// every other persona's All(). A group's creator can be seeded with it
	// (iam.NewGroup.Owner).
	Owner       iam.Role
	Members     MemberPerms
	Credentials CredentialPerms
	// contains filtered or unexported fields
}

PersonaDef is one declared persona: the permissions and roles of its groups. AuthKit registers the built-in permission fields: Members always, Credentials with APIKeys or RemoteApplications. A role holding one that is not registered fails New.

func (*PersonaDef) All

func (p *PersonaDef) All() iam.Perm

All is `<persona>:*`: every permission of the persona.

func (*PersonaDef) Expand added in v1.1.0

func (p *PersonaDef) Expand(grants []iam.Perm) []iam.Perm

Expand lists every catalog permission some grant covers, in catalog order, such as a role's grants (Client.RolePermissions) or an actor's (Client.EffectivePermissions): the owner's `<persona>:*` lists each permission. GET /me/permissions answers the same expansion. It reads no database.

func (*PersonaDef) Permission

func (p *PersonaDef) Permission(resource, action string) iam.Perm

Permission declares the permission `<persona>:<resource>:<action>` and returns it.

func (*PersonaDef) Permissions added in v1.1.0

func (p *PersonaDef) Permissions() []iam.Perm

Permissions is the persona's catalog: the permissions declared with Permission and the built-ins AuthKit registers, sorted.

func (*PersonaDef) RequireMFA

func (p *PersonaDef) RequireMFA(perms ...iam.Perm)

RequireMFA marks permissions, or patterns over the persona's catalog, that need a second factor: a subject holding a grant that reaches one, through any role, include or root role, must have MFA enrolled, and no API key or application may hold it. root:members:manage and root:users:manage always need MFA.

func (*PersonaDef) Resource

func (p *PersonaDef) Resource(name string) Resource

Resource is one resource of the persona, for the pattern over all its actions.

func (*PersonaDef) Role

func (p *PersonaDef) Role(name string, grants ...iam.Grant) iam.Role

Role declares a role held in the persona's groups and returns it. Each grant is a permission or pattern (Resource.All, All), or a role of this persona whose permissions the new role includes. A persona role holds only its own persona's permissions; a root role may hold any persona's, and applies in every group of that persona.

type PersonaOption

type PersonaOption uint8

PersonaOption switches on a persona capability.

const (
	// APIKeys mounts the group API-key routes. It registers Credentials.
	APIKeys PersonaOption = iota + 1
	// RemoteApplications lets the persona's groups control remote
	// applications (Client.UpsertRemoteApplication). It registers Credentials.
	RemoteApplications
)

type RateLimit

type RateLimit = ratelimit.Limit

RateLimit allows at most Limit requests per Window in one bucket, with an optional Cooldown between accepted requests.

type RegistrationConfig

type RegistrationConfig struct {
	// Verification is "none" (the default), "optional" or "required". Every
	// policy stores the address unverified until proven; "optional" also
	// sends a code at registration. Unproven accounts cannot add sign-in
	// methods.
	Verification iam.RegistrationVerificationPolicy
	// NativeUserMode controls public self-registration: "open" (the default),
	// "invite_only" or "closed". The host operations (CreateUser, bootstrap,
	// import) work in every mode.
	NativeUserMode iam.RegistrationMode
	// PasswordlessLogin enables contact-based passwordless sessions.
	PasswordlessLogin bool
	// PasswordlessAutoRegistration lets a verified unknown contact create a
	// passwordless account during passwordless confirmation.
	PasswordlessAutoRegistration bool
	// AllowMissingSenders lets flows that deliver codes and links proceed with
	// no email or SMS sender: nothing is delivered and the engine hands the
	// code back to its caller (dev rigs read it there). By default a missing
	// sender is an error.
	AllowMissingSenders bool
	// VerificationSendTimeout bounds each in-line email or SMS send so an
	// unreachable provider cannot hang the request. 0 defaults to 15s.
	VerificationSendTimeout time.Duration
}

RegistrationConfig controls verification policy and public self-registration.

type RemoteApplicationConfig added in v1.3.0

type RemoteApplicationConfig struct {
	// Issuer is the iss of the tokens it signs: an absolute http(s) URL.
	Issuer string
	// JWKSURI is where its keys are fetched; PublicKeys is a static key list
	// instead. Set exactly one.
	JWKSURI    string
	PublicKeys []iam.RemoteApplicationKey
	// Disabled keeps it registered and refuses its tokens.
	Disabled bool
	// RootRole, when set, is the role it holds on root.
	RootRole iam.Role
}

RemoteApplicationConfig declares one remote application of the root group, keyed by Issuer. Only the system changes it (trust root manual).

type Resource

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

Resource is one resource of a persona.

func (Resource) All

func (r Resource) All() iam.Perm

All is `<persona>:<resource>:*`: every action on the resource.

type ResourceServerConfig added in v1.5.0

type ResourceServerConfig struct {
	// ID is the resource identifier, the access token's aud: an absolute URI
	// without a fragment, usually the API's base URL.
	ID string
	// Scopes are the OAuth scopes the resource defines; a client may request
	// any of them for it.
	Scopes []string
	// Permissions is the resource's permission ceiling, as grant patterns in
	// its own namespace ("merchant:*", "merchant:subscriptions:update"). An
	// access token for it carries, as permissions, the user's live grants on
	// the root group (what this deployment's roles assign them) intersected
	// with this ceiling, so the resource server authorizes from the token.
	// Empty mints tokens with no permissions.
	Permissions []string
}

ResourceServerConfig registers one resource server: an API that accepts this deployment's RFC 9068 access tokens.

func FindResourceServer added in v1.5.0

func FindResourceServer(a AuthorizationServerConfig, id string) (ResourceServerConfig, bool)

FindResourceServer returns the registered resource server with id.

type RiverConfig

type RiverConfig struct {
	// HostOwned declares a River fleet the host owns and shares with other
	// libraries: AuthKit never migrates, starts or stops it, and the host
	// registers Client.RiverJobs. False lets AuthKit run its own client.
	HostOwned bool
	// Schema holds River's tables; empty defaults to "public". Replicas and
	// libraries sharing a schema must register the same full job set.
	Schema string
	// CleanupInterval is how often expired auth state is cleaned up; 0
	// defaults to one hour.
	CleanupInterval time.Duration
}

RiverConfig configures AuthKit's River jobs (account lifecycle, events, cleanup).

func NormalizeRiver

func NormalizeRiver(r RiverConfig) (RiverConfig, error)

NormalizeRiver defaults River's schema to public and cleanup to hourly.

type Roles

type Roles struct {
	// Root is the persona with exactly one group, the whole site. A role held
	// on root applies in every group and may hold any persona's permissions.
	Root *RootDef
	// contains filtered or unexported fields
}

Roles is the app's permission model: its personas, their permissions and their roles. Every declaration returns a typed value (iam.Persona, iam.Perm, iam.Role) that the app then passes to AuthKit, so a misspelled name is a compile error, not a silent deny. Declare it once, typically in a package-level var block, and pass it as Config.Roles. New reads it and reports every declaration error; changes after New have no effect.

A persona is a type of permission group (channel, org, merchant). A permission group is one instance of a persona, created at run time by the host (Client.CreateGroup) for an entity of its own, such as the channel /c/golang. root is the persona with exactly one group, the whole site; it always exists. A permission is `<persona>:<resource>:<action>`; `*` may replace the action (`channel:posts:*`) or everything after the persona (`channel:*`, the owner).

func NewRoles

func NewRoles(opts ...PersonaOption) *Roles

NewRoles starts a permission model holding only root; opts switch on root's capabilities.

func (*Roles) Persona

func (r *Roles) Persona(name string, opts ...PersonaOption) *PersonaDef

Persona declares a persona and returns its definition. name is the first segment of every permission of its groups: `[a-z][a-z0-9-]*`.

type RootDef

type RootDef struct {
	*PersonaDef
	Users UserPerms
}

RootDef is root: a persona, plus the account administration permissions AuthKit registers on it.

type SMSSender added in v0.149.0

type SMSSender interface {
	Send(ctx context.Context, msg iam.SMSMessage) error
	// CheckHealth reports, without sending, whether messages can be delivered
	// now: nil when healthy, or when the provider can't tell.
	CheckHealth(ctx context.Context) error
}

SMSSender delivers text messages; adapters/twilio.NewSMS returns one.

type SignInConfig added in v1.3.0

type SignInConfig struct {
	// AccountsPerDevice caps the distinct accounts that sign in, or are
	// registered, from one device in 24 hours. Signing back into one of them
	// is always allowed; the next other account is refused with 429
	// too_many_accounts. 0 defaults to 5; negative turns it off.
	AccountsPerDevice int
	// AccountsPerAddress is AccountsPerDevice for a client without a device
	// cookie, counted per client address, which many people may share. 0
	// defaults to 20; negative turns it off.
	AccountsPerAddress int
	// NewDevicesPerAccount caps the new devices that sign in to one account
	// in 24 hours. A device that signed in to it within 30 days is not new.
	// Past the cap, a new device enters a code sent to the account's proven
	// email or phone (status device_verification_required); an account with
	// neither is refused with 429 too_many_devices. A sign-in that proved the
	// owner's email or phone, or a second factor, needs no code. 0 defaults
	// to 10; negative turns it off.
	NewDevicesPerAccount int
}

SignInConfig limits distinct accounts and devices over a rolling 24 hours. A device is a browser's device cookie (set by the HTTP surface); a client without one is known by its address (per /64 for IPv6). The counts live in the short-lived store every replica shares, never in a history.

func NormalizeSignIn added in v1.3.0

func NormalizeSignIn(c SignInConfig) SignInConfig

NormalizeSignIn applies the sign-in limit defaults; a negative limit is off and stays negative.

type TokenConfig

type TokenConfig struct {
	// Issuer is this deployment's JWT issuer (required), for example
	// "https://myapp.com". Its path, if any, is where the HTTP surface lives.
	Issuer string
	// IssuedAudiences are the audiences every issued token carries (at least
	// one).
	IssuedAudiences []string
	// ExpectedAudiences are the audiences verification accepts; empty
	// defaults to IssuedAudiences.
	ExpectedAudiences []string
	// AccessTokenDuration is the access-token lifetime; 0 defaults to 15
	// minutes, the longest a revoked session's token passes stateless checks.
	AccessTokenDuration time.Duration
	// RefreshTokenDuration is the refresh-session lifetime; 0 or less means
	// sessions do not expire by age.
	RefreshTokenDuration time.Duration
	// SessionMaxPerUser caps concurrent refresh sessions per user, evicting
	// the oldest. 0 defaults to 3; a negative value means unlimited.
	SessionMaxPerUser int
	// RefreshRotationGrace is how long a just-rotated refresh token keeps being
	// answered with the successor it rotated into instead of being read as
	// reuse and ending the session. It covers two holders of one token
	// refreshing at once (a shared credential file, a retried request). 0
	// defaults to 30s; a negative value makes rotation strictly single-use.
	RefreshRotationGrace time.Duration
	// EntitlementAllowlist selects the provider-granted entitlement names
	// (Deps.Entitlements) that access tokens carry. Empty skips the mint-time
	// lookup and omits the claim.
	EntitlementAllowlist []string
	// AccountIssuers lists every issuer whose deployment shares this account
	// store (the same Schema on the same database), e.g. two sites with
	// separate logins over one set of accounts. Account-level revocations
	// (admin emergency revoke, password or contact changes, ban, deletion)
	// cover refresh sessions on all of them, and they share membership: who
	// holds which role, root included. Each declares its own Roles: a role's
	// permissions are per app, and each app re-checks only the credentials it
	// issued. Issuer is always included; empty means Issuer alone. Every
	// deployment sharing the store should list the same set.
	AccountIssuers []string
	// AllowPrivateNetworkJWKS permits http and private or loopback JWKS URLs
	// for remote applications and the issuers verifiers trust, and turns off
	// the verifier's SSRF guard. Local federation rigs only.
	AllowPrivateNetworkJWKS bool
}

TokenConfig is the JWT issuing/verification contract plus session limits.

type TwoFactorConfig

type TwoFactorConfig struct {
	// Mode is the account-wide policy: iam.TwoFactorDisabled,
	// iam.TwoFactorOptional (the default) or iam.TwoFactorRequired (every user
	// enrolls before normal session use). Persona.RequireMFA enforces MFA per
	// permission; the root owner always needs it.
	Mode iam.TwoFactorMode
	// Methods are the enabled second-factor channels; empty enables email,
	// SMS and TOTP. A method whose dependency is missing (SMS with no sender)
	// is unavailable regardless. Unless Mode is disabled, New refuses a
	// deployment with none available: the root owner always needs MFA.
	Methods []iam.TwoFactorMethod
	// TOTPSecretKey encrypts stored authenticator-app secrets: 16, 24 or 32 raw
	// bytes. It overrides <Keys.Path>/totp.key; with neither, TOTP enrollment
	// is unavailable.
	TOTPSecretKey []byte
}

TwoFactorConfig configures MFA.

type UserPerms

type UserPerms struct {
	Resource
	Read   iam.Perm // look through accounts and their sign-in history
	Ban    iam.Perm // ban and unban
	Delete iam.Perm // delete an account, or restore it within its 30 days
	Manage iam.Perm // edit someone else's account and sign them out everywhere
	Invite iam.Perm // invite someone to create an account
}

UserPerms are root's account administration permissions.

type UsernameConfig

type UsernameConfig struct {
	// MinLength and MaxLength bound the length; 0 defaults to 4 and 30, and
	// MaxLength is at most 64.
	MinLength int
	MaxLength int
	// Renames lets users change their own username; off by default.
	Renames bool
	// RenameInterval is the least time between two renames of one account. 0
	// defaults to 72 hours; a negative value means no wait.
	RenameInterval time.Duration
	// FormerNames is what happens to a username its owner renamed away from.
	FormerNames FormerNamesConfig
}

UsernameConfig is the username rule. The characters are fixed: a letter, then letters, digits and underscores.

func NormalizeUsername

func NormalizeUsername(u UsernameConfig) (UsernameConfig, error)

NormalizeUsername applies the username defaults and rules.

Jump to

Keyboard shortcuts

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