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
- Variables
- func CompileRoles(r *Roles) (*rbac.Schema, error)
- func MountPath(field, p string) (string, error)
- func NormalizeSchema(raw string) (string, error)
- func ParseCIDRs(kind string, cidrs []string) ([]netip.Prefix, error)
- type APIKeysConfig
- type Config
- type CredentialPerms
- type DelegatedConfig
- type Deps
- type DeviceKeysConfig
- type EmailSender
- type FormerNamesConfig
- type FormerNamesMode
- type FrontendConfig
- type HTTPConfig
- type KeysConfig
- type LanguageConfig
- type MemberPerms
- type MigrateOptions
- type PasskeyConfig
- type PasswordPolicy
- type PersonaDef
- type PersonaOption
- type RateLimit
- type RegistrationConfig
- type Resource
- type RiverConfig
- type Roles
- type RootDef
- type SMSSender
- type TokenConfig
- type TwoFactorConfig
- type UserPerms
- type UsernameConfig
Constants ¶
const ( DefaultAPIPath = "/api/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 )
Defaults Normalize applies.
Variables ¶
var ReservedMetadataKeys = []string{"reserved"}
ReservedMetadataKeys are the user-metadata keys AuthKit owns.
Functions ¶
func CompileRoles ¶
CompileRoles checks the declared model and compiles it, once, into the schema the engine authorizes against; nil is root-only.
func MountPath ¶
MountPath normalizes a configured path: surrounding space and trailing slashes are dropped, so "/" is "" (root).
func NormalizeSchema ¶
NormalizeSchema trims and validates a PostgreSQL schema name, defaulting to "profiles". The name is spliced into SQL text, so this is the injection guard.
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 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
// 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. Nil is the default
// policy: 8..128 characters, no composition rules, common passwords
// rejected. A set policy is taken as written (zero lengths still default).
// 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
// Roles is the permission model: personas, their permissions and roles
// (NewRoles). Nil is root-only.
Roles *Roles
// Languages declares the supported languages: the HTTP surface negotiates
// the request's among them, and messages fall back to Default.
Languages LanguageConfig
// PublicUserMetadata lists the user-metadata keys (Client.PatchUserMetadata)
// that other people may see: PublicUsers returns these and no others.
PublicUserMetadata []string
// 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.
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 ConfirmationJWKThumbprintSHA256 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
// 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
// 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 each replica counts separately.
Redis redis.UniversalClient
// Limiter replaces AuthKit's rate limiter: it reports whether one more
// request is allowed in bucket for key. At most one of Redis and Limiter
// may be set.
Limiter func(bucket, key string) (bool, error)
// 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
// Clock replaces the engine clock for TTL and grace-window decisions. It
// never governs ephemeral state (codes, claims, counters), which always
// expires by the database clock so replicas agree.
Clock func() time.Time
}
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
}
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 anchors the JSON API beneath BasePath. Empty means "/api/v1";
// "/" is BasePath itself.
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; they do not apply to Deps.Limiter.
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}/... 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 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: in memory, or written to <Path>/keys.json when Path is set so
// restarts reuse it. Development only.
AllowEphemeralDevKeys bool
// VerifyOnly builds AuthKit with no signer: minting returns
// 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 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(p *PasswordPolicy) (*PasswordPolicy, error)
NormalizePassword returns the policy with defaults: nil is the default policy.
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) Permission ¶
func (p *PersonaDef) Permission(resource, action string) iam.Perm
Permission declares the permission `<persona>:<resource>:<action>` and returns it.
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 ¶
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 ¶
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 Resource ¶
type Resource struct {
// contains filtered or unexported fields
}
Resource is one resource of a persona.
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 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 revoking the family. 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.
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.