Documentation
¶
Index ¶
- Constants
- Variables
- func DefaultRateLimits() map[string]ratelimit.Limit
- func MuxPath(p string) string
- func SanitizeReturnTo(value string) string
- type AuthCapabilities
- type AuthChannelCapabilities
- type AuthPasskeyCapabilities
- type AuthPasswordCapabilities
- type AuthPasswordlessCapabilities
- type AuthPaths
- type AuthProviderSummary
- type AuthRegistrationCapabilities
- type AuthSolanaCapabilities
- type AuthUsernameCapabilities
- type AuthVerificationCapabilities
- type Backend
- type ClientIPFunc
- type CookieVariant
- type DelegatedTokenResponse
- type GroupOp
- type GroupRoute
- type Mount
- type RateLimitResult
- type RateLimiter
- type RateLimiterWithResult
- type RouteSpec
- type Service
- func (s *Service) APIRoutes(groups ...iam.RouteGroup) []RouteSpec
- func (s *Service) Backend() Backend
- func (s *Service) Capabilities() AuthCapabilities
- func (s *Service) Close()
- func (s *Service) GroupHandler(gr GroupRoute) http.HandlerFunc
- func (s *Service) JWKSHandler() http.Handler
- func (s *Service) OIDCBrowserRoutes(groups ...iam.RouteGroup) []RouteSpec
- func (s *Service) PermissionGroupRoutes() []RouteSpec
- func (s *Service) SMSAvailable() bool
- type TwoFactorFactorResponse
Constants ¶
const ( // 2FA-specific rate limit buckets RL2FAStartPhone = "auth_2fa_start_phone" RL2FAStartTOTP = "auth_2fa_start_totp" RL2FAStartEmail = "auth_2fa_start_email" RL2FAEnable = "auth_2fa_enable" RL2FADisable = "auth_2fa_disable" RL2FARegenerateCodes = "auth_2fa_regenerate_codes" RL2FAVerify = "auth_2fa_verify" RLAuthToken = "auth_token" RLAuthRegister = "auth_register" RLAuthRegisterAvailability = "auth_register_availability" RLAuthRegisterAbandon = "auth_register_abandon" RLInviteCreate = "auth_invite_create" RLInviteRedeem = "auth_invite_redeem" RLAPIKeyMint = "auth_api_key_mint" RLPasswordLogin = "auth_password_login" RLPasswordStepUp = "auth_password_step_up" RLPasswordlessStart = "auth_passwordless_start" RLPasswordlessConfirm = "auth_passwordless_confirm" RLPasskeyRegister = "auth_passkey_register" RLPasskeyLogin = "auth_passkey_login" RLDeviceKeyEnrollBegin = "auth_device_key_enroll_begin" RLDeviceKeyEnrollFinish = "auth_device_key_enroll_finish" RLDeviceKeyLoginBegin = "auth_device_key_login_begin" RLDeviceKeyLoginFinish = "auth_device_key_login_finish" RLDeviceKeysManage = "auth_device_keys_manage" RLAuthLogout = "auth_logout" RLAuthSessionsList = "auth_sessions_list" RLAuthSessionsRevoke = "auth_sessions_revoke" RLAuthSessionsRevokeAll = "auth_sessions_revoke_all" // #261 delegated-token mint (authenticated; bounds signing cost per IP). RLDelegatedTokenMint = "delegated_token_mint" RLPasswordResetRequest = "auth_pwd_reset_request" RLPasswordResetConfirm = "auth_pwd_reset_confirm" // #312: one bucket per contact flow, whichever channel the identifier names. RLVerifyRequest = "auth_verify_request" RLVerifyConfirm = "auth_verify_confirm" RLContactChangeRequest = "auth_contact_change_request" RLOIDCStart = "auth_oidc_start" RLOIDCCallback = "auth_oidc_callback" RLUserPasswordChange = "auth_user_password_change" RLUserMe = "auth_user_me" RLUserUpdateUsername = "auth_user_update_username" RLUserPreferredLanguage = "auth_user_preferred_language" RLUserDelete = "auth_user_delete" RLUserUnlinkProvider = "auth_user_unlink_provider" RLAdminUserSessionsList = "auth_admin_user_sessions_list" // The admin session route revokes ALL of a user's sessions; there is no // single-session admin revoke, so no RLAdminUserSessionsRevoke bucket. RLAdminUserSessionsRevokeAll = "auth_admin_user_sessions_revoke_all" // Solana SIWS authentication RLSolanaChallenge = "auth_solana_challenge" RLSolanaLogin = "auth_solana_login" RLSolanaLink = "auth_solana_link" )
Bucket names used by authkit endpoints; they key HTTPConfig.RateLimits.
const ( CookieRefresh cookieKind = "refresh" CookieOIDCState cookieKind = "oidc_state" OIDCStatePrefix = "authkit_oauth_state_" )
const OIDCPath = "/oidc"
Mount layout. The whole surface lives beneath one base path: the path of the issuer, so verifiers find JWKS at the issuer plus iam.JWKSPath. Beneath it, browser OIDC sits at OIDCPath and the JSON API at APIPath. The surface is ONE handler.
Variables ¶
var CookieRegistry = []CookieVariant{ {Kind: CookieRefresh, Name: "authkit_rt", Path: "/", Current: true}, {Kind: CookieRefresh, Name: "__Host-authkit_rt", Path: "/", Secure: true, Current: true}, {Kind: CookieOIDCState, Name: OIDCStatePrefix, Path: "/", Current: true}, {Kind: CookieOIDCState, Name: "__Host-" + OIDCStatePrefix, Path: "/", Secure: true, Current: true}, }
CookieRegistry is append-only.
var GroupRoutes = []GroupRoute{ {http.MethodGet, "/groups/:group_id/members", OpMembersList}, {http.MethodPost, "/groups/:group_id/members", OpMemberAdd}, {http.MethodDelete, "/groups/:group_id/members/:user", OpMemberRemove}, {http.MethodPut, "/groups/:group_id/members/:user/roles/:role", OpMemberRoleAssign}, {http.MethodGet, "/groups/:group_id/roles", OpRolesList}, {http.MethodGet, "/groups/:group_id/api-keys", OpAPIKeysList}, {http.MethodPost, "/groups/:group_id/api-keys", OpAPIKeyMint}, {http.MethodDelete, "/groups/:group_id/api-keys/:key", OpAPIKeyRevoke}, {http.MethodGet, "/groups/:group_id/invites/links", OpInviteLinkList}, {http.MethodPost, "/groups/:group_id/invites/links", OpInviteLinkMint}, {http.MethodDelete, "/groups/:group_id/invites/links/:link", OpInviteLinkRevoke}, }
GroupRoutes is the whole group-management surface.
Functions ¶
func DefaultRateLimits ¶
DefaultRateLimits returns AuthKit's built-in per-endpoint rate limits, per client IP; "default" applies to any bucket not listed. Hosts overlay them with HTTPConfig.RateLimits or replace the limiter.
func MuxPath ¶
MuxPath rewrites colon-style params (":group_id", ":user", ...) into net/http ServeMux wildcards ("{group_id}", "{user}", ...). ServeMux wildcard names may not contain '-', so hyphens become underscores; pathParam() reverses this when reading r.PathValue.
func SanitizeReturnTo ¶
sanitizeReturnTo admits only a same-origin absolute path: a leading "/" but not "//" or "/\" (browsers read both as scheme-relative), no control characters, no scheme or host. Anything else becomes "/".
Types ¶
type AuthCapabilities ¶
type AuthCapabilities struct {
Registration AuthRegistrationCapabilities `json:"registration"`
ExternalLoginProviders []AuthProviderSummary `json:"external_login_providers"`
Username AuthUsernameCapabilities `json:"username"`
Password AuthPasswordCapabilities `json:"password"`
Passwordless AuthPasswordlessCapabilities `json:"passwordless"`
Passkeys AuthPasskeyCapabilities `json:"passkeys"`
Solana AuthSolanaCapabilities `json:"solana"`
Verification AuthVerificationCapabilities `json:"verification"`
Channels AuthChannelCapabilities `json:"channels"`
Languages []string `json:"languages,omitempty"`
Paths AuthPaths `json:"paths"`
}
AuthCapabilities is the public, static auth feature-discovery response.
type AuthChannelCapabilities ¶
AuthChannelCapabilities says which contact channels can deliver now: a sender is configured and, for SMS, its latest health check passed.
type AuthPasskeyCapabilities ¶
type AuthPasskeyCapabilities struct {
Login bool `json:"login"`
}
type AuthPasswordCapabilities ¶
type AuthPasswordCapabilities struct {
MinLength int `json:"min_length"`
MaxLength int `json:"max_length"`
RequireUppercase bool `json:"require_uppercase"`
RequireLowercase bool `json:"require_lowercase"`
RequireDigit bool `json:"require_digit"`
RequireSymbol bool `json:"require_symbol"`
RejectCommon bool `json:"reject_common"`
}
AuthPasswordCapabilities publishes everything a browser needs to pre-validate a new password except the blocklist itself.
type AuthPaths ¶
type AuthPaths struct {
API string `json:"api"`
OIDC string `json:"oidc,omitempty"`
JWKS string `json:"jwks,omitempty"`
}
AuthPaths are the serving mount's anchors as full paths, so a client that knows one AuthKit URL finds the rest. Unmounted anchors are omitted.
type AuthProviderSummary ¶
type AuthSolanaCapabilities ¶
type AuthSolanaCapabilities struct {
Login bool `json:"login"`
}
type AuthUsernameCapabilities ¶
type AuthUsernameCapabilities struct {
MinLength int `json:"min_length"`
MaxLength int `json:"max_length"`
Pattern string `json:"pattern"`
Renames bool `json:"renames"`
RenameIntervalSeconds int64 `json:"rename_interval_seconds"`
FormerNames naming.PolicyInfo `json:"former_names"`
}
AuthUsernameCapabilities publishes the interactive username rule. Pattern is the fixed character rule; length is bounded separately. Renames says whether users may rename themselves, and how often.
type AuthVerificationCapabilities ¶
type AuthVerificationCapabilities struct {
Registration string `json:"registration"`
}
type Backend ¶
type Backend interface {
ops.Operations
// contains filtered or unexported methods
}
Backend is the engine capability the HTTP layer drives: the operations the Client exposes (ops.Operations) plus the flows only the HTTP layer runs. The engine implements it; hosts never see it. Each domain's flow methods live in its own backend_<domain>.go.
type ClientIPFunc ¶
ClientIPFunc determines the client IP used for rate limiting and auditing.
Returning an empty string means "unknown" and causes rate limiting to fail open.
func ClientIPFromForwardedHeaders ¶
func ClientIPFromForwardedHeaders(trusted, cloudflare []netip.Prefix) ClientIPFunc
ClientIPFromForwardedHeaders derives the client IP behind proxies the host declared. A peer inside trusted or cloudflare enables the right-to-left X-Forwarded-For walk (hops in either set are skipped as our own). Only a peer inside cloudflare may additionally be trusted for CF-Connecting-IP, and only as a fallback when X-Forwarded-For yields nothing: a generic reverse proxy forwards CF-Connecting-IP verbatim, so honouring it from any trusted peer let a client pick its own rate-limit key (ak#298). Any other peer resolves to itself.
Hosts that pass a cloudflare set must also lock the origin down to Cloudflare ingress; otherwise a client that reaches the origin directly is its own peer and both headers are ignored, which is the safe outcome.
func DefaultClientIP ¶
func DefaultClientIP() ClientIPFunc
DefaultClientIP returns the immediate peer IP from RemoteAddr.
This intentionally includes private and loopback peers so embedded/local deployments still get default rate-limit protection. Hosts behind reverse proxies should use ClientIPFromForwardedHeaders with trusted proxy CIDRs when they need the original public client IP instead of the proxy peer.
type CookieVariant ¶
type CookieVariant struct {
Kind cookieKind
Name string
Path string
Domain string // AuthKit never sets Domain: every variant is host-only
Secure bool // issued on HTTPS deployments (always true for __Host-)
// Current marks the variant AuthKit issues now, per Secure mode.
Current bool
}
CookieVariant is one cookie shape AuthKit issues. An OIDC state name is a prefix completed by stateCookieName.
func CurrentCookie ¶
func CurrentCookie(kind cookieKind, secure bool) CookieVariant
func (CookieVariant) Identity ¶
func (v CookieVariant) Identity() string
Identity names a variant in testdata/cookie-registry.golden.
type DelegatedTokenResponse ¶
type GroupOp ¶
type GroupOp int
GroupOp is the operation a group route performs.
type GroupRoute ¶
GroupRoute is one group-management endpoint.
func MountedGroupRoutes ¶
func MountedGroupRoutes(s *rbac.Schema) []GroupRoute
MountedGroupRoutes returns the group routes some persona of s has.
type Mount ¶
type Mount struct {
// contains filtered or unexported fields
}
Mount is the canonical HTTP handler and its route catalog. Framework adapters use the catalog to register native routes, delegating requests to ServeHTTP so AuthKit still owns path values, authentication, JSON and cookie guards.
func NewMount ¶
NewMount builds the full AuthKit surface — JSON API, browser OIDC and JWKS — as ONE net/http handler plus its route catalog, as Config.HTTP declares it. Every route keeps the gate its RouteSpec carries; the mount adds no auth and removes none. Excluding a route does not alter the MFA-enrollment exempt set, so a shadowed enroll route stays reachable through the host's replacement.
type RateLimitResult ¶
type RateLimitResult struct {
Allowed bool
RetryAfter time.Duration
Availability *authflow.ActionAvailability
}
type RateLimiter ¶
RateLimiter is a minimal interface used by adapters.
type RateLimiterWithResult ¶
type RouteSpec ¶
type RouteSpec struct {
Method string
Path string
Group iam.RouteGroup
Handler http.Handler
// Auth is the tier the handler wrapper enforces before the handler runs;
// Permission names the root/group permission for AuthPermission (#328).
Auth iam.RouteAuthTier
Permission string
// Bucket is the per-IP rate-limit bucket APIRoutes applies in front of the
// handler ("" = none). Per-identifier and branch-specific buckets stay in
// the handler.
Bucket string
// MFAEnrollmentExempt marks a route as part of the 2FA enroll/challenge/
// verify surface a forced-enrollment-gated user (TwoFactor.Mode required)
// must still be able to reach. NewMount derives the engine's exempt-path
// allowlist from routes tagged here (#243) — the route table is the single
// source of truth, so a rename/add stays consistent by construction.
MFAEnrollmentExempt bool
}
RouteSpec is a concrete, prefix-neutral route with its AuthKit handler attached. Path parameters use net/http ServeMux syntax, e.g. "/namespaces/{slug}".
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service wraps the internal AuthKit engine with net/http mounting helpers.
func New ¶
New assembles the HTTP layer over the engine, which also authenticates its requests, from the normalized configuration. authkit.New is the only production caller.
func (*Service) APIRoutes ¶
func (s *Service) APIRoutes(groups ...iam.RouteGroup) []RouteSpec
APIRoutes returns AuthKit's enabled JSON API routes. With no groups it returns the default API surface. With groups, it returns only matching routes.
func (*Service) Capabilities ¶
func (s *Service) Capabilities() AuthCapabilities
func (*Service) Close ¶
func (s *Service) Close()
Close stops the background work New started: the memory limiter sweep. The engine and Redis client are borrowed and remain owned by the host. Idempotent; safe on a nil Service.
func (*Service) GroupHandler ¶
func (s *Service) GroupHandler(gr GroupRoute) http.HandlerFunc
GroupHandler returns the handler for one group route. It:
- derives the caller's actor (401 if none; 403 for a delegation);
- resolves :group_id to a live group;
- refuses a group whose persona lacks the route, like an unknown group;
- authorizes the route's permission on the group with the engine's live Can, for every actor kind (403 on deny);
- performs the operation, whose engine call applies its own rules.
func (*Service) JWKSHandler ¶
JWKSHandler returns a handler for GET /.well-known/jwks.json. The key set is read per request so a hot-reloaded rotation or key removal is published immediately (ak#392).
func (*Service) OIDCBrowserRoutes ¶
func (s *Service) OIDCBrowserRoutes(groups ...iam.RouteGroup) []RouteSpec
OIDCBrowserRoutes returns browser redirect routes with no mount prefix.
func (*Service) PermissionGroupRoutes ¶
PermissionGroupRoutes returns the group-management routes some persona has, plus the caller's own groups and permissions. Mirrors APIRoutes: prefix-neutral RouteSpecs, rate-limited by their bucket, language-wrapped and gated by their tier.
func (*Service) SMSAvailable ¶
SMSAvailable reports whether phone-based flows should be offered (a sender is configured and, if checked, found able to deliver).
type TwoFactorFactorResponse ¶
Source Files
¶
- account_recovery.go
- admin_roles.go
- admin_routes.go
- admin_signins.go
- audit.go
- auth_token_post.go
- auth_tokens.go
- availability.go
- backend.go
- backend_apps.go
- backend_flows.go
- backend_groups.go
- backend_invites.go
- backend_sessions.go
- backend_users.go
- browser_error.go
- buckets.go
- client_ip.go
- confirm_errors.go
- contact_channel.go
- cookies.go
- delegated_token.go
- device_keys.go
- errors.go
- group_apikeys.go
- group_invites.go
- group_members.go
- group_routes.go
- internal_errors.go
- json_boundary.go
- jwks_get.go
- language.go
- login_continuation.go
- logout_delete.go
- mount.go
- oidc_browser.go
- oidc_util.go
- page.go
- passkeys.go
- password_login_post.go
- passwordless.go
- permission_gate.go
- permission_group_routes.go
- providers.go
- providers_get.go
- ratelimit.go
- refresh_cookie.go
- register.go
- register_availability.go
- routes.go
- server.go
- service.go
- solana_siws.go
- step_up.go
- user_2fa.go
- user_2fa_verify_post.go
- user_me_get.go
- user_password_post.go
- user_routes.go
- user_sessions.go
- util.go