auth

package module
v0.45.7 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 50 Imported by: 22

README

go-auth

A Go authentication library providing JWT based authentication, password management, and role based access control with support for resource level permissions.

Features

  • JWT token generation and validation with structured claims
  • Password hashing and verification using bcrypt
  • User registration and login with email validation
  • Password reset flow with email verification
  • Role based access control (RBAC) with hierarchical permissions
  • Resource level permissions for fine grained access control
  • HTTP middleware for route protection
  • Built in authentication controllers for web applications
  • Database persistence layer using Bun ORM
  • OAuth2 social login (GitHub, Google) with account linking
  • Customizable identity providers and role providers
  • Store backed permission resolver cache with pluggable backends
  • OIDC/provider sessions, lifecycle coordination, assurance/freshness and audit hooks

Package and documentation map

Use Go 1.26.0 or newer as required by go.mod.

Package/module Ownership Guide
Root auth, repository, middleware Local tokens/passwords, account state, controllers, actor context, permission/freshness contracts and storage Sections below; middleware
social Provider OAuth account links in social_accounts Social login
provider/oidc Browser OIDC, immutable provider identity linking and local-token/provider-session callback modes OIDC
provider/auth0 Auth0 JWT validation and optional identity mirroring Auth0
provider/supabase Supabase identity, session/factor and lifecycle capability adapters Supabase
activitymap Producer event normalization; downstream disclosure/retention remains host-owned Activity mapping
adapters/featuregate Separate module mapping actor context into feature claims/permissions Featuregate adapter
adapters/goadmin Separate module mounting browser SSO and account-link/logout UI routes Admin adapter

The root module does not import go-admin. Install optional adapter modules only when those integrations are needed; check their own go.mod and release tags. examples is a separate runnable-example module.

Provider sessions are server-side records with encrypted token material and opaque browser handoffs. OIDC state/nonce/PKCE, lifecycle fences and operations, refresh/revocation and identity binding have explicit storage/policy contracts; configuring an external token validator alone does not assemble this runtime. The OIDC and Supabase guides describe callback modes and migration requirements.

When an IdentityProvider is configured, SessionFromToken and the HTTP protected-route middleware re-read the signed user ID and reject inactive, missing or mismatched identities and provider lookup errors. This adds one identity lookup per successfully validated token. Use SessionFromTokenContext(ctx, token) to pass request cancellation to that lookup. A nil or typed-nil provider keeps token-validation-only behavior; low-level TokenService.Validate remains a cryptographic check.

JWT validity also does not prove current authorization. Sensitive operations can compose AuthorizationFreshnessGuard with authoritative session/account, assurance and permission-version resolvers, invalidation and explicit operation policy. Hosts own step-up delivery and dependency-outage decisions. See authorization_freshness.go, freshness_policy.go, and freshness_invalidation.go; local passwords and external provider sessions use separate credential lifecycles.

Installation

go get github.com/goliatone/go-auth

Quick Start

Basic Authentication Setup

Supply a tracker implementing both UserTracker and AtomicLoginAttemptTracker; password verification requires atomic attempt reservation. RepositoryManager.Users() exposes additional query arguments and needs a small adapter rather than being passed directly. See the tracker adapter in the runnable example for Bun wiring.

package main

import (
    "context"
    "fmt"

    "github.com/goliatone/go-auth"
)

type AppAuthConfig struct {
    SigningKey            string
    SigningMethod         string
    ContextKey            string
    TokenExpiration       int
    ExtendedTokenDuration int
    TokenLookup           string
    AuthScheme            string
    Issuer                string
    Audience              []string
    RejectedRouteKey      string
    RejectedRouteDefault  string
}

func (c AppAuthConfig) GetSigningKey() string           { return c.SigningKey }
func (c AppAuthConfig) GetSigningMethod() string        { return c.SigningMethod }
func (c AppAuthConfig) GetContextKey() string           { return c.ContextKey }
func (c AppAuthConfig) GetTokenExpiration() int         { return c.TokenExpiration }
func (c AppAuthConfig) GetExtendedTokenDuration() int   { return c.ExtendedTokenDuration }
func (c AppAuthConfig) GetTokenLookup() string          { return c.TokenLookup }
func (c AppAuthConfig) GetAuthScheme() string           { return c.AuthScheme }
func (c AppAuthConfig) GetIssuer() string               { return c.Issuer }
func (c AppAuthConfig) GetAudience() []string           { return c.Audience }
func (c AppAuthConfig) GetRejectedRouteKey() string     { return c.RejectedRouteKey }
func (c AppAuthConfig) GetRejectedRouteDefault() string { return c.RejectedRouteDefault }

func authenticateExample(tracker interface {
    auth.UserTracker
    auth.AtomicLoginAttemptTracker
}) error {
    userProvider := auth.NewUserProvider(tracker)

    // Any struct that satisfies auth.Config works.
    config := AppAuthConfig{
        SigningKey:            "your-secret-key",
        SigningMethod:         "HS256",
        ContextKey:            "auth",
        TokenExpiration:       24, // hours
        ExtendedTokenDuration: 24 * 7,
        TokenLookup:           "header:Authorization",
        AuthScheme:            "Bearer",
        Issuer:                "your-app",
        Audience:              []string{"your-audience"},
        RejectedRouteKey:      "redirect",
        RejectedRouteDefault:  "/",
    }

    authenticator := auth.NewAuthenticator(userProvider, config)

    // Login user
    token, err := authenticator.Login(context.Background(), "user@example.com", "password")
    if err != nil {
        return err
    }

    // Validate token and get session
    session, err := authenticator.SessionFromToken(token)
    if err != nil {
        return err
    }

    fmt.Printf("User ID: %s\n", session.GetUserID())
    return nil
}
Temporary bootstrap passwords

go-auth recognizes temporary password metadata on local users:

  • password_temporary
  • password_change_required
  • password_temporary_issued_at
  • password_temporary_expires_at

UserProvider.VerifyIdentity rejects a matching password when password_temporary=true and the expiry is in the past, missing, or malformed. Before expiry, login succeeds so the host can redirect the user to a password-change flow. Add auth.TemporaryPasswordClaimsDecorator() to copy compact password-change hints into JWT/session metadata. Use TemporaryPasswordResetRepository.ResetPasswordAndClearTemporaryPassword when a permanent password reset must clear temporary-password metadata in the same transaction as the password hash update. Repositories that do not expose this optional primitive still support ordinary password resets for users without temporary-password metadata.

Enhanced Resource Level Permissions
// Implement ResourceRoleProvider for fine-grained permissions
type CustomResourceRoleProvider struct {
    repo auth.RepositoryManager
}

func (p *CustomResourceRoleProvider) FindResourceRoles(ctx context.Context, identity auth.Identity) (map[string]string, error) {
    resourceRoles := make(map[string]string)

    switch identity.Role() {
    case "admin":
        resourceRoles["admin:dashboard"] = "owner"
        resourceRoles["project:default"] = "admin"
    case "user":
        resourceRoles["project:default"] = "member"
    }

    return resourceRoles, nil
}

// Use enhanced authenticator
authenticator = authenticator.WithResourceRoleProvider(&CustomResourceRoleProvider{repo: repoManager})

// Generated tokens will include resource-specific permissions
token, err := authenticator.Login(ctx, "admin@example.com", "password")
HTTP Integration
// Create HTTP authenticator for web applications
httpAuth, err := auth.NewHTTPAuthenticator(authenticator, config)
if err != nil {
    log.Fatal(err)
}

// Register browser authentication routes (login, register, password reset)
// with one stable package-managed CSRF contract.
err = auth.RegisterSecureAuthRoutes(
    router.Group("/auth"),
    auth.AuthRouteSecurityConfig{
        CSRF: csrf.Config{
            SecureKey: auth.DeriveBrowserCSRFSecureKey(config),
        },
    },
    auth.WithControllerLogger(logger),
    func(ac *auth.AuthController) *auth.AuthController {
        ac.Auther = httpAuth
        ac.Repo = repoManager
        return ac
    },
)
if err != nil {
    log.Fatal(err)
}

// Protect routes with middleware
protected := httpAuth.ProtectedBrowserRoute(config, errorHandler)
router.Get("/profile", profileHandler, protected)

RegisterAuthRoutes remains available for compatibility and now shares one process-local stateless CSRF key across its route set. Prefer RegisterSecureAuthRoutes with an explicit stable key for deployed browser applications, especially when requests can reach multiple instances.

Success handler contract (jwt middleware) The JWT middleware now invokes a SuccessHandler with the signature func(ctx router.Context, next router.HandlerFunc) error. The default simply calls next(ctx). If you override it, you are responsible for deciding whether to call next (run the protected handler) or short-circuit (e.g., redirect). Example:

protected := httpAuth.ProtectedRoute(config, errorHandler)

// Custom success hook that adds logging, then runs the handler
wrapped := func(ctx router.Context) error {
    return protected(func(c router.Context) error {
        log.Println("auth ok for", c.Path())
        return profileHandler(c) // or c.Next() if chaining
    })(ctx)
}

router.Get("/profile", profileHandler, wrapped)
Social Login (OAuth2)
import (
    "encoding/base64"

    "github.com/goliatone/go-auth/social"
    "github.com/goliatone/go-auth/social/providers/github"
    "github.com/goliatone/go-auth/social/providers/google"
    repo "github.com/goliatone/go-auth/repository"
)

stateEncKey, _ := base64.StdEncoding.DecodeString(cfg.Social.StateEncryptionKey)
stateHMACKey, _ := base64.StdEncoding.DecodeString(cfg.Social.StateHMACKey)

socialRepo := repo.NewSocialAccountRepository(bunDB)

socialAuth := social.NewSocialAuthenticator(
    socialRepo,
    repoManager.Users(),
    authenticator.TokenService(),
    social.SocialAuthConfig{
        DefaultRedirectURL:   "/",
        StateEncryptionKey:   stateEncKey,
        StateHMACKey:         stateHMACKey,
        AllowSignup:          true,
        AllowLinking:         true,
        RequireEmailVerified: true,
    },
    social.WithProvider(github.New(github.Config{
        ClientID:     cfg.Social.GitHubClientID,
        ClientSecret: cfg.Social.GitHubClientSecret,
        CallbackURL:  cfg.BaseURL + "/auth/social/github/callback",
    })),
    social.WithProvider(google.New(google.Config{
        ClientID:     cfg.Social.GoogleClientID,
        ClientSecret: cfg.Social.GoogleClientSecret,
        CallbackURL:  cfg.BaseURL + "/auth/social/google/callback",
    })),
)

socialController := social.NewHTTPController(socialAuth, social.HTTPConfig{
    PathPrefix:        "/auth/social",
    SessionContextKey: cfg.Auth.GetContextKey(),
    CookieName:        cfg.Auth.GetContextKey(),
    SuccessRedirect:   "/dashboard",
    ErrorRedirect:     "/login?error=auth_failed",
    CookieSecure:      true,
    CookieHTTPOnly:    true,
    CookieSameSite:    "Lax",
})
socialController.RegisterRoutes(router.Group("/auth/social"))

Routes registered by the controller:

  • GET /auth/social/providers
  • GET /auth/social/:provider
  • GET /auth/social/:provider/callback
  • POST /auth/social/:provider/link
  • DELETE /auth/social/:provider
  • GET /auth/social/accounts

See docs/SOCIAL_LOGIN.md for linking policies, migration guidance, and security notes. Example wiring lives in examples/extensions/social_login.go.

Social OAuth account links use social_accounts. Browser SSO provider-subject links use user_identifiers. Keep those tables distinct unless your host implements an explicit migration or lookup bridge.

Generic OIDC browser SSO lives in provider/oidc; go-admin integration lives in the nested adapters/goadmin module. See docs/OIDC.md for setup and operational troubleshooting.

Auth0 Integration (Optional)

Auth0 support is opt-in and uses provider/auth0 for JWT validation and claims mapping. For Auth0 + local tokens, use NewMultiTokenValidator to accept both.

import "github.com/goliatone/go-auth/provider/auth0"

auth0Validator, err := auth0.NewTokenValidator(auth0.Config{
    Domain:   "your-tenant.auth0.com",
    Audience: []string{"https://api.yourapp.com"},
})
if err != nil {
    return err
}

authenticator := auth.NewAuthenticator(userProvider, cfg.Auth)

// Accept Auth0 tokens only.
authenticator = authenticator.WithTokenValidator(auth0Validator)

// Or accept Auth0 + local go-auth tokens.
composite := auth.NewMultiTokenValidator(auth0Validator, authenticator.TokenService())
authenticator = authenticator.WithTokenValidator(composite)

For sync (local mirroring), use provider/auth0/sync with auth.IdentifierStore. See docs/AUTH0.md and examples/auth0/ for full examples.

Auth0 validation errors normalize to ErrTokenExpired / ErrTokenMalformed with provider=auth0 metadata. Use HasUserUUID(session) before calling Session.GetUserUUID because Auth0 sub values are not UUIDs.

Session with Resource Permissions
// Check permissions in handlers
func profileHandler(c router.Context) error {
    session, err := auth.GetRouterSession(c, "auth")
    if err != nil {
        return err
    }

    // Enhanced session with resource-level permissions
    if roleCapableSession, ok := session.(auth.RoleCapableSession); ok {
        canEditSettings := roleCapableSession.CanEdit("admin:settings")
        canDeleteUsers := roleCapableSession.CanDelete("admin:users")
        hasAdminRole := roleCapableSession.HasRole("admin")
        isAtLeastMember := roleCapableSession.IsAtLeast("member")

        // Use permissions for authorization logic
    }

    return c.JSON(map[string]any{
        "user_id": session.GetUserID(),
        "data": session.GetData(),
    })
}
CSRF Protection

go-auth ships with a CSRF middleware that plugs into go-router and the template helper stack.

Construct a middleware instance once and reuse it for every route that participates in the same form flow. The generated stateless signing key belongs to that middleware instance; calling csrf.New() separately for the GET and POST sides intentionally creates separate protection domains.

Stateless (default)

import (
    csrf "github.com/goliatone/go-auth/middleware/csrf"
    "github.com/goliatone/go-router"
)

func main() {
    server := router.NewFiberAdapter()
    app := server.Router()

    // HMAC-signed tokens; a random key is generated once for this middleware.
    app.Use(csrf.New())

    app.Post("/submit", func(ctx router.Context) error {
        // Token checked automatically
        return ctx.SendStatus(router.StatusNoContent)
    })

    if err := server.Serve(":8080"); err != nil {
        panic(err)
    }
}

Stateful (storage backed)

type redisStorage struct{ client *redis.Client }

func (r *redisStorage) Get(key string) (string, error) {
    return r.client.Get(context.Background(), key).Result()
}

// Set/Delete omitted for brevity

app.Use(csrf.New(csrf.Config{
    Storage:    &redisStorage{client: redisClient},
    Expiration: 24 * time.Hour,
}))

Templates

// Inside your handler
viewCtx := auth.MergeTemplateData(ctx, router.ViewContext{
    "title": "Secure form",
})

// MergeTemplateData copies the latest request scoped helpers so csrf_field,
// csrf_meta, etc. always render the token minted by the middleware.
return ctx.Render("form", viewCtx)

csrf_field, csrf_token, and csrf_meta are now lazily evaluated helpers. When you register auth.TemplateHelpers() globally, the template engine resolves the current request’s CSRF token automatically—no need to clone helper maps on every render (though MergeTemplateData remains useful when you want a concrete snapshot).

<form method="post">
  {{ csrf_field }}
  <!-- other fields -->
</form>

<script>
  const token = "{{ csrf_token }}";
  const header = "{{ csrf_header_name }}";
  fetch("/submit", {
    method: "POST",
    headers: { [header]: token },
  });
</script>
<!-- Layout head section -->
{{ csrf_meta }}
<meta name="another-example" content="value" />

For the explicit Fiber v3 view engine, register auth.TemplateHelpersForPongo2V7() instead of auth.TemplateHelpers(). A shared router view configuration can retain both runtime-specific maps:

cfg := router.NewSimpleViewConfig("views").
    WithFunctions(auth.TemplateHelpers()).
    WithFiberV3Functions(auth.TemplateHelpersForPongo2V7())

The v7 helper map does not change the legacy factory. Both read the current request's template_helpers map and return plain strings; normal template escaping still applies. Use |safe only for the trusted markup generated by the CSRF middleware (csrf_field and csrf_meta). Custom template integrations can select a factory per renderer with csrf.CSRFTemplateHelpersWithFactory(factory); a nil factory returns static placeholders without consulting or changing the default.

When auth claims are included in view locals, wrap the configured engine before installing it in the host's view configuration:

engine, err := router.InitializeFiberV3ViewEngine(cfg)
// Handle err, then use this as the host's Views value:
views := auth.NewTemplateViews(engine)

NewTemplateViews is opt-in and also works with the v2 engine. It copies plain render maps and slices, replacing auth claims at any key (including nested helper data) with identity and permission methods, UID, UserRole, and copied resource roles. Custom permission checks retain their original behavior. Request locals, standard-context claims, actor data, and token validation remain unchanged. Raw JWT metadata and extension methods are excluded from views; bind any extra presentation fields explicitly as safe data. Other models and helpers still pass through the renderer's normal safety checks. Configure engine-specific extensions before wrapping the engine.

See middleware/csrf/README.md for more examples and configuration options (custom token lookup, skipping routes, etc.).

AJAX/SPA bootstrap endpoint

For clients that need to refresh tokens via XHR (e.g., SPAs), register the helper route:

import csrf "github.com/goliatone/go-auth/middleware/csrf"

csrf.RegisterRoutes(app.Router())

The handler returns JSON:

{
  "token": "...",
  "field_name": "_token",
  "header_name": "X-CSRF-Token"
}

Responses include Cache-Control: no-store, so clients fetch fresh tokens as needed. Call this endpoint whenever a token expires or before issuing state-changing requests in a long-lived SPA session.

Lifecycle Extensions

User Status & State Machine

go-auth persists lifecycle metadata through two columns on users: status (pending, active, suspended, disabled, archived) and suspended_at (timestamp set whenever a user enters or exits the suspended state). The default UserStateMachine enforces the transition graph (archived is terminal, pending can only move to active or disabled, etc.), keeps timestamps in sync, and publishes ActivitySink events.

Use the shared Users repository helpers (UpdateStatus, Suspend, Reinstate) or work directly with the state machine when you need options such as WithTransitionReason, WithTransitionMetadata, or custom hooks:

auditSink := auth.ActivitySinkFunc(func(ctx context.Context, event auth.ActivityEvent) error {
    log.Printf(
        "user %s transitioned %s -> %s (reason=%v)",
        event.UserID,
        event.FromStatus,
        event.ToStatus,
        event.Metadata["reason"],
    )
    return nil
})

stateMachine := auth.NewUserStateMachine(
    repoManager.Users(),
    auth.WithStateMachineActivitySink(auditSink),
)

actor := auth.ActorRef{ID: "admin-42", Type: "admin"}
updated, err := stateMachine.Transition(
    ctx,
    actor,
    user,
    auth.UserStatusSuspended,
    auth.WithTransitionReason("manual review"),
    auth.WithTransitionMetadata(map[string]any{"ticket": "SEC-204"}),
)
if err != nil {
    panic(err)
}

fmt.Println("new status:", updated.Status, "suspended at:", updated.SuspendedAt)

See examples/extensions/extensions.go for an end-to-end sample that persists activity rows and decorates claims based on tenant context.

Transition hooks bubble failures through a configurable handler. By default go-auth panics with a detailed message (great for development). In production override this behavior with auth.WithStateMachineHookErrorHandler to convert hook failures into domain errors or alerts:

handler := func(ctx context.Context, phase auth.TransitionHookPhase, err error, tc auth.TransitionContext) error {
    log.Printf("hook stage=%s user=%s error=%v", phase, tc.User.ID, err)
    return fmt.Errorf("policy hook failed: %w", err)
}

stateMachine := auth.NewUserStateMachine(
    repoManager.Users(),
    auth.WithStateMachineHookErrorHandler(handler),
)
ActivitySink Wiring

ActivitySink is a small interface used across lifecycle transitions, login/impersonation flows, and password reset handlers:

  • ActivityEvent.EventType distinguishes lifecycle (user.status.changed), login, impersonation, and password reset actions.
  • ActorRef identifies who triggered the change (admin dashboard, API, system job).
  • Metadata is an open map for reasons, ticket numbers, IP addresses, etc.
  • Failures are logged; auth flows continue unless you wrap the sink with your own retry/alerting logic.

Configure sinks wherever lifecycle events occur:

auditSink := auth.ActivitySinkFunc(func(ctx context.Context, event auth.ActivityEvent) error {
    log.Printf("activity event=%s user=%s actor=%s", event.EventType, event.UserID, event.Actor.Type)
    return nil
})

stateMachine := auth.NewUserStateMachine(users,
    auth.WithStateMachineActivitySink(auditSink),
)

auther := auth.NewAuthenticator(provider, cfg).
    WithActivitySink(auditSink)
Activity Mapping Helpers

Use activitymap.Normalize when you need to forward auth.ActivityEvent into another activity record contract without re implementing translation logic:

import (
    "context"
    "time"

    auth "github.com/goliatone/go-auth"
    "github.com/goliatone/go-auth/activitymap"
)

type ExternalRecord struct {
    ActorID    string
    Verb       string
    ObjectType string
    ObjectID   string
    Channel    string
    Metadata   map[string]any
    OccurredAt time.Time
}

sink := auth.ActivitySinkFunc(func(ctx context.Context, event auth.ActivityEvent) error {
    normalized := activitymap.Normalize(
        event,
        activitymap.WithDefaultChannel("auth"),
        activitymap.WithDefaultObjectType("user"),
        activitymap.WithObjectIDResolver(func(e auth.ActivityEvent) string {
            if v, ok := e.Metadata["password_reset_id"].(string); ok {
                return v
            }
            return e.UserID
        }),
    )

    record := ExternalRecord{
        ActorID:    normalized.ActorID,
        Verb:       normalized.Verb,
        ObjectType: normalized.ObjectType,
        ObjectID:   normalized.ObjectID,
        Channel:    normalized.Channel,
        Metadata:   normalized.Metadata,
        OccurredAt: normalized.OccurredAt,
    }
    _ = record
    return nil
})

Defaults:

  • channel: auth
  • object_type: user
  • object_id: event.UserID
  • actor_id: event.Actor.ID -> event.UserID -> "system"

For ordinary events, normalized metadata is shallow-cloned from event.Metadata and enriched with:

  • actor_type (from event.Actor.Type, when available)
  • from_status / to_status for lifecycle transitions

Provider lifecycle/session events use restricted projections and identity fingerprints. Ordinary metadata can still contain submitted identifiers and provider errors; apply host disclosure/retention policy before persistence. See activity mapping for adapter guidance.

The same sink can forward events to a SQL table, queue, or logging pipeline. Refer to examples/extensions/extensions.go for a Postgres-based implementation and batching hints.

ClaimsDecorator Hook

Use Auther.WithClaimsDecorator to enrich JWTs with tenant metadata or derived resource roles before they are signed. Decorators receive the pending JWTClaims and may only mutate extension fields such as Resources, Metadata, or additional custom payload that your product documents. Core JWT claims (sub, uid, iss, aud, iat, exp) are guarded and any attempt to edit them aborts token generation.

decorator := auth.ClaimsDecoratorFunc(func(ctx context.Context, identity auth.Identity, claims *auth.JWTClaims) error {
	if claims.Metadata == nil {
		claims.Metadata = map[string]any{}
	}
	claims.Metadata["tenant_id"] = lookupTenant(identity.ID())
	if claims.Resources == nil {
		claims.Resources = map[string]string{}
	}
	claims.Resources["team:"+identity.ID()] = "editor"
	return nil
})

auther := auth.NewAuthenticator(provider, cfg).
	WithClaimsDecorator(decorator)

If the decorator returns an error the token flow stops, the failure is logged, and no JWT is issued. Coordinate decorations with your ActivitySink so downstream services can reconcile claims with lifecycle transitions. Additional wiring tips and a multi-tenant example live in examples/extensions/extensions.go.

JWT Size Safety Defaults

go-auth minimizes oversized JWT metadata by default to reduce cookie bloat and HTTP 431 Request Header Fields Too Large failures.

  • Default claim minimization removes metadata keys (case-insensitive, - normalized to _):
    • permissions, permission_list, permissions_list
    • scopes, scope_list, scopes_list
  • Top-level structured claims are preserved:
    • role, res, and top-level scopes

Token size guardrails apply to all signed JWTs:

  • Warning threshold: 2048 bytes (default)
  • Hard limit: 4096 bytes (default, returns ErrTokenTooLarge)

You can override thresholds without changing interfaces:

auther := auth.NewAuthenticator(provider, cfg).
    WithTokenSizeGuardrails(3072, 6144)

Equivalent token-service options:

tokenService := auth.NewTokenService(
    signingKey,
    tokenExpiration,
    issuer,
    audience,
    logger,
    auth.WithTokenSizeGuardrails(2048, 4096),
)

Migration note: applications that previously read permissions/scopes from JWT metadata should move permission expansion to resolver-based checks (CachedPermissionsResolver + request-scoped cache) and keep JWT payloads minimal.

API Reference

TokenService Access

The Authenticator provides access to its underlying TokenService for advanced use cases:

// Access the token service directly
tokenService := authenticator.TokenService()

// Generate tokens manually with custom resource roles
resourceRoles := map[string]string{
    "project:123": "admin",
    "files:uploads": "owner",
}
token, err := tokenService.Generate(identity, resourceRoles)

// Validate tokens manually
claims, err := tokenService.Validate(tokenString)
Scoped Token Minting

Use MintScopedToken to issue short lived tokens with optional scopes and TTL overrides (useful for debug or session scoped access). The helper reuses defaults from the built-in token service when available, and returns the computed expiration alongside the token.

tokenService := authenticator.TokenService()

opts := auth.ScopedTokenOptions{
    TTL:    15 * time.Minute,            // overrides default expiration
    Scopes: []string{"debug.view"},       // stored in the "scopes" claim
}

token, expiresAt, err := auth.MintScopedToken(tokenService, identity, nil, opts)

MintScopedToken keeps top-level JWTClaims.Scopes intact. Only metadata scope arrays are minimized by default on token signing.

Permission Resolver Cache

Use CachedPermissionsResolver to cache expensive permission resolution across requests. The resolver keeps request fanout under control with singleflight and stores permission sets through a pluggable PermissionCacheStore.

baseResolver := func(ctx context.Context) ([]string, error) {
    // load effective permissions (db, role registry, policy engine, etc.)
    return []string{"admin.translations.export"}, nil
}

resolver := auth.NewCachedPermissionsResolver(auth.CachedPermissionsResolverConfig{
    Resolver: baseResolver,
    KeyFunc:  auth.DefaultPermissionsCacheKeyFromContext,
    TTL:      2 * time.Minute,
    // Store omitted -> defaults to in-memory implementation
    // CacheErrorMode omitted -> defaults to fail_open
})

resolvePermissions := resolver.ResolverFunc()

Request-scope dedupe helper:

ctx := auth.WithResolvedPermissionsCache(req.Context())
permissions, err := resolvePermissions(ctx) // repeated calls in this request resolve once

Strict-mode resolver validation:

if err := auth.ValidateResolverConfigured(true, resolvePermissions); err != nil {
    return err
}
// or panic-fast for startup wiring:
auth.MustValidateResolverConfigured(true, resolvePermissions)

PermissionCacheStore contract:

type PermissionCacheStore interface {
    Get(ctx context.Context, key string) (permissions []string, ok bool, err error)
    Set(ctx context.Context, key string, permissions []string, ttl time.Duration) error
    Delete(ctx context.Context, key string) error
}

Optional purge capability:

type PurgeablePermissionCacheStore interface {
    PurgeExpired(ctx context.Context) (purged int, err error)
}

If you use a generic cache package (for example go-cache), create a thin adapter that satisfies PermissionCacheStore:

type PermissionStoreAdapter struct {
    cache cache.Cache[string, []string]
}

func (s *PermissionStoreAdapter) Get(ctx context.Context, key string) ([]string, bool, error) {
    return s.cache.Get(ctx, key)
}

func (s *PermissionStoreAdapter) Set(ctx context.Context, key string, permissions []string, ttl time.Duration) error {
    return s.cache.Set(ctx, key, permissions, ttl)
}

func (s *PermissionStoreAdapter) Delete(ctx context.Context, key string) error {
    return s.cache.Delete(ctx, key)
}

Then wire it into the resolver:

resolver := auth.NewCachedPermissionsResolver(auth.CachedPermissionsResolverConfig{
    Resolver:       baseResolver,
    KeyFunc:        auth.DefaultPermissionsCacheKeyFromContext,
    Store:          &PermissionStoreAdapter{cache: sharedCache},
    TTL:            2 * time.Minute,
    CacheErrorMode: auth.PermissionCacheErrorModeFailOpen, // or FailClosed
})

Manual cache operations:

_ = resolver.Invalidate(ctx, cacheKey)
purged, err := resolver.PurgeExpired(ctx) // returns 0,nil if store is not purgeable
_ = purged
_ = err

Notes:

  • DefaultPermissionsCacheKeyFromContext includes permission affecting discriminators (version, token id, scopes, impersonation, session). If no discriminator is available, cross request caching is bypassed.
  • PermissionCacheErrorModeFailOpen (default) keeps authz available when cache operations fail.
  • PermissionCacheErrorModeFailClosed propagates cache errors immediately.
  • Runtime counters are available through resolver.Stats().
  • SetPermissionsVersionMetadata / PermissionsVersionFromContext keep cache keys stable across permission-set updates.
JWT Middleware Integration

Use the TokenService with JWT middleware for custom authentication flows:

// Create TokenServiceAdapter for jwtware middleware
tokenValidator := auth.NewTokenServiceAdapter(authenticator.TokenService())

// Configure JWT middleware
jwtConfig := jwtware.Config{
    SigningKey: jwtware.SigningKey{
        Key:    []byte(config.GetSigningKey()),
        JWTAlg: config.GetSigningMethod(),
    },
    TokenValidator: tokenValidator,
    ContextKey:     "auth",
}

middleware := jwtware.New(jwtConfig)

Core Concepts

User Roles

The library defines a hierarchical role system:

  • guest - Read-only access
  • member - Read and edit access
  • admin - Read, edit, and create access
  • owner - Full access including delete
Resource-Level Permissions

Beyond global user roles, the library supports resource-specific permissions:

// Example resource roles map
resourceRoles := map[string]string{
    "project:123":     "admin",      // Admin of project 123
    "admin:dashboard": "member",     // Member access to admin dashboard
    "files:uploads":   "owner",      // Owner of file uploads
}
JWT Claims Structure

The library generates structured JWT claims:

{
  "sub": "user-id",
  "uid": "user-id",
  "role": "admin",
  "res": {
    "project:123": "admin",
    "admin:dashboard": "member"
  },
  "scopes": ["debug.view", "debug.repl"],
  "iss": "your-app",
  "aud": ["your-audience"],
  "iat": 1234567890,
  "exp": 1234654290,
  "jti": "token-id"
}

Database Schema

The library requires two database tables. Note: migrations use TEXT IDs in Postgres/SQLite, while Go models cast to uuid.UUID. This is intentional for now; IDs are stored as text and parsed/validated in the app. We may move to native UUID columns in a future migration.

Users Table
CREATE TABLE users (
    id TEXT NOT NULL PRIMARY KEY,
    user_role TEXT NOT NULL DEFAULT 'guest' CHECK (
        user_role IN ('guest', 'member', 'admin', 'owner')
    ),
    first_name TEXT NOT NULL,
    last_name TEXT NOT NULL,
    username TEXT NOT NULL,
    profile_picture TEXT,
    email TEXT NOT NULL UNIQUE,
    phone_number TEXT,
    password_hash TEXT,
    metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
    is_email_verified BOOLEAN DEFAULT FALSE,
    login_attempts INTEGER DEFAULT 0,
    login_attempt_at TIMESTAMP,
    loggedin_at TIMESTAMP,
    status TEXT NOT NULL DEFAULT 'active' CHECK (
        status IN ('pending', 'active', 'suspended', 'disabled', 'archived')
    ),
    suspended_at TIMESTAMP,
    external_id TEXT,
    external_id_provider TEXT,
    reseted_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP,
    deleted_at TIMESTAMP
);
Password Reset Table
CREATE TABLE password_reset (
    id TEXT NOT NULL PRIMARY KEY,
    user_id TEXT NOT NULL REFERENCES users(id),
    email TEXT NOT NULL,
    status TEXT NOT NULL DEFAULT 'unknown' CHECK (
        status IN ('unknown', 'requested', 'expired', 'changed')
    ),
    reseted_at TIMESTAMP,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP,
    deleted_at TIMESTAMP
);
Social Accounts Table

Social login adds a social_accounts table for linked provider identities. Migrations ship in data/sql/migrations and data/sql/migrations/sqlite. Use auth.GetAuthExtrasMigrationsFS() for segmented registration (or auth.GetMigrationsFS() for the full tree).

CREATE TABLE social_accounts (
    id TEXT NOT NULL PRIMARY KEY,
    user_id TEXT NOT NULL,
    provider TEXT NOT NULL,
    provider_user_id TEXT NOT NULL,
    email TEXT,
    name TEXT,
    username TEXT,
    avatar_url TEXT,
    access_token TEXT,
    refresh_token TEXT,
    token_expires_at TIMESTAMP NULL,
    profile_data JSONB NOT NULL DEFAULT '{}'::jsonb,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
    CONSTRAINT uq_social_accounts_provider_id UNIQUE (provider, provider_user_id),
    CONSTRAINT uq_social_accounts_user_provider UNIQUE (user_id, provider)
);

CREATE INDEX idx_social_accounts_user_id ON social_accounts(user_id);
CREATE INDEX idx_social_accounts_provider ON social_accounts(provider, provider_user_id);
Auth0 Identifiers Table (Optional Sync Track)

SSO and Auth0 sync use the provider-neutral user_identifiers mapping table. The canonical lookup key is (provider, identifier), where identifier is the provider subject. Optional external ID columns on users are legacy enrichment, not the primary SSO lookup path. Migrations ship in data/sql/migrations and data/sql/migrations/sqlite:

  • 20240701090000_auth0_identifiers.up.sql
  • 20240701090000_auth0_identifiers.down.sql

See docs/AUTH0.md for schema details and sync wiring.

Migration Registration Profiles

go-auth exposes segmented migration filesystems:

  • auth.GetCoreMigrationsFS() for core auth schema (users, password_reset, user_status).
  • auth.GetAuthExtrasMigrationsFS() for optional extras (social_accounts, user_identifiers, users.external_id*, OIDC state, provider sessions/tokens/fences, and lifecycle operations).
  • auth.GetMigrationsFS() for the full migration tree.

Register core first, then extras when both are used. Segmented assets are now directory-packaged under data/sql/migration_tracks/{core,auth_extras} to avoid filename-pattern embeds.

Configuration

The library uses a configuration interface that you can implement:

type Config interface {
    GetSigningKey() string
    GetTokenExpiration() int
    GetExtendedTokenDuration() int
    GetIssuer() string
    GetAudience() []string
    GetContextKey() string
    GetTokenLookup() string
    GetAuthScheme() string
    GetRejectedRouteKey() string
    GetRejectedRouteDefault() string
}

Authentication Flow

User Registration
  1. User submits registration form
  2. Password is hashed using bcrypt
  3. User record is created in database
  4. Optional email verification can be triggered
Login Process
  1. User provides credentials
  2. Identity provider verifies password
  3. Resource role provider fetches permissions (if configured)
  4. JWT token is generated with structured claims
  5. Token is returned to client
Password Reset
  1. User requests password reset via email
  2. Reset token is generated and stored
  3. Email with reset link is sent
  4. User follows link to reset password
  5. New password is hashed and updated

Middleware

HTTP Middleware

The library provides HTTP middleware for route protection:

// Protect routes requiring authentication
httpAuth, err := auth.NewHTTPAuthenticator(authenticator, config)
if err != nil {
    log.Fatal(err)
}
protectedRoute := httpAuth.ProtectedRoute(config, errorHandler)
router.Use("/api/", protectedRoute)

// Custom authorization logic
func requireAdminRole(c router.Context) error {
    session, err := auth.GetRouterSession(c, config.GetContextKey())
    if err != nil {
        return c.Status(401).SendString("Unauthorized")
    }
    if !session.IsAtLeast(auth.RoleAdmin) {
        return c.Status(403).SendString("Forbidden")
    }
    return c.Next()
}
WebSocket Authentication

auth.NewWSTokenValidator adapts a TokenValidator to go-router's WSTokenValidator. Auther.NewWSAuthMiddleware returns the high-level router.WebSocketMiddleware shape (WSHandler to WSHandler). Register the wrapped handler through router.NewWSHandler; there is no router.WS method or *router.WSContext type.

func registerChat[T any](routes router.Router[T], authenticator *auth.Auther) {
    protected := authenticator.NewWSAuthMiddleware()
    routes.Get("/chat", router.NewWSHandler(protected(
        func(ctx context.Context, client router.WSClient) error {
            claims, ok := auth.WSAuthClaimsFromContext(ctx)
            if !ok || !claims.CanRead("chat:messages") {
                return client.Close(1008, "Unauthorized")
            }
            return client.SendJSON(map[string]string{"user_id": claims.UserID()})
        },
    )))
}

For custom extraction/failure handling, pass router.WSAuthConfig:

wsConfig := router.WSAuthConfig{
    TokenExtractor: func(ctx context.Context, client router.WSClient) (string, error) {
        token := client.Conn().Header("X-Auth-Token")
        if token == "" { return "", errors.New("missing auth token") }
        return token, nil
    },
    OnAuthFailure: func(ctx context.Context, client router.WSClient, err error) error {
        return client.Close(1008, "Authentication failed")
    },
}
protected := authenticator.NewWSAuthMiddleware(wsConfig)

Default extraction checks token query parameters, then the Authorization header; cookie extraction requires EnableTokenCookie. Hosts choose the transport and avoid exposing token-bearing URLs in logs. Authentication here runs in the high-level connection handler. Use package-managed HTTP/pre-upgrade admission when a rejection must carry an HTTP status before the upgrade.

For a custom validator, return claims through auth.NewWSTokenValidator(customTokenValidator) rather than constructing WSAuthClaimsAdapter directly: its wrapped claims are private. Use the low-level router.WebSocketContext API only when the application owns the read/write loop. See websocket_adapter.go and go-router's WebSocket guides.

Command Handlers

The library includes command handlers for common operations. resetDelivery below is a host-provided auth.PasswordResetDelivery that sends the opaque credential through a trusted channel; reset credentials are not returned in command responses. Configure feature gates through WithFeatureGate when used.

// Register user
registerUser := auth.NewRegisterUserHandler(repositoryManager)
err := registerUser.Execute(ctx, auth.RegisterUserMessage{
    FirstName: "John",
    LastName:  "Doe",
    Email:     "john@example.com",
    Password:  "securepassword",
})

// Initialize password reset
initReset := auth.NewInitializePasswordResetHandler(repositoryManager).WithDelivery(resetDelivery)
err := initReset.Execute(ctx, auth.InitializePasswordResetMessage{
    Email: "user@example.com",
    Stage: "show-reset",
})

Development

See docs/GUIDE_DEVELOPMENT_CICD.md for the multi-module formatting, test, lint, security, CI, and release-validation workflow.

Example application

Run the complete local browser example from its module:

cd examples
./taskfile dev:run

The task regenerates Go configuration, installs the pinned frontend build dependencies when needed, rebuilds public/css/main.css from every template under views/, builds the Go binary, and starts it on http://127.0.0.1:8572.

Documentation

Overview

Package auth provides authentication primitives (JWT issuance, stateful repositories, HTTP helpers) plus lifecycle extension points for downstream admin workflows.

User lifecycle:

  • Users carry a UserStatus field that is persisted via Bun. Statuses cover pending, active, suspended, disabled, and archived flows so every product can opt into the same invariants.
  • UserStateMachine centralizes the transition graph, timestamp handling, hooks, and persistence. Embed the shared Users repository and invoke Transition with ActorRef metadata whenever an admin moves an account. Hook failures route through a configurable error handler so production services can translate panics into domain errors.

Activity sinks:

  • ActivitySink is a light-weight audit emitter used by Auther and the state machine to describe lifecycle, login, impersonation, and password reset events. Sinks run best-effort (errors are logged) so you can forward to a database or queue without blocking authentication.

Claims decoration:

  • ClaimsDecorator is invoked before JWTs are signed. Decorators may enrich extension fields such as resource roles or metadata while protected claims (sub, iss, aud, exp, etc.) remain immutable. Combine WithClaimsDecorator with ActivitySink to keep lifecycle state and issued tokens consistent.

Index

Constants

View Source
const (
	TextCodeIdentityProviderRequired    = "IDENTITY_PROVIDER_REQUIRED"
	TextCodeInvalidCreds                = "INVALID_CREDENTIALS" // #nosec G101 -- Error text code, not a credential.
	TextCodeTooManyAttempts             = "TOO_MANY_ATTEMPTS"
	TextCodeSessionNotFound             = "SESSION_NOT_FOUND"
	TextCodeSessionDecodeError          = "SESSION_DECODE_ERROR"
	TextCodeClaimsMappingError          = "CLAIMS_MAPPING_ERROR"
	TextCodeDataParseError              = "DATA_PARSE_ERROR"
	TextCodeEmptyPassword               = "EMPTY_PASSWORD_NOT_ALLOWED"
	TextCodeTokenExpired                = "TOKEN_EXPIRED"
	TextCodeTokenMalformed              = "TOKEN_MALFORMED" // #nosec G101 -- Error text code, not a credential.
	TextCodeTokenTooLarge               = "TOKEN_TOO_LARGE"
	TextCodeImmutableClaim              = "IMMUTABLE_CLAIM_MUTATION"
	TextCodeAccountSuspended            = "ACCOUNT_SUSPENDED"
	TextCodeAccountDisabled             = "ACCOUNT_DISABLED"
	TextCodeAccountArchived             = "ACCOUNT_ARCHIVED"
	TextCodeAccountPending              = "ACCOUNT_PENDING"
	TextCodeSignupDisabled              = "SIGNUP_DISABLED"
	TextCodePasswordResetDisabled       = "PASSWORD_RESET_DISABLED"
	TextCodePermissionResolverRequired  = "PERMISSION_RESOLVER_REQUIRED"
	TextCodeTemporaryPasswordExpired    = "TEMPORARY_PASSWORD_EXPIRED"
	TextCodeIdentifierConflict          = "IDENTIFIER_CONFLICT"
	TextCodeAssuranceMissing            = "ASSURANCE_MISSING"
	TextCodeAssuranceUnknown            = "ASSURANCE_UNKNOWN"
	TextCodeAssuranceInsufficient       = "ASSURANCE_INSUFFICIENT"
	TextCodeAssuranceStale              = "ASSURANCE_STALE"
	TextCodeAssuranceStepUpRequired     = "ASSURANCE_STEP_UP_REQUIRED"
	TextCodeAccountStateUnknown         = "ACCOUNT_STATE_UNKNOWN"
	TextCodeAccountStateConflict        = "ACCOUNT_STATE_CONFLICT"
	TextCodeAccountStateUnavailable     = "ACCOUNT_STATE_UNAVAILABLE"
	TextCodePermissionVersionMismatch   = "PERMISSION_VERSION_MISMATCH"
	TextCodePermissionVersionMissing    = "PERMISSION_VERSION_MISSING"
	TextCodeAuthorizationRoleMissing    = "AUTHORIZATION_ROLE_MISSING"
	TextCodeFreshnessPolicyInvalid      = "FRESHNESS_POLICY_INVALID"
	TextCodeAuthorizationFreshnessDeny  = "AUTHORIZATION_FRESHNESS_DENIED"
	TextCodeFreshnessInvalidationFailed = "FRESHNESS_INVALIDATION_FAILED"
	TextCodeEmergencyAccessDenied       = "EMERGENCY_ACCESS_DENIED"
	TextCodeEmergencyAccessUnavailable  = "EMERGENCY_ACCESS_UNAVAILABLE"
)
View Source
const (
	MaxNormalAccountStateCache    = 15 * time.Minute
	MaxPrivilegedStateCache       = time.Minute
	MaxAssuranceAuthenticationAge = 24 * time.Hour
	MaxAuthorizationPropagation   = time.Hour
)
View Source
const (
	// ResetUnknownStatus is the unknown status
	ResetUnknownStatus = "unknown"
	// ResetRequestedStatus is the requested status
	ResetRequestedStatus = "requested"
	// ResetExpiredStatus is the expired status
	ResetExpiredStatus = "expired"
	// ResetChangedStatus is the changed status
	ResetChangedStatus = "changed"
)
View Source
const (
	DefaultPermissionResolutionTimeout = 5 * time.Second
	MaxPermissionResolutionTimeout     = 30 * time.Second
)
View Source
const (
	TokenEnvelopeVersion1  = uint8(1)
	TokenEnvelopeAES256GCM = "AES-256-GCM" // #nosec G101 -- Algorithm identifier, not a credential.
)
View Source
const (
	DefaultProviderSessionCookieName = "__Host-go_auth_ps"
	DefaultProviderSessionTouch      = 5 * time.Minute
	DefaultProviderRefreshLease      = 30 * time.Second
	DefaultProviderSessionRetention  = 30 * 24 * time.Hour
	DefaultProviderTokenRetention    = 24 * time.Hour
	MaxProviderTokenPayloadBytes     = 64 * 1024
	MaxProviderTokenKeyIDBytes       = 128
)
View Source
const (
	DefaultPrincipalMetadataEntries = 32
	DefaultPrincipalMetadataBytes   = 16 * 1024
)
View Source
const (
	TemporaryPasswordMetadataKey          = "password_temporary"
	PasswordChangeRequiredMetadataKey     = "password_change_required"
	TemporaryPasswordIssuedAtMetadataKey  = "password_temporary_issued_at"
	TemporaryPasswordExpiresAtMetadataKey = "password_temporary_expires_at"
)
View Source
const (
	// DefaultTokenWarnThresholdBytes emits a warning log when a signed JWT reaches
	// this size. It remains valid unless the hard limit is exceeded.
	DefaultTokenWarnThresholdBytes = 2048
	// DefaultTokenHardLimitBytes rejects tokens larger than this size to reduce
	// oversized cookie risk in downstream applications.
	DefaultTokenHardLimitBytes = 4096
)
View Source
const (
	// TokenTypeSession labels regular auth/session JWTs.
	TokenTypeSession = "session"
	// TokenTypeScoped labels short-lived scoped JWTs minted by MintScopedToken.
	TokenTypeScoped = "scoped"
	// TokenTypeCustom labels direct TokenService.SignClaims calls.
	TokenTypeCustom = "custom"
)
View Source
const (
	DefaultMaxLoginAttempts   = 5
	DefaultLoginAttemptWindow = 24 * time.Hour
)
View Source
const MaxEmergencyAccessDuration = time.Hour
View Source
const MinimumHMACSigningKeyBytes = 32
View Source
const (
	// PermissionsVersionMetadataKey is the preferred claim metadata key used to
	// carry permission-set version/etag values across requests.
	PermissionsVersionMetadataKey = "permissions_version"
)

Variables

View Source
var (
	ErrProviderOperationInvalid      = errors.New("auth: invalid provider operation")
	ErrProviderOperationUnauthorized = errors.New("auth: provider operation is not authorized")
	ErrProviderOperationUnsupported  = errors.New("auth: provider operation is unsupported")
	ErrProviderOperationConflict     = errors.New("auth: provider operation conflicts with current state")
	ErrProviderOperationPending      = errors.New("auth: provider operation outcome is pending")
)
View Source
var (
	ErrLifecycleOperationUnavailable = errors.New("auth: lifecycle operation store unavailable")
	ErrLifecycleOperationConflict    = errors.New("auth: lifecycle operation revision conflict")
)
View Source
var (
	ErrProviderSessionInvalid         = errors.New("auth: invalid provider session")
	ErrProviderSessionNotFound        = errors.New("auth: provider session not found")
	ErrProviderSessionExpired         = errors.New("auth: provider session expired")
	ErrProviderSessionRevoked         = errors.New("auth: provider session revoked")
	ErrProviderSessionUncertain       = errors.New("auth: provider session refresh outcome is uncertain")
	ErrProviderSessionConflict        = errors.New("auth: provider session revision conflict")
	ErrProviderSessionBinding         = errors.New("auth: provider session binding mismatch")
	ErrProviderSessionUnavailable     = errors.New("auth: provider session unavailable")
	ErrProviderSessionCredential      = errors.New("auth: conflicting authentication credentials")
	ErrProviderRefreshInProgress      = errors.New("auth: provider session refresh in progress")
	ErrProviderRefreshRejected        = errors.New("auth: provider refresh rejected")
	ErrProviderRefreshAmbiguous       = errors.New("auth: provider refresh outcome ambiguous")
	ErrProviderTokenCipher            = errors.New("auth: provider token cipher failure")
	ErrProviderTokenKeyNotFound       = errors.New("auth: provider token key not found")
	ErrProviderTokenKeyRetired        = errors.New("auth: provider token key is retired")
	ErrProviderTokenEnvelope          = errors.New("auth: invalid provider token envelope")
	ErrProviderTokenTarget            = errors.New("auth: invalid provider token target")
	ErrProviderTokenPolicy            = errors.New("auth: provider token access denied")
	ErrProviderTokenPolicyUnavailable = errors.New("auth: provider token access policy unavailable")
)
View Source
var (
	ErrSecretSerialization = errors.New("auth: secret serialization is disabled")
	ErrInvalidTokenSet     = errors.New("auth: invalid provider token set")
	ErrInvalidPrincipal    = errors.New("auth: invalid authenticated principal")
)
View Source
var (
	MaxLoginAttempts = DefaultMaxLoginAttempts
	CoolDownPeriod   = "24h"
)

MaxLoginAttempts and CoolDownPeriod remain variables for source compatibility. NewUserProvider uses immutable defaults; configure an instance with WithLoginAttemptPolicy instead.

View Source
var ErrAccountStateConflict = errors.New("account state sources conflict", errors.CategoryAuthz).
	WithTextCode(TextCodeAccountStateConflict).
	WithCode(errors.CodeForbidden)
View Source
var ErrAccountStateUnavailable = errors.New("account state is unavailable", errors.CategoryExternal).
	WithTextCode(TextCodeAccountStateUnavailable).
	WithCode(errors.CodeInternal)
View Source
var ErrAccountStateUnknown = errors.New("account state is unknown", errors.CategoryAuthz).
	WithTextCode(TextCodeAccountStateUnknown).
	WithCode(errors.CodeForbidden)
View Source
var ErrAssuranceInsufficient = errors.New("authentication assurance is insufficient", errors.CategoryAuthz).
	WithTextCode(TextCodeAssuranceInsufficient).
	WithCode(errors.CodeForbidden)
View Source
var ErrAssuranceMissing = errors.New("authentication assurance is missing", errors.CategoryAuth).
	WithTextCode(TextCodeAssuranceMissing).
	WithCode(errors.CodeUnauthorized)
View Source
var ErrAssuranceStale = errors.New("authentication assurance is stale", errors.CategoryAuthz).
	WithTextCode(TextCodeAssuranceStale).
	WithCode(errors.CodeForbidden)
View Source
var ErrAssuranceStepUpRequired = errors.New("authentication step-up is required", errors.CategoryAuth).
	WithTextCode(TextCodeAssuranceStepUpRequired).
	WithCode(errors.CodeUnauthorized)
View Source
var ErrAssuranceUnknown = errors.New("authentication assurance is unknown", errors.CategoryAuthz).
	WithTextCode(TextCodeAssuranceUnknown).
	WithCode(errors.CodeForbidden)
View Source
var ErrAuthorizationFreshnessDenied = errors.New("authorization freshness requirement was denied", errors.CategoryAuthz).
	WithTextCode(TextCodeAuthorizationFreshnessDeny).
	WithCode(errors.CodeForbidden)
View Source
var ErrAuthorizationRoleMissing = errors.New("authorization role is unavailable", errors.CategoryExternal).
	WithTextCode(TextCodeAuthorizationRoleMissing).
	WithCode(errors.CodeInternal)
View Source
var ErrEmergencyAccessDenied = errors.New("emergency access denied", errors.CategoryAuthz).
	WithTextCode(TextCodeEmergencyAccessDenied).
	WithCode(errors.CodeForbidden)
View Source
var ErrEmergencyAccessUnavailable = errors.New("emergency access validation unavailable", errors.CategoryExternal).
	WithTextCode(TextCodeEmergencyAccessUnavailable).
	WithCode(errors.CodeInternal)
View Source
var ErrFreshnessInvalidationFailed = errors.New("freshness invalidation failed", errors.CategoryInternal).
	WithTextCode(TextCodeFreshnessInvalidationFailed).
	WithCode(errors.CodeInternal)
View Source
var ErrFreshnessPolicyInvalid = errors.New("authorization freshness policy is invalid", errors.CategoryValidation).
	WithTextCode(TextCodeFreshnessPolicyInvalid).
	WithCode(errors.CodeBadRequest)
View Source
var ErrIdentifierConflict = errors.New("external identifier is already bound", errors.CategoryConflict).
	WithTextCode(TextCodeIdentifierConflict).
	WithCode(errors.CodeConflict)

ErrIdentifierConflict is returned when an immutable external identifier is already bound to another local user.

View Source
var ErrIdentityNotFound = errors.New("identity not found", errors.CategoryNotFound).
	WithCode(errors.CodeNotFound)

ErrIdentityNotFound is returned when an identity cannot be found.

View Source
var ErrIdentityProviderRequired = errors.New("identity provider is required", errors.CategoryInternal).
	WithCode(errors.CodeInternal).
	WithTextCode(TextCodeIdentityProviderRequired)

ErrIdentityProviderRequired indicates missing authenticator configuration. NewAuthenticator remains compatible with token-validation-only callers; credential operations require a non-nil IdentityProvider.

View Source
var ErrImmutableClaimMutation = errors.New("claims decorator attempted to mutate immutable claim", errors.CategoryValidation).
	WithTextCode(TextCodeImmutableClaim).
	WithCode(errors.CodeBadRequest)

ErrImmutableClaimMutation is returned when a decorator tampers with protected claims.

View Source
var ErrInvalidTransition = goerrors.New("invalid user state transition", goerrors.CategoryValidation).
	WithTextCode(textCodeInvalidTransition).
	WithCode(goerrors.CodeBadRequest)

ErrInvalidTransition is returned when a requested status change is not allowed.

View Source
var ErrMismatchedHashAndPassword = errors.New("the credentials provided are invalid", errors.CategoryAuth).
	WithTextCode(TextCodeInvalidCreds).
	WithCode(errors.CodeUnauthorized)

ErrMismatchedHashAndPassword is returned on a failure to check a password hash. The message is generic to avoid leaking information.

View Source
var ErrNoEmptyString = errors.New("password can't be an empty string", errors.CategoryValidation).
	WithTextCode(TextCodeEmptyPassword).
	WithCode(errors.CodeBadRequest)

ErrNoEmptyString is returned when an empty string is provided for a value that must not be empty, like a password.

View Source
var ErrPasswordResetDisabled = errors.New("password reset is currently disabled", errors.CategoryAuthz).
	WithTextCode(TextCodePasswordResetDisabled).
	WithCode(errors.CodeForbidden)

ErrPasswordResetDisabled is returned when password reset flows are disabled.

View Source
var ErrPermissionResolverRequired = errors.New("permission resolver is required in strict mode", errors.CategoryValidation).
	WithTextCode(TextCodePermissionResolverRequired).
	WithCode(errors.CodeBadRequest)

ErrPermissionResolverRequired is returned when strict resolver mode is enabled without a resolver.

View Source
var ErrPermissionVersionMismatch = errors.New("permission version is stale", errors.CategoryAuthz).
	WithTextCode(TextCodePermissionVersionMismatch).
	WithCode(errors.CodeForbidden)
View Source
var ErrPermissionVersionMissing = errors.New("permission version is unavailable", errors.CategoryExternal).
	WithTextCode(TextCodePermissionVersionMissing).
	WithCode(errors.CodeInternal)
View Source
var ErrSignupDisabled = errors.New("signups are currently disabled", errors.CategoryAuthz).
	WithTextCode(TextCodeSignupDisabled).
	WithCode(errors.CodeForbidden)

ErrSignupDisabled is returned when registrations are turned off by feature gates.

View Source
var ErrTemporaryPasswordExpired = errors.New("temporary password expired", errors.CategoryAuth).
	WithTextCode(TextCodeTemporaryPasswordExpired).
	WithCode(errors.CodeForbidden)

ErrTemporaryPasswordExpired is returned when a temporary bootstrap password is no longer valid.

View Source
var ErrTerminalState = goerrors.New("user state is terminal", goerrors.CategoryConflict).
	WithTextCode(textCodeTerminalState).
	WithCode(goerrors.CodeConflict)

ErrTerminalState is returned when attempting to move away from a terminal status (e.g., archived).

View Source
var ErrTokenExpired = errors.New("token is expired", errors.CategoryAuth).
	WithTextCode(TextCodeTokenExpired).
	WithCode(errors.CodeUnauthorized)

ErrTokenExpired is returned when a JWT token has expired.

View Source
var ErrTokenMalformed = errors.New("token is malformed", errors.CategoryAuth).
	WithTextCode(TextCodeTokenMalformed).
	WithCode(errors.CodeBadRequest)

ErrTokenMalformed is returned when a JWT token is malformed.

View Source
var ErrTokenTooLarge = errors.New("token exceeds maximum allowed size", errors.CategoryValidation).
	WithTextCode(TextCodeTokenTooLarge).
	WithCode(errors.CodeBadRequest)

ErrTokenTooLarge is returned when a signed JWT exceeds configured guardrails.

View Source
var ErrTooManyLoginAttempts = errors.New("too many login attempts, please try again later", errors.CategoryRateLimit).
	WithTextCode(TextCodeTooManyAttempts).
	WithCode(errors.CodeTooManyRequests)

ErrTooManyLoginAttempts indicates the user has tried to log in too many times.

View Source
var ErrUnableToDecodeSession = errors.New("unable to decode session", errors.CategoryAuth).
	WithTextCode(TextCodeSessionDecodeError).
	WithCode(errors.CodeUnauthorized)

ErrUnableToDecodeSession is returned when a session token (e.g., JWT) cannot be decoded or parsed.

View Source
var ErrUnableToFindSession = errors.New("unable to find session", errors.CategoryAuth).
	WithTextCode(TextCodeSessionNotFound).
	WithCode(errors.CodeUnauthorized)

ErrUnableToFindSession is returned when a session (e.g., a cookie) is missing from a request.

View Source
var ErrUnableToMapClaims = errors.New("unable to map claims from token", errors.CategoryAuth).
	WithTextCode(TextCodeClaimsMappingError).
	WithCode(errors.CodeUnauthorized)

ErrUnableToMapClaims is returned when claims cannot be extracted from a parsed token.

View Source
var ErrUnableToParseData = errors.New("unable to parse authentication data", errors.CategoryBadInput).
	WithTextCode(TextCodeDataParseError).
	WithCode(errors.CodeBadRequest)

ErrUnableToParseData is returned on a generic data parsing error within the auth context.

View Source
var ErrUserArchived = errors.New("user account is archived", errors.CategoryAuth).
	WithTextCode(TextCodeAccountArchived).
	WithCode(errors.CodeForbidden)

ErrUserArchived is returned when an account is archived.

View Source
var ErrUserDisabled = errors.New("user account is disabled", errors.CategoryAuth).
	WithTextCode(TextCodeAccountDisabled).
	WithCode(errors.CodeForbidden)

ErrUserDisabled is returned when an account is disabled.

View Source
var ErrUserPending = errors.New("user account is pending activation", errors.CategoryAuth).
	WithTextCode(TextCodeAccountPending).
	WithCode(errors.CodeForbidden)

ErrUserPending is returned when an account is pending activation.

View Source
var ErrUserSuspended = errors.New("user account is suspended", errors.CategoryAuth).
	WithTextCode(TextCodeAccountSuspended).
	WithCode(errors.CodeForbidden)

ErrUserSuspended is returned when an account is suspended.

View Source
var ResetUserPasswordSQL = `` /* 148-byte string literal not displayed */

#nosec G101 -- SQL updates a password hash but does not embed credentials.

View Source
var TemplateUserKey = "current_user"

Functions

func Can added in v0.7.0

func Can(ctx context.Context, resource, permission string) bool

Can is a convenience function to check permissions directly from the standard context Use CanFromRouter for router-based contexts.

func CanFromRouter added in v0.7.0

func CanFromRouter(ctx router.Context, resource, permission string) bool

CanFromRouter is a convenience function to check permissions directly from the router context

func ClearTemporaryPasswordMetadata added in v0.42.0

func ClearTemporaryPasswordMetadata(metadata map[string]any) map[string]any

ClearTemporaryPasswordMetadata removes temporary-password state from a cloned metadata map.

func ComparePasswordAndHash

func ComparePasswordAndHash(password, hash string) error

ComparePasswordAndHash will validate the given cleartext password matches the hashed password

func ContextEnricherAdapter added in v0.23.0

func ContextEnricherAdapter(c context.Context, claims jwtware.AuthClaims) context.Context

ContextEnricherAdapter adapts jwtware.AuthClaims to auth.AuthClaims and stores claims + actor context in the standard context for downstream guard usage.

func CredentialModeGuard added in v0.45.0

func CredentialModeGuard(cfg RouteCredentialConfig) (router.MiddlewareFunc, error)

func DefaultPermissionsCacheKeyFromContext added in v0.32.0

func DefaultPermissionsCacheKeyFromContext(ctx context.Context) (string, bool)

DefaultPermissionsCacheKeyFromContext builds a stable resolver key from identity/tenant context plus permission-affecting discriminators (version, token, scopes, impersonation, session). It bypasses caching when no discriminator is available.

func DeriveBrowserCSRFSecureKey added in v0.45.0

func DeriveBrowserCSRFSecureKey(authCfg Config) []byte

DeriveBrowserCSRFSecureKey derives a stable, domain-separated CSRF key from the host's authentication configuration. It keeps browser CSRF signatures aligned across package-managed auth routes and application instances without reusing the raw authentication signing key.

func EncodeProviderSessionReason added in v0.45.0

func EncodeProviderSessionReason(reason ProviderSessionReason) string

func GetAuthExtrasMigrationsFS added in v0.36.0

func GetAuthExtrasMigrationsFS() fs.FS

GetAuthExtrasMigrationsFS returns optional auth extras migrations.

func GetCoreMigrationsFS added in v0.36.0

func GetCoreMigrationsFS() fs.FS

GetCoreMigrationsFS returns the canonical core auth schema migrations.

func GetMigrationsFS

func GetMigrationsFS() fs.FS

GetMigrationsFS returns the migration files for this package

func GetTemplateUser added in v0.10.0

func GetTemplateUser(ctx router.Context, userKey string) (any, bool)

GetTemplateUser is a convenience function to extract user data from router context for template usage. It returns the user object and a boolean indicating if it was found.

Usage:

if user, ok := auth.GetTemplateUser(ctx, auth.TemplateUserKey); ok {
	// Use user in template data
	data["user"] = user
}

func HasTemporaryPasswordMetadata added in v0.42.0

func HasTemporaryPasswordMetadata(metadata map[string]any) bool

HasTemporaryPasswordMetadata reports whether the metadata carries any temporary-password markers that must be cleared during a permanent password change.

func HasUserUUID added in v0.24.0

func HasUserUUID(session Session) bool

HasUserUUID reports whether Session.GetUserUUID will succeed.

func HashPassword

func HashPassword(password string) (string, error)

HashPassword will generate a password hash

func IsMalformedError

func IsMalformedError(err error) bool

func IsOutsideThresholdPeriod

func IsOutsideThresholdPeriod(t time.Time, pattern string) (bool, error)

IsOutsideThresholdPeriod is the negation of IsWithinThresholdPeriod

func IsProviderLifecycleActivity added in v0.45.0

func IsProviderLifecycleActivity(eventType ActivityEventType) bool

func IsProviderSessionActivity added in v0.45.0

func IsProviderSessionActivity(eventType ActivityEventType) bool

func IsTokenExpiredError

func IsTokenExpiredError(err error) bool

func IsWithinThresholdPeriod

func IsWithinThresholdPeriod(t time.Time, pattern string) (bool, error)

IsWithinThresholdPeriod checks if the given time is within the threshold

func MergeTemplateData added in v0.16.0

func MergeTemplateData(ctx router.Context, data router.ViewContext) router.ViewContext

MergeTemplateData ensures every render includes the latest template helpers (current user, CSRF helpers, etc.) merged with the provided view context. It evaluates helper closures that return strings or template.HTML so request- scoped helpers are always materialized before hitting the renderer.

func MintScopedToken added in v0.29.0

func MintScopedToken(tokenService TokenService, identity Identity, resourceRoles map[string]string, opts ScopedTokenOptions) (string, time.Time, error)

MintScopedToken mints a short-lived JWT with optional scopes and TTL override. It uses TokenService defaults for issuer, audience, and TTL when available.

func MustValidateResolverConfigured added in v0.34.0

func MustValidateResolverConfigured(strict bool, resolver PermissionResolverFunc)

MustValidateResolverConfigured is a panic wrapper around ValidateResolverConfigured.

func NewPasswordResetsRepository

func NewPasswordResetsRepository(db *bun.DB) repository.Repository[*PasswordReset]

func NewTemplateViews added in v0.45.5

func NewTemplateViews(views router.Views) router.Views

NewTemplateViews wraps a configured engine with an opt-in auth view boundary. Claims in plain render maps/slices expose identity and permission checks, not raw JWT metadata or extension methods. Request locals and context are untouched. Configure engine-specific helpers/extensions before wrapping. Nil stays nil.

func PermissionsVersionFromClaims added in v0.32.0

func PermissionsVersionFromClaims(claims AuthClaims) string

PermissionsVersionFromClaims extracts the permissions version from claims metadata.

func PermissionsVersionFromContext added in v0.32.0

func PermissionsVersionFromContext(ctx context.Context) string

PermissionsVersionFromContext extracts the permissions version from actor/claims metadata.

func RandomPasswordHash

func RandomPasswordHash() string

RandomPasswordHash is a temporary password

func RegisterAuthRoutes

func RegisterAuthRoutes[T any](app router.Router[T], opts ...AuthControllerOption)

func RegisterSecureAuthRoutes added in v0.45.0

func RegisterSecureAuthRoutes[T any](app router.Router[T], cfg AuthRouteSecurityConfig, opts ...AuthControllerOption) error

RegisterSecureAuthRoutes registers browser authentication routes with CSRF and origin protection. Logout is POST-only in this secure route set.

func RegisterValidationListeners added in v0.23.0

func RegisterValidationListeners(cfg *jwtware.Config, listeners ...ValidationListener)

RegisterValidationListeners appends listeners to a jwtware.Config in a safe, reusable way.

func RequireTokenUse added in v0.45.0

func RequireTokenUse(claims AuthClaims, expected string) error

RequireTokenUse enforces an explicit token-use boundary. Scoped-token consumers should call this with TokenTypeScoped after general validation.

func ResolveLogger added in v0.31.0

func ResolveLogger(name string, provider LoggerProvider, logger Logger) (LoggerProvider, Logger)

ResolveLogger resolves provider and logger with precedence provider > logger > nop.

func SetPermissionsVersionMetadata added in v0.32.0

func SetPermissionsVersionMetadata(claims *JWTClaims, version string)

SetPermissionsVersionMetadata stores a compact permission-version marker in claims metadata.

func TemplateHelpers added in v0.10.0

func TemplateHelpers() map[string]any

TemplateHelpers returns a map of helper functions and data that can be used with go-template's WithGlobalData option for authentication-related template functionality.

Usage:

renderer, err := template.NewRenderer(
    template.WithBaseDir("./templates"),
    template.WithGlobalData(auth.TemplateHelpers()),
)

In templates, you can then use:

{% if current_user %}
{% if current_user|has_role:"admin" %}
{% if current_user|can_create:"posts" %}
{{ csrf_field }}
{{ csrf_token }}

func TemplateHelpersForPongo2V7 added in v0.45.5

func TemplateHelpersForPongo2V7() map[string]any

TemplateHelpersForPongo2V7 returns auth helpers for a pongo2/v7 renderer, such as go-router's explicit Fiber v3 view engine. CSRF values are resolved from each execution context and returned as plain strings; the renderer owns escaping. This does not change TemplateHelpers or the default CSRF helper factory.

func TemplateHelpersWithRouter added in v0.10.0

func TemplateHelpersWithRouter(ctx router.Context, userKey string) map[string]any

TemplateHelpersWithRouter returns template helpers with user data extracted from router context. This is useful for automatically injecting the current user from JWT middleware context. It also includes CSRF token helpers when a CSRF token is available in the context.

Usage:

// In your route handler
globalData := auth.TemplateHelpersWithRouter(ctx, auth.TemplateUserKey)
// Merge with request-specific data and render template

Or with a reusable render helper:

func renderTemplate(ctx router.Context, name string, data map[string]any) (string, error) {
	globalData := auth.TemplateHelpersWithRouter(ctx, auth.TemplateUserKey)
	// Create renderer with current context or use a cached one
	return renderer.RenderTemplate(name, data)
}

func TemplateHelpersWithUser added in v0.10.0

func TemplateHelpersWithUser(user *User) map[string]any

TemplateHelpersWithUser returns template helpers with a specific user set as current_user. This is useful when you want to inject the current user directly into the global context.

Usage:

currentUser := getCurrentUser(ctx)
renderer, err := template.NewRenderer(
    template.WithBaseDir("./templates"),
    template.WithGlobalData(auth.TemplateHelpersWithUser(currentUser)),
)

func TokenIDFromContext added in v0.29.0

func TokenIDFromContext(ctx context.Context) (string, bool)

TokenIDFromContext extracts the token ID (jti) from the standard context.

func ValidateResolverConfigured added in v0.34.0

func ValidateResolverConfigured(strict bool, resolver PermissionResolverFunc) error

ValidateResolverConfigured enforces resolver presence when strict mode is enabled.

func ValidateStringEquals

func ValidateStringEquals(str string) validation.RuleFunc

ValidateStringEquals will check that both values match

func WithActorContext added in v0.15.0

func WithActorContext(ctx context.Context, actor *ActorContext) context.Context

WithActorContext stores the ActorContext in the provided context.

func WithAssuranceContext added in v0.45.0

func WithAssuranceContext(ctx context.Context, assurance AssuranceContext) context.Context

WithAssuranceContext stores isolated normalized assurance evidence.

func WithClaimsContext added in v0.7.0

func WithClaimsContext(r context.Context, claims AuthClaims) context.Context

WithClaimsContext sets the AuthClaims in the given context

func WithContext added in v0.4.0

func WithContext(r context.Context, user *User) context.Context

WithContext sets the User in the given context

func WithCurrentPermissionsRequest added in v0.45.0

func WithCurrentPermissionsRequest(
	ctx context.Context,
	request CurrentPermissionsRequest,
) (context.Context, error)

WithCurrentPermissionsRequest returns a context whose permission cache keys and invalidation scope are derived from current normalized authorization state rather than stale token hints.

func WithProviderSessionContext added in v0.45.0

func WithProviderSessionContext(ctx context.Context, session ProviderSession, principal AuthenticatedPrincipal) context.Context

func WithResolvedPermissionsCache added in v0.34.0

func WithResolvedPermissionsCache(ctx context.Context) context.Context

WithResolvedPermissionsCache seeds a request-scoped permission resolver cache in the provided context. The cache deduplicates repeated permission lookups within the same request context.

Types

type AESGCMTokenCipher added in v0.45.0

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

func NewAESGCMTokenCipher added in v0.45.0

func NewAESGCMTokenCipher(keys TokenKeyProvider) (*AESGCMTokenCipher, error)

func (*AESGCMTokenCipher) Open added in v0.45.0

func (c *AESGCMTokenCipher) Open(ctx context.Context, envelope TokenEnvelope, associatedData []byte) ([]byte, error)

func (*AESGCMTokenCipher) Seal added in v0.45.0

func (c *AESGCMTokenCipher) Seal(ctx context.Context, plaintext, associatedData []byte) (TokenEnvelope, error)

type AccountLifecycleRequest added in v0.45.0

type AccountLifecycleRequest struct {
	Operation AuthorizedOperationContext
}

type AccountRegistrerer

type AccountRegistrerer interface {
	RegisterUser(ctx context.Context, email, username, password string) (*User, error)
}

AccountRegistrerer is the interface we need to handle new user registrations

type AccountState added in v0.45.0

type AccountState string

AccountState is the provider-neutral lifecycle state used by freshness policy. Unknown and unsupported never imply active.

const (
	AccountStateActive      AccountState = "active"
	AccountStateSuspended   AccountState = "suspended"
	AccountStateDisabled    AccountState = "disabled"
	AccountStatePending     AccountState = "pending"
	AccountStateArchived    AccountState = "archived"
	AccountStateUnknown     AccountState = "unknown"
	AccountStateUnsupported AccountState = "unsupported"
)

func AccountStateFromProvider added in v0.45.0

func AccountStateFromProvider(state ProviderAccountState) AccountState

func ParseAccountState added in v0.45.0

func ParseAccountState(value string) (AccountState, error)

type AccountStateInvalidator added in v0.45.0

type AccountStateInvalidator interface {
	InvalidateAccountState(context.Context, string, string) error
}

type AccountStateObservation added in v0.45.0

type AccountStateObservation struct {
	State      AccountState
	Source     string
	ObservedAt time.Time
}

type AccountStateRequest added in v0.45.0

type AccountStateRequest struct {
	Principal        AuthenticatedPrincipal
	MaximumStaleness time.Duration
	Privileged       bool
}

type AccountStateResolution added in v0.45.0

type AccountStateResolution struct {
	State           AccountState
	ObservedAt      time.Time
	Sources         []AccountStateObservation
	FromCache       bool
	Conflict        bool
	Unavailable     bool
	InvalidEvidence bool
}

type AccountStateResolver added in v0.45.0

type AccountStateResolver interface {
	ResolveCurrentAccountState(context.Context, AccountStateRequest) (AccountStateResolution, error)
}

type AccountStateResult added in v0.45.0

type AccountStateResult struct {
	ProviderOperationOutcome
	State     ProviderAccountState
	UpdatedAt time.Time
}

type AccountStateScopeInvalidator added in v0.45.0

type AccountStateScopeInvalidator interface {
	InvalidateAccountStates(context.Context, PermissionInvalidationScope, int) (deleted int, more bool, err error)
}

type AccountStateSource added in v0.45.0

type AccountStateSource interface {
	ResolveAccountState(context.Context, AuthenticatedPrincipal) (AccountStateObservation, error)
}

type AccountStateSourceFunc added in v0.45.0

type AccountStateSourceFunc func(context.Context, AuthenticatedPrincipal) (AccountStateObservation, error)

func (AccountStateSourceFunc) ResolveAccountState added in v0.45.0

type AccountVerificationHandler

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

func (*AccountVerificationHandler) Execute

type AccountVerificationMesage

type AccountVerificationMesage struct {
	Session    string `json:"session" example:"350399bc-c095-4bdc-a59c-3352d44848e4" doc:"Reset password session token"`
	OnResponse func(a *AccountVerificationResponse)
}

type AccountVerificationResponse

type AccountVerificationResponse struct {
	Stage    string   `json:"stage" example:"Rone" doc:"Customer last name."`
	Redirect string   `json:"redirect" example:"Rone" doc:"Customer last name."`
	Expired  bool     `json:"expired" example:"true" doc:"Has the request expired?"`
	Found    bool     `json:"found" example:"true" doc:"Has the request been found?"`
	Errors   []string `json:"errors" example:"['invalid username']" doc:"Error messages."`
}

type ActivityEvent added in v0.14.0

type ActivityEvent struct {
	EventType  ActivityEventType
	Actor      ActorRef
	UserID     string
	FromStatus UserStatus
	ToStatus   UserStatus
	Metadata   map[string]any
	OccurredAt time.Time
}

ActivityEvent captures producer-side information about an action. Metadata is not a persistence-safe payload: login events may include the raw, unverified submitted identifier and provider error text. Consumers must apply their own retention/redaction policy before storage, forwarding or display. An attempted identifier must never be treated as verified actor identity.

func NewProviderLifecycleActivityEvent added in v0.45.0

func NewProviderLifecycleActivityEvent(
	operation AuthorizedOperationContext,
	outcome ProviderOperationOutcome,
	occurredAt time.Time,
) (ActivityEvent, error)

NewProviderLifecycleActivityEvent constructs a secret-free audit event from typed lifecycle inputs. Security-state delivery remains the coordinator's responsibility; this event is best-effort audit context only.

func NewProviderSessionActivityEvent added in v0.45.0

func NewProviderSessionActivityEvent(
	eventType ActivityEventType,
	session ProviderSession,
	metadata ProviderSessionActivityMetadata,
	occurredAt time.Time,
) (ActivityEvent, error)

type ActivityEventType added in v0.14.0

type ActivityEventType string

ActivityEventType enumerates supported activity categories.

const (
	ActivityEventUserStatusChanged        ActivityEventType = "user.status.changed"
	ActivityEventLoginSuccess             ActivityEventType = "auth.login.success"
	ActivityEventLoginFailure             ActivityEventType = "auth.login.failure"
	ActivityEventSocialLogin              ActivityEventType = "auth.social.login"
	ActivityEventSSOLoginSuccess          ActivityEventType = "auth.sso.login.success"
	ActivityEventSSOLoginFailure          ActivityEventType = "auth.sso.login.failure"
	ActivityEventSSOLinkAutomatic         ActivityEventType = "auth.sso.link.automatic"
	ActivityEventSSOLinkManual            ActivityEventType = "auth.sso.link.manual"
	ActivityEventSSOLinkRejected          ActivityEventType = "auth.sso.link.rejected"
	ActivityEventSSOUnlink                ActivityEventType = "auth.sso.unlink"
	ActivityEventSSOLogout                ActivityEventType = "auth.sso.logout"
	ActivityEventProviderSessionCreated   ActivityEventType = "auth.provider_session.created"
	ActivityEventProviderSessionRefreshed ActivityEventType = "auth.provider_session.refreshed"
	ActivityEventProviderSessionUncertain ActivityEventType = "auth.provider_session.uncertain"
	ActivityEventProviderSessionRevoked   ActivityEventType = "auth.provider_session.revoked"
	ActivityEventProviderTokenAccessed    ActivityEventType = "auth.provider_token.accessed"
	ActivityEventProviderInvite           ActivityEventType = "auth.provider.identity.invite"
	ActivityEventProviderRecovery         ActivityEventType = "auth.provider.identity.recovery"
	ActivityEventProviderAccountSuspend   ActivityEventType = "auth.provider.account.suspend"
	ActivityEventProviderAccountActivate  ActivityEventType = "auth.provider.account.activate"
	ActivityEventProviderAccountState     ActivityEventType = "auth.provider.account.state"
	ActivityEventProviderFactorList       ActivityEventType = "auth.provider.factor.list"
	ActivityEventProviderFactorRemove     ActivityEventType = "auth.provider.factor.remove"
	ActivityEventProviderAuthDetails      ActivityEventType = "auth.provider.authorization.details"
	ActivityEventProviderAuthApprove      ActivityEventType = "auth.provider.authorization.approve"
	ActivityEventProviderAuthDeny         ActivityEventType = "auth.provider.authorization.deny"
	ActivityEventImpersonationSuccess     ActivityEventType = "auth.impersonation.success"
	ActivityEventImpersonationFailure     ActivityEventType = "auth.impersonation.failure"
	ActivityEventPasswordResetSuccess     ActivityEventType = "auth.password.reset"
	ActivityEventAssuranceDenied          ActivityEventType = "auth.assurance.denied"
	ActivityEventAssuranceStepUp          ActivityEventType = "auth.assurance.step_up"
	ActivityEventAuthorizationFreshness   ActivityEventType = "auth.authorization.freshness"
	ActivityEventFreshnessInvalidation    ActivityEventType = "auth.freshness.invalidation"
	ActivityEventEmergencyAccess          ActivityEventType = "auth.emergency_access"
)

type ActivitySink added in v0.14.0

type ActivitySink interface {
	Record(ctx context.Context, event ActivityEvent) error
}

ActivitySink consumes activity events for auditing/telemetry purposes.

type ActivitySinkFunc added in v0.14.0

type ActivitySinkFunc func(ctx context.Context, event ActivityEvent) error

ActivitySinkFunc adapts a function to the ActivitySink interface.

func (ActivitySinkFunc) Record added in v0.14.0

func (f ActivitySinkFunc) Record(ctx context.Context, event ActivityEvent) error

Record implements ActivitySink.

type ActorContext added in v0.15.0

type ActorContext struct {
	ActorID        string
	Subject        string
	Role           string
	ResourceRoles  map[string]string
	TenantID       string
	OrganizationID string
	Metadata       map[string]any
	ImpersonatorID string
	IsImpersonated bool
}

ActorContext captures normalized actor metadata for downstream policy/guard layers.

func ActorContextFromClaims added in v0.15.0

func ActorContextFromClaims(claims AuthClaims) *ActorContext

ActorContextFromClaims normalizes actor metadata from AuthClaims into an ActorContext structure.

func ActorFromContext added in v0.15.0

func ActorFromContext(ctx context.Context) (*ActorContext, bool)

ActorFromContext extracts the ActorContext from the standard context.

func ActorFromRouterContext added in v0.15.0

func ActorFromRouterContext(ctx router.Context) (*ActorContext, bool)

ActorFromRouterContext extracts the ActorContext from a router context by reading the underlying standard context.

type ActorRef added in v0.14.0

type ActorRef struct {
	ID   string
	Type string
}

ActorRef identifies who/what triggered a transition.

type AssuranceContext added in v0.45.0

type AssuranceContext struct {
	Level            AssuranceLevel
	Methods          []string
	AuthenticationAt time.Time
}

AssuranceContext contains normalized, non-secret authentication evidence.

func AssuranceFromContext added in v0.45.0

func AssuranceFromContext(ctx context.Context) (AssuranceContext, error)

AssuranceFromContext returns explicit assurance evidence or derives it from the normalized provider-session principal.

type AssuranceDecision added in v0.45.0

type AssuranceDecision string
const (
	AssuranceAllowed        AssuranceDecision = "allowed"
	AssuranceDenied         AssuranceDecision = "denied"
	AssuranceStepUpRequired AssuranceDecision = "step_up_required"
)

type AssuranceGuard added in v0.45.0

type AssuranceGuard struct {
	Now          func() time.Time
	ActivitySink ActivitySink
}

AssuranceGuard evaluates assurance and emits denial/step-up audit events.

func (AssuranceGuard) Require added in v0.45.0

type AssuranceLevel added in v0.45.0

type AssuranceLevel string

AssuranceLevel is a provider-neutral ordered authentication assurance level.

const (
	AssuranceUnknown AssuranceLevel = "unknown"
	AssuranceAAL1    AssuranceLevel = "aal1"
	AssuranceAAL2    AssuranceLevel = "aal2"
)

func ParseAssuranceLevel added in v0.45.0

func ParseAssuranceLevel(value string) (AssuranceLevel, error)

ParseAssuranceLevel parses only supported provider-neutral values.

func (AssuranceLevel) Meets added in v0.45.0

func (l AssuranceLevel) Meets(required AssuranceLevel) bool

Meets reports whether a known level satisfies another known level.

type AssuranceReason added in v0.45.0

type AssuranceReason string
const (
	AssuranceReasonSatisfied    AssuranceReason = "satisfied"
	AssuranceReasonMissing      AssuranceReason = "missing"
	AssuranceReasonUnknown      AssuranceReason = "unknown"
	AssuranceReasonInsufficient AssuranceReason = "insufficient"
	AssuranceReasonStale        AssuranceReason = "stale"
	AssuranceReasonInvalid      AssuranceReason = "invalid_requirement"
)

type AssuranceRequirement added in v0.45.0

type AssuranceRequirement struct {
	Level                AssuranceLevel
	MaxAuthenticationAge time.Duration
	Operation            string
	AllowStepUp          bool
}

AssuranceRequirement is policy input for a single operation.

type AssuranceResult added in v0.45.0

type AssuranceResult struct {
	Decision         AssuranceDecision
	Reason           AssuranceReason
	Required         AssuranceLevel
	Current          AssuranceLevel
	Methods          []string
	AuthenticationAt time.Time
	Operation        string
}

AssuranceResult is safe to log and contains no provider tokens.

func RequireAssurance added in v0.45.0

func RequireAssurance(ctx context.Context, level AssuranceLevel) (AssuranceResult, error)

RequireAssurance performs the compatibility-friendly level-only check.

type AtomicIndexedPermissionCacheStore added in v0.45.0

type AtomicIndexedPermissionCacheStore interface {
	IndexedPermissionCacheStore
	SetPermissionCacheEntry(
		ctx context.Context,
		key string,
		permissions []string,
		ttl time.Duration,
		scope PermissionInvalidationScope,
	) error
}

AtomicIndexedPermissionCacheStore publishes a permission value and all of its invalidation indexes as one operation. Implementations must leave neither the value nor its indexes visible when this method returns an error.

type AtomicLoginAttemptRepository added in v0.45.0

type AtomicLoginAttemptRepository interface {
	AtomicLoginAttemptTracker
	ReserveLoginAttemptTx(ctx context.Context, tx bun.IDB, userID uuid.UUID, policy LoginAttemptPolicy) (LoginAttemptReservation, error)
}

AtomicLoginAttemptRepository is the optional repository capability for reserving login attempts atomically, including inside an existing transaction. It is separate from Users to preserve compatibility for custom Users implementations.

type AtomicLoginAttemptTracker added in v0.45.0

type AtomicLoginAttemptTracker interface {
	ReserveLoginAttempt(context.Context, uuid.UUID, LoginAttemptPolicy) (LoginAttemptReservation, error)
}

AtomicLoginAttemptTracker reserves password-verification attempts with one database operation so parallel requests cannot exceed the configured budget.

type AuthClaims added in v0.7.0

type AuthClaims interface {
	Subject() string
	UserID() string
	Role() string
	CanRead(resource string) bool
	CanEdit(resource string) bool
	CanCreate(resource string) bool
	CanDelete(resource string) bool
	HasRole(role string) bool
	IsAtLeast(minRole string) bool
	Expires() time.Time
	IssuedAt() time.Time
}

AuthClaims represents structured JWT claims with enhanced permission checking

func GetClaims added in v0.7.0

func GetClaims(ctx context.Context) (AuthClaims, bool)

GetClaims extracts the AuthClaims from the standard context

func GetRouterClaims added in v0.7.0

func GetRouterClaims(ctx router.Context, key string) (AuthClaims, bool)

GetRouterClaims extracts the AuthClaims from the router context

func WSAuthClaimsFromContext added in v0.9.0

func WSAuthClaimsFromContext(ctx context.Context) (AuthClaims, bool)

WSAuthClaimsFromContext is a convenience function to retrieve auth claims from WebSocket context. It returns the underlying go-auth AuthClaims for easier access to go-auth specific functionality.

type AuthController

type AuthController struct {
	Debug                 bool
	Logger                Logger
	LoggerProvider        LoggerProvider
	Repo                  RepositoryManager
	Routes                *AuthControllerRoutes
	Views                 *AuthControllerViews
	Auther                HTTPAuthenticator
	ErrorHandler          router.ErrorHandler
	RegisterRedirect      string
	UseHashID             bool
	PasswordResetDelivery PasswordResetDelivery
	// contains filtered or unexported fields
}

func NewAuthController

func NewAuthController(opts ...AuthControllerOption) *AuthController

func (*AuthController) LogOut

func (a *AuthController) LogOut(ctx router.Context) error

func (*AuthController) LoginPost

func (a *AuthController) LoginPost(ctx router.Context) error

func (*AuthController) LoginShow

func (a *AuthController) LoginShow(ctx router.Context) error

func (*AuthController) PasswordResetExecute

func (a *AuthController) PasswordResetExecute(ctx router.Context) error

func (*AuthController) PasswordResetForm

func (a *AuthController) PasswordResetForm(ctx router.Context) error

func (*AuthController) PasswordResetGet

func (a *AuthController) PasswordResetGet(ctx router.Context) error

func (*AuthController) PasswordResetPost

func (a *AuthController) PasswordResetPost(ctx router.Context) error

func (*AuthController) RegistrationCreate

func (a *AuthController) RegistrationCreate(ctx router.Context) error

func (*AuthController) RegistrationShow

func (a *AuthController) RegistrationShow(ctx router.Context) error

func (*AuthController) WithLogger added in v0.4.0

func (a *AuthController) WithLogger(l Logger) *AuthController

type AuthControllerOption

type AuthControllerOption func(*AuthController) *AuthController

func WithAuthControllerActivitySink added in v0.14.0

func WithAuthControllerActivitySink(sink ActivitySink) AuthControllerOption

func WithAuthControllerRedirect added in v0.3.0

func WithAuthControllerRedirect(r string) AuthControllerOption

func WithAuthControllerRoutes added in v0.3.0

func WithAuthControllerRoutes(r *AuthControllerRoutes) AuthControllerOption

func WithAuthControllerUseHashID added in v0.3.0

func WithAuthControllerUseHashID(v bool) AuthControllerOption

func WithAuthControllerViews added in v0.3.0

func WithAuthControllerViews(v *AuthControllerViews) AuthControllerOption

func WithControllerLogger added in v0.1.1

func WithControllerLogger(logger Logger) AuthControllerOption

func WithControllerLoggerProvider added in v0.31.0

func WithControllerLoggerProvider(provider LoggerProvider) AuthControllerOption

func WithErrorHandler added in v0.3.0

func WithErrorHandler(errHandler router.ErrorHandler) AuthControllerOption

func WithFeatureGate added in v0.26.0

func WithFeatureGate(featureGate gate.FeatureGate) AuthControllerOption

func WithPasswordResetDelivery added in v0.45.0

func WithPasswordResetDelivery(delivery PasswordResetDelivery) AuthControllerOption

type AuthControllerRoutes

type AuthControllerRoutes struct {
	Login         string
	Logout        string
	Register      string
	PasswordReset string
}

type AuthControllerViews

type AuthControllerViews struct {
	Login         string
	Logout        string
	Register      string
	PasswordReset string
}

type AuthCookieOption added in v0.44.0

type AuthCookieOption func(*authCookieOptions)

func WithAuthCookieDuration added in v0.44.0

func WithAuthCookieDuration(duration time.Duration) AuthCookieOption

WithAuthCookieDuration overrides the default session-cookie duration used by SetAuthCookie for externally authenticated browser flows.

func WithExtendedAuthCookieDuration added in v0.44.0

func WithExtendedAuthCookieDuration() AuthCookieOption

WithExtendedAuthCookieDuration uses the configured extended session duration when SetAuthCookie writes a session cookie.

type AuthRouteSecurityConfig added in v0.45.0

type AuthRouteSecurityConfig struct {
	CSRF   csfmw.Config
	Origin router.OriginProtectionConfig
}

AuthRouteSecurityConfig configures CSRF and origin checks for the package's browser-facing authentication routes.

type AuthenticatedPrincipal added in v0.45.0

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

func NewAuthenticatedPrincipal added in v0.45.0

func NewAuthenticatedPrincipal(input AuthenticatedPrincipalInput) (AuthenticatedPrincipal, error)

func (AuthenticatedPrincipal) ApplicationSubject added in v0.45.0

func (p AuthenticatedPrincipal) ApplicationSubject() string

func (AuthenticatedPrincipal) AssuranceLevel added in v0.45.0

func (p AuthenticatedPrincipal) AssuranceLevel() string

func (AuthenticatedPrincipal) AssuranceMethods added in v0.45.0

func (p AuthenticatedPrincipal) AssuranceMethods() []string

func (AuthenticatedPrincipal) AuthenticationAt added in v0.45.0

func (p AuthenticatedPrincipal) AuthenticationAt() time.Time

func (AuthenticatedPrincipal) BindLocalSessionID added in v0.45.0

func (p AuthenticatedPrincipal) BindLocalSessionID(localSessionID string) (AuthenticatedPrincipal, error)

BindLocalSessionID returns a copy associated with the host session created after provider identity linking. Rebinding to a different session fails.

func (AuthenticatedPrincipal) ClientID added in v0.45.0

func (p AuthenticatedPrincipal) ClientID() string

func (AuthenticatedPrincipal) Clone added in v0.45.0

func (AuthenticatedPrincipal) ExpiresAt added in v0.45.0

func (p AuthenticatedPrincipal) ExpiresAt() time.Time

func (AuthenticatedPrincipal) IssuedAt added in v0.45.0

func (p AuthenticatedPrincipal) IssuedAt() time.Time

func (AuthenticatedPrincipal) LocalSessionID added in v0.45.0

func (p AuthenticatedPrincipal) LocalSessionID() string

func (AuthenticatedPrincipal) Metadata added in v0.45.0

func (p AuthenticatedPrincipal) Metadata() map[string]string

func (AuthenticatedPrincipal) OrganizationID added in v0.45.0

func (p AuthenticatedPrincipal) OrganizationID() string

func (AuthenticatedPrincipal) PermissionVersion added in v0.45.0

func (p AuthenticatedPrincipal) PermissionVersion() string

func (AuthenticatedPrincipal) Provider added in v0.45.0

func (p AuthenticatedPrincipal) Provider() string

func (AuthenticatedPrincipal) ProviderSessionID added in v0.45.0

func (p AuthenticatedPrincipal) ProviderSessionID() string

func (AuthenticatedPrincipal) ProviderSubject added in v0.45.0

func (p AuthenticatedPrincipal) ProviderSubject() string

func (AuthenticatedPrincipal) TenantID added in v0.45.0

func (p AuthenticatedPrincipal) TenantID() string

func (AuthenticatedPrincipal) TokenID added in v0.45.0

func (p AuthenticatedPrincipal) TokenID() string

type AuthenticatedPrincipalInput added in v0.45.0

type AuthenticatedPrincipalInput struct {
	ApplicationSubject string
	Provider           string
	ProviderSubject    string
	ProviderSessionID  string
	LocalSessionID     string
	ClientID           string
	AssuranceLevel     string
	AssuranceMethods   []string
	AuthenticationAt   time.Time
	IssuedAt           time.Time
	ExpiresAt          time.Time
	TokenID            string
	TenantID           string
	OrganizationID     string
	PermissionVersion  string
	Metadata           map[string]string
}

AuthenticatedPrincipalInput is accepted only after provider identity linking.

type Authenticator

type Authenticator interface {
	Login(ctx context.Context, identifier, password string) (string, error)
	Impersonate(ctx context.Context, identifier string) (string, error)
	SessionFromToken(token string) (Session, error)
	IdentityFromSession(ctx context.Context, session Session) (Identity, error)
	TokenService() TokenService
}

Authenticator holds methods to deal with authentication

type Auther

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

func NewAuthenticator

func NewAuthenticator(provider IdentityProvider, opts Config) *Auther

NewAuthenticator returns a new Authenticator. A nil or typed-nil provider supports token-validation-only use; Login and Impersonate return ErrIdentityProviderRequired until a valid provider is configured.

func (*Auther) IdentityFromSession

func (s *Auther) IdentityFromSession(ctx context.Context, session Session) (Identity, error)

func (*Auther) Impersonate

func (s *Auther) Impersonate(ctx context.Context, identifier string) (string, error)

func (*Auther) Login

func (s *Auther) Login(ctx context.Context, identifier, password string) (string, error)

func (*Auther) NewWSAuthMiddleware added in v0.9.0

func (a *Auther) NewWSAuthMiddleware(config ...router.WSAuthConfig) router.WebSocketMiddleware

NewWSAuthMiddleware creates a fully configured WebSocket authentication middleware using the go-auth TokenService. This is a convenience function for go-auth users.

func (Auther) SessionFromToken

func (s Auther) SessionFromToken(raw string) (Session, error)

SessionFromToken validates a session token and, when a provider is configured, checks that its current identity still exists and is active. For request-scoped cancellation, use SessionFromTokenContext.

func (Auther) SessionFromTokenContext added in v0.45.3

func (s Auther) SessionFromTokenContext(ctx context.Context, raw string) (Session, error)

SessionFromTokenContext validates a token before checking current account state. Authenticators without an identity provider retain token-validation-only mode.

func (*Auther) TokenService added in v0.11.0

func (s *Auther) TokenService() TokenService

TokenService returns the TokenService instance used by this Authenticator

func (*Auther) WithActivitySink added in v0.14.0

func (s *Auther) WithActivitySink(sink ActivitySink) *Auther

WithActivitySink configures an ActivitySink for emitting auth events.

func (*Auther) WithClaimsDecorator added in v0.14.0

func (s *Auther) WithClaimsDecorator(decorator ClaimsDecorator) *Auther

WithClaimsDecorator configures a ClaimsDecorator for enriching JWTs.

func (*Auther) WithLogger added in v0.1.1

func (s *Auther) WithLogger(logger Logger) *Auther

func (*Auther) WithLoggerProvider added in v0.31.0

func (s *Auther) WithLoggerProvider(provider LoggerProvider) *Auther

WithLoggerProvider overrides the logger provider used by the authenticator.

func (*Auther) WithResourceRoleProvider added in v0.7.0

func (s *Auther) WithResourceRoleProvider(provider ResourceRoleProvider) *Auther

WithResourceRoleProvider sets a custom ResourceRoleProvider for the Auther. This enables resource-level permissions in JWT tokens.

func (*Auther) WithTokenSizeGuardrails added in v0.34.0

func (s *Auther) WithTokenSizeGuardrails(warnThresholdBytes, hardLimitBytes int) *Auther

WithTokenSizeGuardrails configures signed JWT size warning/rejection thresholds.

func (*Auther) WithTokenValidator added in v0.24.0

func (s *Auther) WithTokenValidator(validator TokenValidator) *Auther

WithTokenValidator sets a custom token validator for externally issued tokens.

type AuthorizationContinuation added in v0.45.0

type AuthorizationContinuation struct {
	AuthorizationID string
	Environment     string
	ExpiresAt       time.Time
}

func (AuthorizationContinuation) Validate added in v0.45.0

func (c AuthorizationContinuation) Validate(now time.Time) error

type AuthorizationDecisionRequest added in v0.45.0

type AuthorizationDecisionRequest struct {
	Operation       AuthorizedOperationContext
	AuthorizationID string
	ClientID        string
	Session         ProviderUserSession
	Scopes          []string
	CSRFBinding     string
	// DecisionProof must be the server-held proof returned by details retrieval.
	DecisionProof Secret
}

func (AuthorizationDecisionRequest) Validate added in v0.45.0

func (r AuthorizationDecisionRequest) Validate(action ProviderOperationAction, provider, environment string, now time.Time) error

type AuthorizationDecisionResult added in v0.45.0

type AuthorizationDecisionResult struct {
	ProviderOperationOutcome
	RedirectURL string
}

func (AuthorizationDecisionResult) Format added in v0.45.0

func (r AuthorizationDecisionResult) Format(state fmt.State, _ rune)

func (AuthorizationDecisionResult) GoString added in v0.45.0

func (r AuthorizationDecisionResult) GoString() string

func (AuthorizationDecisionResult) HTTPRedirectURL added in v0.45.0

func (r AuthorizationDecisionResult) HTTPRedirectURL() string

func (AuthorizationDecisionResult) LogValue added in v0.45.0

func (r AuthorizationDecisionResult) LogValue() slog.Value

func (AuthorizationDecisionResult) MarshalJSON added in v0.45.0

func (r AuthorizationDecisionResult) MarshalJSON() ([]byte, error)

func (AuthorizationDecisionResult) String added in v0.45.0

func (AuthorizationDecisionResult) ValidateRedirect added in v0.45.0

func (r AuthorizationDecisionResult) ValidateRedirect(allow func(*url.URL) bool) error

type AuthorizationDecisionService added in v0.45.0

type AuthorizationDetails added in v0.45.0

type AuthorizationDetails struct {
	AuthorizationID string
	ClientID        string
	ClientName      string
	Scopes          []string
	RedirectURL     string
	ExpiresAt       time.Time
	// DecisionProof is server-held, tamper-evident continuity state. It is
	// intentionally omitted from JSON and default formatting.
	DecisionProof Secret
}

func (AuthorizationDetails) Clone added in v0.45.0

func (AuthorizationDetails) MarshalJSON added in v0.45.0

func (d AuthorizationDetails) MarshalJSON() ([]byte, error)

type AuthorizationDetailsRequest added in v0.45.0

type AuthorizationDetailsRequest struct {
	Operation    AuthorizedOperationContext
	Continuation AuthorizationContinuation
	Session      ProviderUserSession
}

func (AuthorizationDetailsRequest) Validate added in v0.45.0

func (r AuthorizationDetailsRequest) Validate(provider, environment string, now time.Time) error

type AuthorizationFreshnessGuard added in v0.45.0

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

AuthorizationFreshnessGuard composes current session, assurance, account state, permission version, and current permission checks.

func NewAuthorizationFreshnessGuard added in v0.45.0

func NewAuthorizationFreshnessGuard(cfg AuthorizationFreshnessGuardConfig) (*AuthorizationFreshnessGuard, error)

func (*AuthorizationFreshnessGuard) Authorize added in v0.45.0

type AuthorizationFreshnessGuardConfig added in v0.45.0

type AuthorizationFreshnessGuardConfig struct {
	Policy             *FreshnessPolicy
	AccountStates      AccountStateResolver
	PermissionVersions PermissionVersionResolver
	Permissions        PermissionResolverFunc
	Assurance          AssuranceGuard
	ActivitySink       ActivitySink
	Now                func() time.Time
}

type AuthorizationFreshnessRequest added in v0.45.0

type AuthorizationFreshnessRequest struct {
	Operation string
	// Role is retained for source compatibility but is not authorization
	// evidence. The guard selects policy from PermissionVersionResult.Role.
	// Deprecated: populate the authoritative role in PermissionVersionResult.
	Role      string
	Principal AuthenticatedPrincipal
}

type AuthorizationFreshnessResult added in v0.45.0

type AuthorizationFreshnessResult struct {
	Decision             FreshnessDecision
	Reason               FreshnessReason
	Operation            string
	Policy               FreshnessOperationPolicy
	Assurance            AssuranceResult
	AccountState         AccountStateResolution
	SessionVersion       string
	CurrentVersion       string
	CurrentRole          string
	Permissions          []string
	PermissionsRefreshed bool
}

type AuthorizationMutation added in v0.45.0

type AuthorizationMutation func(context.Context) error

AuthorizationMutation is executed inside the host authorization transaction that also advances the permission version.

type AuthorizationVersionEvent added in v0.45.0

type AuthorizationVersionEvent struct {
	OperationID        string
	ApplicationSubject string
	TenantID           string
	Version            string
	CommittedAt        time.Time
}

type AuthorizationVersionPublisher added in v0.45.0

type AuthorizationVersionPublisher interface {
	PublishAuthorizationVersion(context.Context, AuthorizationVersionEvent) error
}

type AuthorizationVersionPublisherFunc added in v0.45.0

type AuthorizationVersionPublisherFunc func(context.Context, AuthorizationVersionEvent) error

func (AuthorizationVersionPublisherFunc) PublishAuthorizationVersion added in v0.45.0

func (f AuthorizationVersionPublisherFunc) PublishAuthorizationVersion(ctx context.Context, event AuthorizationVersionEvent) error

type AuthorizationVersionStore added in v0.45.0

type AuthorizationVersionStore interface {
	CurrentAuthorizationVersion(context.Context, string, string) (PermissionVersionResult, error)
	AdvanceAuthorizationVersion(context.Context, string, string, string, AuthorizationMutation) (PermissionVersionResult, error)
}

AuthorizationVersionStore is the host-owned atomic transaction boundary.

type AuthorizationVersionWriteResult added in v0.45.0

type AuthorizationVersionWriteResult struct {
	Event     AuthorizationVersionEvent
	Committed bool
	Published bool
}

type AuthorizationVersionWriter added in v0.45.0

type AuthorizationVersionWriter struct {
	Store     AuthorizationVersionStore
	Publisher AuthorizationVersionPublisher
	Now       func() time.Time
}

AuthorizationVersionWriter publishes only after the store's atomic mutation and version advance have committed.

func (AuthorizationVersionWriter) Advance added in v0.45.0

func (w AuthorizationVersionWriter) Advance(
	ctx context.Context,
	operationID, applicationSubject, tenantID string,
	mutation AuthorizationMutation,
) (AuthorizationVersionWriteResult, error)

type AuthorizedOperationContext added in v0.45.0

type AuthorizedOperationContext struct {
	OperationID       string
	Action            ProviderOperationAction
	Permission        string
	Actor             ActorRef
	Target            ProviderOperationTarget
	Reason            string
	Environment       string
	RequestID         string
	ProviderSessionID string
	AuthorizedAt      time.Time
}

AuthorizedOperationContext is a typed proof that the host authorized one exact provider operation. It deliberately contains no credential or token.

func (AuthorizedOperationContext) Validate added in v0.45.0

func (c AuthorizedOperationContext) Validate(expected ProviderOperationAction, environment, provider string) error

Validate verifies that the proof is complete and bound to the expected action, environment, and target provider before any transport work occurs.

type BrowserProtectionConfig added in v0.37.0

type BrowserProtectionConfig struct {
	AuthCookieName string
	CSRF           csrf.Config
	Origin         router.OriginProtectionConfig
}

type CachedPermissionsResolver added in v0.32.0

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

CachedPermissionsResolver wraps a permission resolver with key-based TTL caching and singleflight deduplication to prevent query amplification under load.

func NewCachedPermissionsResolver added in v0.32.0

func NewCachedPermissionsResolver(cfg CachedPermissionsResolverConfig) *CachedPermissionsResolver

NewCachedPermissionsResolver builds a CachedPermissionsResolver. When cfg.TTL <= 0, cross-request storage is disabled but singleflight deduplication still applies.

func (*CachedPermissionsResolver) Invalidate added in v0.32.0

func (r *CachedPermissionsResolver) Invalidate(ctx context.Context, key string) error

Invalidate removes a single cache key.

func (*CachedPermissionsResolver) InvalidateScope added in v0.45.0

func (r *CachedPermissionsResolver) InvalidateScope(
	ctx context.Context,
	scope PermissionInvalidationScope,
	limit int,
) (deleted int, more bool, err error)

InvalidateScope removes at most limit indexed entries. Callers retry while more=true; no implementation is allowed to fall back to a full key scan.

func (*CachedPermissionsResolver) PurgeExpired added in v0.32.0

func (r *CachedPermissionsResolver) PurgeExpired(ctx context.Context) (int, error)

PurgeExpired deletes stale cache entries when the configured store supports it.

func (*CachedPermissionsResolver) ResolvePermissions added in v0.32.0

func (r *CachedPermissionsResolver) ResolvePermissions(ctx context.Context) ([]string, error)

ResolvePermissions resolves permissions with cache + singleflight safeguards.

func (*CachedPermissionsResolver) ResolverFunc added in v0.32.0

ResolverFunc returns the wrapped resolver function.

func (*CachedPermissionsResolver) Stats added in v0.32.0

Stats returns a copy of the internal counters.

func (*CachedPermissionsResolver) Store added in v0.33.0

Store returns the configured cache store implementation.

type CachedPermissionsResolverConfig added in v0.32.0

type CachedPermissionsResolverConfig struct {
	Resolver PermissionResolverFunc
	KeyFunc  PermissionCacheKeyFunc
	Store    PermissionCacheStore
	TTL      time.Duration
	// ResolutionTimeout bounds shared backend work independently from any one
	// caller. Zero uses DefaultPermissionResolutionTimeout.
	ResolutionTimeout time.Duration
	CacheErrorMode    PermissionCacheErrorMode
	Logger            Logger
}

CachedPermissionsResolverConfig configures the cross-request resolver cache.

type ClaimsDecorator added in v0.14.0

type ClaimsDecorator interface {
	Decorate(ctx context.Context, identity Identity, claims *JWTClaims) error
}

ClaimsDecorator can mutate allowed JWT claim extensions before a token is signed. Implementations may only touch extension fields (e.g. Resources, Metadata) and must leave registered/identity claims untouched so core auth semantics stay stable.

func TemporaryPasswordClaimsDecorator added in v0.41.0

func TemporaryPasswordClaimsDecorator() ClaimsDecorator

TemporaryPasswordClaimsDecorator copies compact temporary-password hints into JWT metadata.

type ClaimsDecoratorFunc added in v0.14.0

type ClaimsDecoratorFunc func(ctx context.Context, identity Identity, claims *JWTClaims) error

ClaimsDecoratorFunc adapts a function into a ClaimsDecorator.

func (ClaimsDecoratorFunc) Decorate added in v0.14.0

func (f ClaimsDecoratorFunc) Decorate(ctx context.Context, identity Identity, claims *JWTClaims) error

Decorate satisfies the ClaimsDecorator interface.

type CompositeAccountStateResolver added in v0.45.0

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

CompositeAccountStateResolver evaluates every configured authoritative source. Hard denies win; privileged ambiguity and outage fail closed.

func NewCompositeAccountStateResolver added in v0.45.0

func NewCompositeAccountStateResolver(cfg CompositeAccountStateResolverConfig) (*CompositeAccountStateResolver, error)

func (*CompositeAccountStateResolver) InvalidateAccountState added in v0.45.0

func (r *CompositeAccountStateResolver) InvalidateAccountState(_ context.Context, applicationSubject, tenantID string) error

func (*CompositeAccountStateResolver) InvalidateAccountStates added in v0.45.0

func (r *CompositeAccountStateResolver) InvalidateAccountStates(
	_ context.Context,
	scope PermissionInvalidationScope,
	limit int,
) (int, bool, error)

func (*CompositeAccountStateResolver) ResolveCurrentAccountState added in v0.45.0

func (r *CompositeAccountStateResolver) ResolveCurrentAccountState(
	ctx context.Context,
	request AccountStateRequest,
) (AccountStateResolution, error)

type CompositeAccountStateResolverConfig added in v0.45.0

type CompositeAccountStateResolverConfig struct {
	Sources  []NamedAccountStateSource
	CacheTTL time.Duration
	Now      func() time.Time
}

type Config

type Config interface {
	GetSigningKey() string
	GetSigningMethod() string
	GetContextKey() string
	GetTokenExpiration() int
	GetExtendedTokenDuration() int
	GetTokenLookup() string
	GetAuthScheme() string
	GetIssuer() string
	GetAudience() []string
	GetRejectedRouteKey() string
	GetRejectedRouteDefault() string
}

Config holds auth options

type CoordinatedProviderOperationExecutor added in v0.45.0

type CoordinatedProviderOperationExecutor interface {
	ExecuteCoordinatedProviderOperation(
		context.Context,
		AuthorizedOperationContext,
		LifecycleExecutionPermit,
	) (ProviderOperationOutcome, error)
}

type CoordinatedProviderOperationExecutorFunc added in v0.45.0

type CoordinatedProviderOperationExecutorFunc func(
	context.Context,
	AuthorizedOperationContext,
	LifecycleExecutionPermit,
) (ProviderOperationOutcome, error)

func (CoordinatedProviderOperationExecutorFunc) ExecuteCoordinatedProviderOperation added in v0.45.0

type CurrentPermissionsRequest added in v0.45.0

type CurrentPermissionsRequest struct {
	Principal AuthenticatedPrincipal
	Version   string
	Role      string
	SessionID string
	// ForceRefresh bypasses every cross-request cache lookup. A successful
	// authoritative result may still replace the entry under the current key.
	ForceRefresh bool
}

CurrentPermissionsRequest binds permission resolution to the normalized principal and authoritative authorization version selected by the freshness guard. SessionID is the local provider-session ID when one is available.

func CurrentPermissionsRequestFromContext added in v0.45.0

func CurrentPermissionsRequestFromContext(ctx context.Context) (CurrentPermissionsRequest, bool)

CurrentPermissionsRequestFromContext returns a defensive copy of the authoritative permission-resolution request.

type EmergencyAccessDecision added in v0.45.0

type EmergencyAccessDecision string
const (
	EmergencyAccessAllowed EmergencyAccessDecision = "allowed"
	EmergencyAccessDenied  EmergencyAccessDecision = "denied"
)

type EmergencyAccessGrant added in v0.45.0

type EmergencyAccessGrant struct {
	ID                string
	ActorID           string
	Approvers         []string
	AllowedOperations []string
	CredentialClass   string
	Reason            string
	IssuedAt          time.Time
	ExpiresAt         time.Time
}

type EmergencyAccessGrantResolver added in v0.45.0

type EmergencyAccessGrantResolver interface {
	ResolveEmergencyAccessGrant(context.Context, string) (IssuedEmergencyAccessGrant, error)
}

type EmergencyAccessGrantResolverFunc added in v0.45.0

type EmergencyAccessGrantResolverFunc func(context.Context, string) (IssuedEmergencyAccessGrant, error)

func (EmergencyAccessGrantResolverFunc) ResolveEmergencyAccessGrant added in v0.45.0

func (f EmergencyAccessGrantResolverFunc) ResolveEmergencyAccessGrant(
	ctx context.Context,
	grantID string,
) (IssuedEmergencyAccessGrant, error)

type EmergencyAccessPolicy added in v0.45.0

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

func NewEmergencyAccessPolicy added in v0.45.0

func NewEmergencyAccessPolicy(cfg EmergencyAccessPolicyConfig) (*EmergencyAccessPolicy, error)

func (*EmergencyAccessPolicy) Authorize deprecated added in v0.45.0

func (p *EmergencyAccessPolicy) Authorize(
	ctx context.Context,
	grant EmergencyAccessGrant,
	operation, credentialClass string,
) (EmergencyAccessResult, error)

Authorize validates a caller-constructed compatibility grant.

Deprecated: use AuthorizeGrant with an authoritative resolver and isolated credential verifier.

func (*EmergencyAccessPolicy) AuthorizeGrant added in v0.45.0

func (p *EmergencyAccessPolicy) AuthorizeGrant(
	ctx context.Context,
	grantID, operation string,
	presentedProof Secret,
) (EmergencyAccessResult, error)

AuthorizeGrant resolves immutable issuance data and independently verifies opaque isolated-credential evidence. Caller-supplied labels are never used as authority.

func (*EmergencyAccessPolicy) Revoke deprecated added in v0.45.0

func (p *EmergencyAccessPolicy) Revoke(
	ctx context.Context,
	grantID, actorID, reason string,
) error

Revoke revokes a caller-constructed compatibility grant by logical ID.

Deprecated: authoritative policies require RevokeIssuedGrant so revocation is bound to the same immutable grant version checked by AuthorizeGrant.

func (*EmergencyAccessPolicy) RevokeIssuedGrant added in v0.45.0

func (p *EmergencyAccessPolicy) RevokeIssuedGrant(
	ctx context.Context,
	grantID, grantVersion, actorID, reason string,
) error

RevokeIssuedGrant revokes one immutable grant version without affecting a separately issued version with the same logical grant identifier.

type EmergencyAccessPolicyConfig added in v0.45.0

type EmergencyAccessPolicyConfig struct {
	Owner                 string
	ApprovedAt            time.Time
	PolicyVersion         string
	CredentialClass       string
	AllowedOperations     []string
	ApprovedApprovers     []string
	RequiredApprovals     int
	MaxDuration           time.Duration
	MonitoringDestination string
	ExerciseCadence       time.Duration
	Revocations           EmergencyAccessRevocationResolver
	Revoker               EmergencyAccessRevoker
	GrantResolver         EmergencyAccessGrantResolver
	CredentialVerifier    EmergencyCredentialVerifier
	// AllowLegacyAuthorize permits the deprecated caller-constructed grant API.
	// Hardened deployments must leave it false.
	AllowLegacyAuthorize bool
	ActivitySink         ActivitySink
	Now                  func() time.Time
}

type EmergencyAccessReason added in v0.45.0

type EmergencyAccessReason string
const (
	EmergencyAccessReasonAllowed          EmergencyAccessReason = "allowed"
	EmergencyAccessReasonInvalidGrant     EmergencyAccessReason = "invalid_grant"
	EmergencyAccessReasonCredential       EmergencyAccessReason = "credential_isolation" // #nosec G101 -- Audit reason code, not a credential.
	EmergencyAccessReasonScope            EmergencyAccessReason = "scope_violation"
	EmergencyAccessReasonExpired          EmergencyAccessReason = "expired"
	EmergencyAccessReasonRevoked          EmergencyAccessReason = "revoked"
	EmergencyAccessReasonDependencyOutage EmergencyAccessReason = "dependency_outage"
	EmergencyAccessReasonAuditFailure     EmergencyAccessReason = "audit_failure"
)

type EmergencyAccessResult added in v0.45.0

type EmergencyAccessResult struct {
	Decision     EmergencyAccessDecision
	Reason       EmergencyAccessReason
	GrantID      string
	GrantVersion string
	ActorID      string
	Operation    string
	ExpiresAt    time.Time
}

type EmergencyAccessRevocationResolver added in v0.45.0

type EmergencyAccessRevocationResolver interface {
	EmergencyAccessRevoked(context.Context, string) (bool, error)
}

type EmergencyAccessRevocationResolverFunc added in v0.45.0

type EmergencyAccessRevocationResolverFunc func(context.Context, string) (bool, error)

func (EmergencyAccessRevocationResolverFunc) EmergencyAccessRevoked added in v0.45.0

func (f EmergencyAccessRevocationResolverFunc) EmergencyAccessRevoked(ctx context.Context, grantID string) (bool, error)

type EmergencyAccessRevoker added in v0.45.0

type EmergencyAccessRevoker interface {
	RevokeEmergencyAccess(context.Context, string, string) error
}

type EmergencyAccessRevokerFunc added in v0.45.0

type EmergencyAccessRevokerFunc func(context.Context, string, string) error

func (EmergencyAccessRevokerFunc) RevokeEmergencyAccess added in v0.45.0

func (f EmergencyAccessRevokerFunc) RevokeEmergencyAccess(ctx context.Context, grantID, reason string) error

type EmergencyCredentialVerification added in v0.45.0

type EmergencyCredentialVerification struct {
	GrantID         string
	GrantVersion    string
	ActorID         string
	CredentialClass string
}

type EmergencyCredentialVerifier added in v0.45.0

type EmergencyCredentialVerifier interface {
	VerifyEmergencyCredential(
		context.Context,
		IssuedEmergencyAccessGrant,
		Secret,
	) (EmergencyCredentialVerification, error)
}

type EmergencyCredentialVerifierFunc added in v0.45.0

type EmergencyCredentialVerifierFunc func(
	context.Context,
	IssuedEmergencyAccessGrant,
	Secret,
) (EmergencyCredentialVerification, error)

func (EmergencyCredentialVerifierFunc) VerifyEmergencyCredential added in v0.45.0

type FactorLifecycle added in v0.45.0

type FactorLifecycle interface {
	ListFactors(context.Context, FactorListRequest) (ProviderFactorsResult, error)
	RemoveFactor(context.Context, FactorRemoveRequest) (ProviderOperationOutcome, error)
}

type FactorListRequest added in v0.45.0

type FactorListRequest struct {
	Operation AuthorizedOperationContext
}

type FactorRemoveRequest added in v0.45.0

type FactorRemoveRequest struct {
	Operation AuthorizedOperationContext
	FactorID  string
	// KnownState is an optional optimistic-concurrency expectation. Provider
	// implementations must derive security behavior from authoritative state.
	KnownState ProviderFactorState
	// RemainingVerifiedFactors is an optional expectation for the authoritative
	// verified-factor count. A zero value means no caller expectation.
	RemainingVerifiedFactors int
	AllowLastVerified        bool
}

type FieldsLogger added in v0.31.0

type FieldsLogger = glog.FieldsLogger

type FinalizePasswordResetHandler

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

func NewFinalizePasswordResetHandler added in v0.14.0

func NewFinalizePasswordResetHandler(repo RepositoryManager) *FinalizePasswordResetHandler

NewFinalizePasswordResetHandler creates a handler with sane defaults.

func (*FinalizePasswordResetHandler) Execute

func (*FinalizePasswordResetHandler) WithActivitySink added in v0.14.0

WithActivitySink sets the sink used to emit password reset events.

func (*FinalizePasswordResetHandler) WithFeatureGate added in v0.26.0

WithFeatureGate sets the feature gate used to authorize reset completion.

func (*FinalizePasswordResetHandler) WithLogger added in v0.14.0

WithLogger overrides the logger used by the handler.

func (*FinalizePasswordResetHandler) WithLoggerProvider added in v0.31.0

WithLoggerProvider overrides the logger provider used by the handler.

type FinalizePasswordResetMesasge

type FinalizePasswordResetMesasge struct {
	Session  string `json:"session" example:"350399bc-c095-4bdc-a59c-3352d44848e4" doc:"Reset password session token"`
	Password string `json:"password" example:"some_secret_word" doc:"Password"`
}

type FormattedLogger added in v0.31.0

type FormattedLogger = compat.FormattedLogger

func ToFormattedLogger added in v0.31.0

func ToFormattedLogger(logger Logger) FormattedLogger

ToFormattedLogger adapts a glog.Logger into a format-style logger.

type FreshnessDecision added in v0.45.0

type FreshnessDecision string
const (
	FreshnessAllowed FreshnessDecision = "allowed"
	FreshnessDenied  FreshnessDecision = "denied"
	FreshnessStepUp  FreshnessDecision = "step_up_required"
)

type FreshnessInvalidationCoordinator added in v0.45.0

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

FreshnessInvalidationCoordinator consumes normalized results only. It never calls a remote provider, and lifecycle consumption never repeats the coordinator's local-first session revocation.

func NewFreshnessInvalidationCoordinator added in v0.45.0

func NewFreshnessInvalidationCoordinator(
	cfg FreshnessInvalidationCoordinatorConfig,
) (*FreshnessInvalidationCoordinator, error)

func (*FreshnessInvalidationCoordinator) ConsumeAuthorizationVersion added in v0.45.0

func (c *FreshnessInvalidationCoordinator) ConsumeAuthorizationVersion(
	ctx context.Context,
	event AuthorizationVersionEvent,
	revokeSessions bool,
) (FreshnessInvalidationResult, error)

func (*FreshnessInvalidationCoordinator) ConsumeLifecycleResult added in v0.45.0

func (*FreshnessInvalidationCoordinator) InvalidateLifecycleFreshness added in v0.45.0

func (c *FreshnessInvalidationCoordinator) InvalidateLifecycleFreshness(
	ctx context.Context,
	request LifecycleFreshnessRequest,
) error

type FreshnessInvalidationCoordinatorConfig added in v0.45.0

type FreshnessInvalidationCoordinatorConfig struct {
	Permissions   PermissionScopeInvalidator
	AccountStates AccountStateScopeInvalidator
	Sessions      ProviderSessionScopeInvalidator
	BatchLimit    int
	ResultTTL     time.Duration
	MaxResults    int
	ActivitySink  ActivitySink
	Now           func() time.Time
}

type FreshnessInvalidationResult added in v0.45.0

type FreshnessInvalidationResult struct {
	OperationID         string
	PermissionEntries   int
	AccountStateEntries int
	ProviderSessions    int
	More                bool
	Partial             bool
	Retryable           bool
}

type FreshnessOperationPolicy added in v0.45.0

type FreshnessOperationPolicy struct {
	Operation                   string
	Risk                        OperationRisk
	RequiredPermission          string
	RequiredAssurance           AssuranceLevel
	MaxAuthenticationAge        time.Duration
	MaxAccountStateAge          time.Duration
	AllowStepUp                 bool
	RefreshOnPermissionMismatch bool
	RequireProviderSession      bool
}

type FreshnessPolicy added in v0.45.0

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

FreshnessPolicy is immutable after construction.

func NewFreshnessPolicy added in v0.45.0

func NewFreshnessPolicy(cfg FreshnessPolicyConfig) (*FreshnessPolicy, error)

func (*FreshnessPolicy) ApprovedAt added in v0.45.0

func (p *FreshnessPolicy) ApprovedAt() time.Time

func (*FreshnessPolicy) Operation added in v0.45.0

func (p *FreshnessPolicy) Operation(operation, role string) (FreshnessOperationPolicy, error)

func (*FreshnessPolicy) Owner added in v0.45.0

func (p *FreshnessPolicy) Owner() string

func (*FreshnessPolicy) PropagationTarget added in v0.45.0

func (p *FreshnessPolicy) PropagationTarget() time.Duration

type FreshnessPolicyConfig added in v0.45.0

type FreshnessPolicyConfig struct {
	Owner             string
	ApprovedAt        time.Time
	PropagationTarget time.Duration
	Operations        []FreshnessOperationPolicy
	RoleOverrides     []RoleFreshnessPolicy
}

type FreshnessReason added in v0.45.0

type FreshnessReason string
const (
	FreshnessReasonSatisfied         FreshnessReason = "satisfied"
	FreshnessReasonUnknownOperation  FreshnessReason = "unknown_operation"
	FreshnessReasonSessionInvalid    FreshnessReason = "session_invalid"
	FreshnessReasonAssurance         FreshnessReason = "assurance"
	FreshnessReasonAccountState      FreshnessReason = "account_state"
	FreshnessReasonPermissionVersion FreshnessReason = "permission_version"
	FreshnessReasonPermissionDenied  FreshnessReason = "permission_denied"
	FreshnessReasonDependencyOutage  FreshnessReason = "dependency_outage"
)

type HTTPAuthenticator

type HTTPAuthenticator interface {
	Middleware
	Login(c router.Context, payload LoginPayload) error
	Logout(c router.Context)
	SetRedirect(c router.Context)
	GetRedirect(c router.Context, def ...string) string
	GetRedirectOrDefault(c router.Context) string
	MakeClientRouteAuthErrorHandler(optionalAuth bool) func(c router.Context, err error) error
}

type HTTPAuthenticatorOption added in v0.37.0

type HTTPAuthenticatorOption func(*RouteAuthenticator) error

func WithAuthCookieTemplate added in v0.37.0

func WithAuthCookieTemplate(cookie router.Cookie) HTTPAuthenticatorOption

func WithRedirectCookieTemplate added in v0.37.0

func WithRedirectCookieTemplate(cookie router.Cookie) HTTPAuthenticatorOption

type HookErrorHandler added in v0.15.0

type HookErrorHandler func(ctx context.Context, phase TransitionHookPhase, err error, tc TransitionContext) error

HookErrorHandler handles errors surfaced by transition hooks.

type IdentifierStore added in v0.44.0

type IdentifierStore interface {
	FindUserID(ctx context.Context, provider, identifier string) (string, error)
	Upsert(ctx context.Context, userID, provider, identifier string) error
	Delete(ctx context.Context, userID, provider, identifier string) error
}

IdentifierStore maps external provider identifiers to local user IDs.

type Identity

type Identity interface {
	ID() string
	Username() string
	Email() string
	Role() string
}

Identity holds the attributes of an identity

func NewIdentityFromUser added in v0.24.0

func NewIdentityFromUser(user *User) Identity

NewIdentityFromUser returns an Identity adapter for the provided user.

type IdentityLifecycle added in v0.45.0

type IdentityLifecycle interface {
	Invite(context.Context, InviteRequest) (ProviderDeliveryOutcome, error)
	StartRecovery(context.Context, RecoveryRequest) (ProviderDeliveryOutcome, error)
}

type IdentityProvider

type IdentityProvider interface {
	VerifyIdentity(ctx context.Context, identifier, password string) (Identity, error)
	FindIdentityByIdentifier(ctx context.Context, identifier string) (Identity, error)
}

IdentityProvider ensure we have a store to retrieve auth identity

type ImmutableIdentifierStore added in v0.45.0

type ImmutableIdentifierStore interface {
	IdentifierStore
	Bind(ctx context.Context, userID, provider, identifier string) error
}

ImmutableIdentifierStore binds an external provider identifier exactly once. Repeating the same binding is idempotent; binding it to a different user must return ErrIdentifierConflict.

type InMemoryAuthorizationVersionStore added in v0.45.0

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

InMemoryAuthorizationVersionStore is a concurrency-safe reference store for tests and single-process hosts. Durable hosts should implement the same transaction boundary in their authorization database.

func NewInMemoryAuthorizationVersionStore added in v0.45.0

func NewInMemoryAuthorizationVersionStore(now func() time.Time) *InMemoryAuthorizationVersionStore

func (*InMemoryAuthorizationVersionStore) AdvanceAuthorizationVersion added in v0.45.0

func (s *InMemoryAuthorizationVersionStore) AdvanceAuthorizationVersion(
	ctx context.Context,
	applicationSubject, tenantID, operationID string,
	mutation AuthorizationMutation,
) (PermissionVersionResult, error)

func (*InMemoryAuthorizationVersionStore) CurrentAuthorizationVersion added in v0.45.0

func (s *InMemoryAuthorizationVersionStore) CurrentAuthorizationVersion(
	_ context.Context,
	applicationSubject, tenantID string,
) (PermissionVersionResult, error)

type InMemoryLifecycleOperationStore added in v0.45.0

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

InMemoryLifecycleOperationStore is an explicit development and compatibility store. It is process-local and must not be used when durable coordination is required.

func NewInMemoryLifecycleOperationStore added in v0.45.0

func NewInMemoryLifecycleOperationStore(now func() time.Time) *InMemoryLifecycleOperationStore

func (*InMemoryLifecycleOperationStore) Advance added in v0.45.0

func (*InMemoryLifecycleOperationStore) Claim added in v0.45.0

func (*InMemoryLifecycleOperationStore) ClaimPending added in v0.45.0

func (*InMemoryLifecycleOperationStore) Durable added in v0.45.0

func (*InMemoryLifecycleOperationStore) Load added in v0.45.0

type InMemoryPermissionCacheStore added in v0.33.0

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

InMemoryPermissionCacheStore is the default PermissionCacheStore implementation.

func NewInMemoryPermissionCacheStore added in v0.33.0

func NewInMemoryPermissionCacheStore(cfg InMemoryPermissionCacheStoreConfig) *InMemoryPermissionCacheStore

NewInMemoryPermissionCacheStore builds an in-memory permission cache store.

func (*InMemoryPermissionCacheStore) Delete added in v0.33.0

Delete removes a key from the store.

func (*InMemoryPermissionCacheStore) DeletePermissionCacheScope added in v0.45.0

func (s *InMemoryPermissionCacheStore) DeletePermissionCacheScope(
	_ context.Context,
	scope PermissionInvalidationScope,
	limit int,
) (int, bool, error)

func (*InMemoryPermissionCacheStore) Get added in v0.33.0

Get returns cached permissions when the key exists and has not expired.

func (*InMemoryPermissionCacheStore) IndexPermissionCacheKey added in v0.45.0

func (s *InMemoryPermissionCacheStore) IndexPermissionCacheKey(
	_ context.Context,
	key string,
	scope PermissionInvalidationScope,
) error

func (*InMemoryPermissionCacheStore) PurgeExpired added in v0.33.0

func (s *InMemoryPermissionCacheStore) PurgeExpired(_ context.Context) (int, error)

PurgeExpired removes all expired entries and returns the number of keys removed.

func (*InMemoryPermissionCacheStore) Set added in v0.33.0

func (s *InMemoryPermissionCacheStore) Set(_ context.Context, key string, permissions []string, ttl time.Duration) error

Set stores permissions for the provided key and ttl. ttl<=0 removes the key.

func (*InMemoryPermissionCacheStore) SetPermissionCacheEntry added in v0.45.0

func (s *InMemoryPermissionCacheStore) SetPermissionCacheEntry(
	_ context.Context,
	key string,
	permissions []string,
	ttl time.Duration,
	scope PermissionInvalidationScope,
) error

type InMemoryPermissionCacheStoreConfig added in v0.33.0

type InMemoryPermissionCacheStoreConfig struct {
	// PurgeInterval throttles opportunistic cleanup on writes.
	// Zero applies a sensible default.
	PurgeInterval time.Duration
	// Now can be provided in tests to control time.
	Now func() time.Time
}

InMemoryPermissionCacheStoreConfig configures the default in-memory permission cache store.

type IndexedPermissionCacheStore added in v0.45.0

type IndexedPermissionCacheStore interface {
	PermissionCacheStore
	IndexPermissionCacheKey(ctx context.Context, key string, scope PermissionInvalidationScope) error
	DeletePermissionCacheScope(ctx context.Context, scope PermissionInvalidationScope, limit int) (deleted int, more bool, err error)
}

IndexedPermissionCacheStore is the additive bounded-invalidation contract.

type InitializePasswordResetHandler

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

func NewInitializePasswordResetHandler added in v0.26.0

func NewInitializePasswordResetHandler(repo RepositoryManager) *InitializePasswordResetHandler

func (*InitializePasswordResetHandler) Execute

func (*InitializePasswordResetHandler) WithDelivery added in v0.45.0

WithDelivery configures the trusted out-of-band reset credential delivery.

func (*InitializePasswordResetHandler) WithFeatureGate added in v0.26.0

func (*InitializePasswordResetHandler) WithLogger added in v0.45.0

WithLogger overrides the logger used by the handler.

func (*InitializePasswordResetHandler) WithLoggerProvider added in v0.45.0

WithLoggerProvider overrides the logger provider used by the handler.

type InitializePasswordResetMessage

type InitializePasswordResetMessage struct {
	Stage      string `json:"stage" example:"Rone" doc:"Customer last name."`
	Session    string `json:"session" example:"350399bc-c095-4bdc-a59c-3352d44848e4" doc:"Reset password session token"`
	Email      string `json:"email" example:"pepe.rone@example.com" doc:"Customer email."`
	OnResponse func(resp *InitializePasswordResetResponse)
}

func (InitializePasswordResetMessage) Type

type InitializePasswordResetResponse

type InitializePasswordResetResponse struct {
	// Reset is retained for source compatibility. Password reset credentials
	// are never returned through command responses.
	Reset   *PasswordReset
	Stage   string
	Success bool
}

type InviteRequest added in v0.45.0

type InviteRequest struct {
	Operation AuthorizedOperationContext
	Email     string
	ReturnURL string
}

type IssuedEmergencyAccessGrant added in v0.45.0

type IssuedEmergencyAccessGrant struct {
	EmergencyAccessGrant
	Version       string
	PolicyVersion string
}

type JWTClaims added in v0.7.0

type JWTClaims struct {
	jwt.RegisteredClaims
	UID       string            `json:"uid,omitempty"`
	UserRole  string            `json:"role,omitempty"`
	Resources map[string]string `json:"res,omitempty"`      // resource -> role mapping
	Metadata  map[string]any    `json:"metadata,omitempty"` // extension payload
	Scopes    []string          `json:"scopes,omitempty"`   // optional scopes (e.g., debug tokens)
	Use       string            `json:"token_use,omitempty"`
}

JWTClaims is the concrete implementation of AuthClaims

func (*JWTClaims) CanCreate added in v0.7.0

func (c *JWTClaims) CanCreate(resource string) bool

CanCreate checks if the user can create a specific resource

func (*JWTClaims) CanDelete added in v0.7.0

func (c *JWTClaims) CanDelete(resource string) bool

CanDelete checks if the user can delete a specific resource

func (*JWTClaims) CanEdit added in v0.7.0

func (c *JWTClaims) CanEdit(resource string) bool

CanEdit checks if the user can edit a specific resource

func (*JWTClaims) CanRead added in v0.7.0

func (c *JWTClaims) CanRead(resource string) bool

CanRead checks if the user can read a specific resource

func (*JWTClaims) ClaimsMetadata added in v0.15.0

func (c *JWTClaims) ClaimsMetadata() map[string]any

ClaimsMetadata exposes metadata extensions for optional context enrichment.

func (*JWTClaims) Expires added in v0.7.0

func (c *JWTClaims) Expires() time.Time

Expires returns the expiration time

func (*JWTClaims) HasRole added in v0.7.0

func (c *JWTClaims) HasRole(role string) bool

HasRole checks if the user has a specific role (either global or for any resource)

func (*JWTClaims) IsAtLeast added in v0.7.0

func (c *JWTClaims) IsAtLeast(minRole string) bool

IsAtLeast checks if the user's role is at least the minimum required role

func (*JWTClaims) IssuedAt added in v0.7.0

func (c *JWTClaims) IssuedAt() time.Time

IssuedAt returns the issued at time

func (*JWTClaims) ResourceRoles added in v0.15.0

func (c *JWTClaims) ResourceRoles() map[string]string

ResourceRoles exposes resource-specific roles for optional context enrichment.

func (*JWTClaims) Role added in v0.7.0

func (c *JWTClaims) Role() string

Role returns the global role

func (*JWTClaims) Subject added in v0.7.0

func (c *JWTClaims) Subject() string

Subject returns the subject claim

func (*JWTClaims) TokenID added in v0.29.0

func (c *JWTClaims) TokenID() string

TokenID returns the JWT ID (jti) claim.

func (*JWTClaims) TokenUse added in v0.45.0

func (c *JWTClaims) TokenUse() string

TokenUse returns the signed token-use boundary.

func (*JWTClaims) UserID added in v0.7.0

func (c *JWTClaims) UserID() string

UserID returns the user ID

type LegacyLogger added in v0.31.0

type LegacyLogger interface {
	Debug(format string, args ...any)
	Info(format string, args ...any)
	Warn(format string, args ...any)
	Error(format string, args ...any)
}

LegacyLogger matches the historical go-auth logging contract.

type LifecycleActionPolicy added in v0.45.0

type LifecycleActionPolicy struct {
	Action                  ProviderOperationAction
	MutatesProvider         bool
	SecurityRestricting     bool
	LocalSessionEffect      ProviderSessionEffect
	LifecycleState          ProviderSessionLifecycleState
	CredentialsInvalidating bool
	FreshnessRequired       bool
	QueueSessionRevocation  bool
}

func LifecyclePolicyForAction added in v0.45.0

func LifecyclePolicyForAction(action ProviderOperationAction) (LifecycleActionPolicy, error)

type LifecycleCoordinationRequest added in v0.45.0

type LifecycleCoordinationRequest struct {
	Operation AuthorizedOperationContext
	// Deprecated: hardened coordination derives this from the action policy.
	SecurityRestricting bool
	// Deprecated: hardened coordination derives this from the action policy.
	LocalSessionEffect ProviderSessionEffect
	Remote             ProviderOperationExecutor
}

type LifecycleCoordinationResult added in v0.45.0

type LifecycleCoordinationResult struct {
	OperationID string
	Local       ProviderOperationOutcome
	Remote      ProviderOperationOutcome
	Freshness   ProviderOperationOutcome
}

type LifecycleCoordinator added in v0.45.0

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

func NewLifecycleCoordinator added in v0.45.0

func NewLifecycleCoordinator(config LifecycleCoordinatorConfig) (*LifecycleCoordinator, error)

func (*LifecycleCoordinator) Coordinate added in v0.45.0

Coordinate advances one durable operation state machine. Completed phases are loaded from the store and are never replayed.

func (*LifecycleCoordinator) ReconcileLifecycleOperation added in v0.45.0

func (c *LifecycleCoordinator) ReconcileLifecycleOperation(
	ctx context.Context,
	reconciliation LifecycleOperationReconciliation,
) (LifecycleCoordinationResult, error)

ReconcileLifecycleOperation persists an authoritative outcome for one leased pending operation, then resumes freshness and completion. It never dispatches the provider mutation.

type LifecycleCoordinatorConfig added in v0.45.0

type LifecycleCoordinatorConfig struct {
	LocalInvalidator     ProviderSessionLocalInvalidator
	LifecycleInvalidator ProviderSessionLifecycleInvalidator
	Freshness            LifecycleFreshnessInvalidator
	OperationStore       LifecycleOperationStore
	RequireDurable       bool
	RequirePermits       bool
	RemoteLease          time.Duration
	PhaseLease           time.Duration
	// Deprecated: retained for source compatibility with the previous
	// process-local result cache. Durable stores own retention.
	ResultTTL time.Duration
	// Deprecated: retained for source compatibility.
	MaxResults int
	Clock      func() time.Time
}

type LifecycleExecutionPermit added in v0.45.0

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

LifecycleExecutionPermit is an opaque, single-use capability minted only after an operation store claims one exact remote attempt. Copies share the same consumption state.

func (LifecycleExecutionPermit) Consume added in v0.45.0

Consume validates this permit against the live operation claim and consumes it before provider transport. It permits an explicitly selected in-memory store for development and compatibility use.

func (LifecycleExecutionPermit) ConsumeForHardenedMutation added in v0.45.0

func (p LifecycleExecutionPermit) ConsumeForHardenedMutation(
	ctx context.Context,
	operation AuthorizedOperationContext,
) error

ConsumeForHardenedMutation additionally requires durable operation authority. Hardened provider adapters must use this method.

func (LifecycleExecutionPermit) IdempotencyKey added in v0.45.0

func (p LifecycleExecutionPermit) IdempotencyKey() string

func (LifecycleExecutionPermit) Validate added in v0.45.0

type LifecycleFreshnessInvalidator added in v0.45.0

type LifecycleFreshnessInvalidator interface {
	InvalidateLifecycleFreshness(context.Context, LifecycleFreshnessRequest) error
}

type LifecycleFreshnessInvalidatorFunc added in v0.45.0

type LifecycleFreshnessInvalidatorFunc func(context.Context, LifecycleFreshnessRequest) error

func (LifecycleFreshnessInvalidatorFunc) InvalidateLifecycleFreshness added in v0.45.0

func (f LifecycleFreshnessInvalidatorFunc) InvalidateLifecycleFreshness(
	ctx context.Context,
	request LifecycleFreshnessRequest,
) error

type LifecycleFreshnessRequest added in v0.45.0

type LifecycleFreshnessRequest struct {
	Operation AuthorizedOperationContext
	Remote    ProviderOperationOutcome
}

type LifecycleOperationClaim added in v0.45.0

type LifecycleOperationClaim struct {
	OperationID string
	Fingerprint string
	Action      ProviderOperationAction
}

type LifecycleOperationClaimDisposition added in v0.45.0

type LifecycleOperationClaimDisposition string
const (
	LifecycleOperationClaimed  LifecycleOperationClaimDisposition = "claimed"
	LifecycleOperationExisting LifecycleOperationClaimDisposition = "existing"
)

type LifecycleOperationPendingPolicy added in v0.45.0

type LifecycleOperationPendingPolicy struct {
	Now        time.Time
	LeaseOwner string
	Lease      time.Duration
	Limit      int
}

type LifecycleOperationPhase added in v0.45.0

type LifecycleOperationPhase string
const (
	LifecyclePhasePending          LifecycleOperationPhase = "pending"
	LifecyclePhaseInFlight         LifecycleOperationPhase = "in_flight"
	LifecyclePhaseSucceeded        LifecycleOperationPhase = "succeeded"
	LifecyclePhaseFailed           LifecycleOperationPhase = "failed"
	LifecyclePhasePendingReconcile LifecycleOperationPhase = "pending_reconcile"
	LifecyclePhaseSkipped          LifecycleOperationPhase = "skipped"
)

type LifecycleOperationReconciliation added in v0.45.0

type LifecycleOperationReconciliation struct {
	Request LifecycleCoordinationRequest
	Claim   LifecycleOperationRecord
	Remote  ProviderOperationOutcome
}

LifecycleOperationReconciliation completes a pending remote phase from an authoritative provider observation. Claim must be a live record returned by LifecycleOperationStore.ClaimPending.

type LifecycleOperationRecord added in v0.45.0

type LifecycleOperationRecord struct {
	OperationID            string
	Fingerprint            string
	Action                 ProviderOperationAction
	LocalPhase             LifecycleOperationPhase
	RemotePhase            LifecycleOperationPhase
	FreshnessPhase         LifecycleOperationPhase
	Local                  ProviderOperationOutcome
	Remote                 ProviderOperationOutcome
	Freshness              ProviderOperationOutcome
	ProviderIdempotencyKey string
	LocalLeaseOwner        string
	LocalLeaseUntil        time.Time
	RemoteAttempt          int
	RemoteLeaseOwner       string
	RemoteLeaseUntil       time.Time
	FreshnessLeaseOwner    string
	FreshnessLeaseUntil    time.Time
	Revision               int64
	Completed              bool
	CreatedAt              time.Time
	UpdatedAt              time.Time
}

func (LifecycleOperationRecord) Validate added in v0.45.0

func (r LifecycleOperationRecord) Validate() error

type Logger

type Logger = glog.Logger

func EnsureLogger added in v0.31.0

func EnsureLogger(logger Logger) Logger

EnsureLogger guarantees a non-nil logger.

func FromFormattedLogger added in v0.31.0

func FromFormattedLogger(logger FormattedLogger) Logger

FromFormattedLogger adapts a format-style logger into a glog.Logger.

func FromLegacyLogger added in v0.31.0

func FromLegacyLogger(logger LegacyLogger) Logger

FromLegacyLogger adapts the historical go-auth logger into a glog.Logger.

type LoggerProvider added in v0.31.0

type LoggerProvider = glog.LoggerProvider

type LoginAttemptPolicy added in v0.45.0

type LoginAttemptPolicy struct {
	MaxAttempts int
	Window      time.Duration
}

type LoginAttemptReservation added in v0.45.0

type LoginAttemptReservation struct {
	Allowed    bool
	Attempts   int
	RecordedAt time.Time
}

type LoginPayload

type LoginPayload interface {
	GetIdentifier() string
	GetPassword() string
	GetExtendedSession() bool
}

type LoginRequest

type LoginRequest struct {
	Identifier string `form:"identifier" json:"identifier"`
	Password   string `form:"password" json:"password"`
	RememberMe bool   `form:"remember_me" json:"remember_me"`
}

LoginRequest payload

func (LoginRequest) GetExtendedSession

func (r LoginRequest) GetExtendedSession() bool

GetExtendedSession will return the password

func (LoginRequest) GetIdentifier

func (r LoginRequest) GetIdentifier() string

GetIdentifier returns the identifier

func (LoginRequest) GetPassword

func (r LoginRequest) GetPassword() string

GetPassword will return the password

func (LoginRequest) Validate

func (r LoginRequest) Validate() *errors.Error

Validate will run validation rules

type Middleware

type Middleware interface {
	Impersonate(c router.Context, identifier string) error
	ProtectedRoute(cfg Config, errorHandler func(router.Context, error) error) router.MiddlewareFunc
	ProtectedBrowserRoute(cfg Config, errorHandler func(router.Context, error) error, config ...BrowserProtectionConfig) router.MiddlewareFunc
}

type MultiTokenValidator added in v0.24.0

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

MultiTokenValidator tries validators in order until one succeeds. It treats ErrTokenMalformed as "try next" and returns the last malformed error if all validators fail.

func NewMultiTokenValidator added in v0.24.0

func NewMultiTokenValidator(validators ...TokenValidator) *MultiTokenValidator

NewMultiTokenValidator filters nil validators and returns a composite validator.

func (*MultiTokenValidator) Validate added in v0.24.0

func (m *MultiTokenValidator) Validate(tokenString string) (AuthClaims, error)

Validate satisfies the TokenValidator interface.

func (*MultiTokenValidator) ValidateSession added in v0.45.0

func (m *MultiTokenValidator) ValidateSession(tokenString string) (AuthClaims, error)

ValidateSession applies session-use enforcement to validators that expose a session-specific validation boundary while preserving external validators.

type NamedAccountStateSource added in v0.45.0

type NamedAccountStateSource struct {
	Name   string
	Source AccountStateSource
}

type OperationRisk added in v0.45.0

type OperationRisk string
const (
	OperationRiskNormalRead OperationRisk = "normal_read"
	OperationRiskPrivileged OperationRisk = "privileged"
)

type PasswordAuthenticator

type PasswordAuthenticator interface {
	HashPassword(password string) (string, error)
	ComparePasswordAndHash(password, hash string) error
}

PasswordAuthenticator authenticates passwords

type PasswordReset

type PasswordReset struct {
	bun.BaseModel `bun:"table:password_reset,alias:pwdr"`
	ID            uuid.UUID  `bun:"id,pk,nullzero,type:uuid" json:"id,omitempty"`
	UserID        *uuid.UUID `bun:"user_id,notnull" json:"user_id,omitempty"`
	User          *User      `bun:"rel:has-one,join:user_id=id" json:"user,omitempty"`
	Status        string     `bun:"status,notnull" json:"status,omitempty"`
	Email         string     `bun:"email,notnull" json:"email,omitempty"`
	DeletedAt     *time.Time `bun:"deleted_at,soft_delete,nullzero" json:"deleted_at,omitempty"`
	ResetedAt     *time.Time `bun:"reseted_at,nullzero" json:"reseted_at,omitempty"`
	CreatedAt     *time.Time `bun:"created_at,nullzero,default:current_timestamp" json:"created_at,omitempty"`
	UpdatedAt     *time.Time `bun:"updated_at,nullzero,default:current_timestamp" json:"updated_at,omitempty"`
}

PasswordReset is the user model

func MarkPasswordAsReseted

func MarkPasswordAsReseted(id uuid.UUID) *PasswordReset

MarkPasswordAsReseted will create a new instance

type PasswordResetDelivery added in v0.45.0

type PasswordResetDelivery interface {
	DeliverPasswordReset(context.Context, PasswordResetDeliveryRequest) error
}

PasswordResetDelivery delivers a password reset credential over a trusted out-of-band channel, such as email.

type PasswordResetDeliveryFunc added in v0.45.0

type PasswordResetDeliveryFunc func(context.Context, PasswordResetDeliveryRequest) error

PasswordResetDeliveryFunc adapts a function to PasswordResetDelivery.

func (PasswordResetDeliveryFunc) DeliverPasswordReset added in v0.45.0

type PasswordResetDeliveryRequest added in v0.45.0

type PasswordResetDeliveryRequest struct {
	Email     string
	Token     Secret
	ExpiresAt time.Time
}

PasswordResetDeliveryRequest contains the minimum capability required by a trusted out-of-band delivery implementation. Token is deliberately opaque so common formatting and serialization paths redact it.

type PasswordResetRequestPayload

type PasswordResetRequestPayload struct {
	Email string `form:"email" json:"email"`
	Stage string `form:"stage" json:"stage"`
}

PasswordResetRequestPayload holds values for password reset

func (PasswordResetRequestPayload) Validate

Validate will validate the payload

type PasswordResetStep

type PasswordResetStep = string

PasswordResetStep step on password reset

const (
	// ResetUnknown is the unknown status
	ResetUnknown PasswordResetStep = "unknown"
	// ResetInit is the initial step
	ResetInit PasswordResetStep = "show-reset"
	//AccountVerification notifiction sent
	AccountVerification PasswordResetStep = "email-sent"
	// ChangingPassword user will change password
	ChangingPassword PasswordResetStep = "change-password"
	// ChangeFinalized processing change
	ChangeFinalized PasswordResetStep = "password-changed"
)

type PasswordResetVerifyPayload

type PasswordResetVerifyPayload struct {
	Stage           string `form:"stage" json:"stage"`
	Password        string `form:"password" json:"password"`
	ConfirmPassword string `form:"confirm_password" json:"confirm_password"`
}

PasswordResetVerifyPayload holds values for password reset

func (PasswordResetVerifyPayload) Validate

func (r PasswordResetVerifyPayload) Validate() *errors.Error

Validate will validate the payload

type PermissionCacheErrorMode added in v0.33.0

type PermissionCacheErrorMode string

PermissionCacheErrorMode defines resolver behavior when cache store operations fail.

const (
	// PermissionCacheErrorModeFailOpen bypasses cache errors and continues resolving.
	PermissionCacheErrorModeFailOpen PermissionCacheErrorMode = "fail_open"
	// PermissionCacheErrorModeFailClosed returns cache operation errors immediately.
	PermissionCacheErrorModeFailClosed PermissionCacheErrorMode = "fail_closed"
)

type PermissionCacheKeyFunc added in v0.32.0

type PermissionCacheKeyFunc func(context.Context) (key string, ok bool)

PermissionCacheKeyFunc computes a stable cache key for a permission resolution request. Return ok=false to bypass cross-request caching.

type PermissionCacheStore added in v0.33.0

type PermissionCacheStore interface {
	Get(ctx context.Context, key string) (permissions []string, ok bool, err error)
	Set(ctx context.Context, key string, permissions []string, ttl time.Duration) error
	Delete(ctx context.Context, key string) error
}

PermissionCacheStore is the storage contract used by CachedPermissionsResolver. The interface is intentionally narrow to align with generic cache backends.

type PermissionInvalidationScope added in v0.45.0

type PermissionInvalidationScope struct {
	ApplicationSubject string
	TenantID           string
	SessionID          string
}

PermissionInvalidationScope identifies cache entries without requiring unbounded key scans. At least one dimension must be present.

type PermissionResolverFunc added in v0.32.0

type PermissionResolverFunc func(context.Context) ([]string, error)

PermissionResolverFunc resolves effective permission keys from a request context.

func (PermissionResolverFunc) ResolveCurrentPermissions added in v0.45.0

func (f PermissionResolverFunc) ResolveCurrentPermissions(
	ctx context.Context,
	request CurrentPermissionsRequest,
) ([]string, error)

ResolveCurrentPermissions resolves permissions for an authoritative version. Existing PermissionResolverFunc implementations remain source compatible and receive the normalized request through context.

type PermissionResolverStats added in v0.32.0

type PermissionResolverStats struct {
	Calls              uint64
	ResolverRuns       uint64
	CacheHits          uint64
	CacheMisses        uint64
	NoCacheCalls       uint64
	Errors             uint64
	SingleflightShared uint64
	StoreGetErrors     uint64
	StoreSetErrors     uint64
	StoreDeleteErrors  uint64
	PurgeRuns          uint64
	PurgedEntries      uint64
}

PermissionResolverStats exposes lightweight runtime counters for observability.

type PermissionScopeInvalidator added in v0.45.0

type PermissionScopeInvalidator interface {
	InvalidateScope(context.Context, PermissionInvalidationScope, int) (deleted int, more bool, err error)
}

type PermissionVersionResolver added in v0.45.0

type PermissionVersionResolver interface {
	ResolvePermissionVersion(context.Context, AuthenticatedPrincipal) (PermissionVersionResult, error)
}

type PermissionVersionResolverFunc added in v0.45.0

type PermissionVersionResolverFunc func(context.Context, AuthenticatedPrincipal) (PermissionVersionResult, error)

func (PermissionVersionResolverFunc) ResolvePermissionVersion added in v0.45.0

func (f PermissionVersionResolverFunc) ResolvePermissionVersion(
	ctx context.Context,
	principal AuthenticatedPrincipal,
) (PermissionVersionResult, error)

type PermissionVersionResult added in v0.45.0

type PermissionVersionResult struct {
	Version string
	// Role is the current host-owned authorization role from the same
	// authoritative read as Version. Freshness policy selection must never use
	// a token or request role in its place.
	Role       string
	ObservedAt time.Time
}

type PrincipalSnapshot added in v0.45.0

type PrincipalSnapshot struct {
	ApplicationSubject string
	Provider           string
	ProviderSubject    string
	ProviderSessionID  string
	LocalSessionID     string
	ClientID           string
	AssuranceLevel     string
	AssuranceMethods   []string
	AuthenticationAt   time.Time
	IssuedAt           time.Time
	ExpiresAt          time.Time
	TokenID            string
	TenantID           string
	OrganizationID     string
	PermissionVersion  string
	Metadata           map[string]string
}

PrincipalSnapshot is the non-secret persistence representation of a normalized principal.

func NewPrincipalSnapshot added in v0.45.0

func NewPrincipalSnapshot(principal AuthenticatedPrincipal) PrincipalSnapshot

func (PrincipalSnapshot) Principal added in v0.45.0

type ProviderAccountState added in v0.45.0

type ProviderAccountState string
const (
	ProviderAccountStateActive    ProviderAccountState = "active"
	ProviderAccountStateSuspended ProviderAccountState = "suspended"
	ProviderAccountStateDisabled  ProviderAccountState = "disabled"
	ProviderAccountStateUnknown   ProviderAccountState = "unknown"
)

type ProviderAuditFingerprint added in v0.45.0

type ProviderAuditFingerprint string

ProviderAuditFingerprint is a one-way correlation value safe for activity payloads. It preserves equality without retaining the source string.

func EnsureProviderAuditFingerprint added in v0.45.0

func EnsureProviderAuditFingerprint(value string) ProviderAuditFingerprint

func FingerprintProviderAuditValue added in v0.45.0

func FingerprintProviderAuditValue(value string) ProviderAuditFingerprint

FingerprintProviderAuditValue removes raw free-form values from provider lifecycle audit data. Values are always transformed; callers must retain the ProviderAuditFingerprint type instead of round-tripping it through string.

type ProviderDeliveryOutcome added in v0.45.0

type ProviderDeliveryOutcome struct {
	ProviderOperationOutcome
	Delivery ProviderDeliveryStatus
}

type ProviderDeliveryStatus added in v0.45.0

type ProviderDeliveryStatus string
const (
	ProviderDeliverySent      ProviderDeliveryStatus = "sent"
	ProviderDeliveryDuplicate ProviderDeliveryStatus = "duplicate"
	ProviderDeliveryPending   ProviderDeliveryStatus = "pending"
	ProviderDeliveryFailed    ProviderDeliveryStatus = "failed"
)

type ProviderFactor added in v0.45.0

type ProviderFactor struct {
	ID           string
	Type         ProviderFactorType
	State        ProviderFactorState
	FriendlyName string
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

type ProviderFactorState added in v0.45.0

type ProviderFactorState string
const (
	ProviderFactorVerified   ProviderFactorState = "verified"
	ProviderFactorUnverified ProviderFactorState = "unverified"
)

type ProviderFactorType added in v0.45.0

type ProviderFactorType string
const (
	ProviderFactorTOTP     ProviderFactorType = "totp"
	ProviderFactorPhone    ProviderFactorType = "phone"
	ProviderFactorWebAuthn ProviderFactorType = "webauthn"
	ProviderFactorUnknown  ProviderFactorType = "unknown"
)

type ProviderFactorsResult added in v0.45.0

type ProviderFactorsResult struct {
	ProviderOperationOutcome
	Factors []ProviderFactor
}

type ProviderOperationAction added in v0.45.0

type ProviderOperationAction string

ProviderOperationAction names a narrow provider-neutral operation. Hosts authorize these actions before invoking a provider implementation.

const (
	ProviderActionInvite               ProviderOperationAction = "identity.invite"
	ProviderActionStartRecovery        ProviderOperationAction = "identity.recovery.start"
	ProviderActionSuspend              ProviderOperationAction = "account.suspend"
	ProviderActionActivate             ProviderOperationAction = "account.activate"
	ProviderActionGetAccountState      ProviderOperationAction = "account.state.get"
	ProviderActionListFactors          ProviderOperationAction = "factor.list"
	ProviderActionRemoveFactor         ProviderOperationAction = "factor.remove"
	ProviderActionAuthorizationDetails ProviderOperationAction = "authorization.details"
	ProviderActionAuthorizationApprove ProviderOperationAction = "authorization.approve"
	ProviderActionAuthorizationDeny    ProviderOperationAction = "authorization.deny"
)

type ProviderOperationAuthorizationRequest added in v0.45.0

type ProviderOperationAuthorizationRequest struct {
	Action      ProviderOperationAction
	Permission  string
	Actor       ActorRef
	Target      ProviderOperationTarget
	Reason      string
	Environment string
	RequestID   string
}

type ProviderOperationAuthorizer added in v0.45.0

type ProviderOperationAuthorizer interface {
	AuthorizeProviderOperation(context.Context, ProviderOperationAuthorizationRequest) (AuthorizedOperationContext, error)
}

ProviderOperationAuthorizer is host-owned. Provider adapters consume the resulting proof but never decide business permissions themselves.

type ProviderOperationExecutor added in v0.45.0

type ProviderOperationExecutor interface {
	ExecuteProviderOperation(context.Context, AuthorizedOperationContext) (ProviderOperationOutcome, error)
}

type ProviderOperationExecutorFunc added in v0.45.0

type ProviderOperationExecutorFunc func(context.Context, AuthorizedOperationContext) (ProviderOperationOutcome, error)

func (ProviderOperationExecutorFunc) ExecuteProviderOperation added in v0.45.0

type ProviderOperationFingerprintContributor added in v0.45.0

type ProviderOperationFingerprintContributor interface {
	ProviderOperationFingerprintFields() []ProviderOperationFingerprintField
}

ProviderOperationFingerprintContributor is implemented by concrete executors whose request contains action inputs outside AuthorizedOperationContext.

type ProviderOperationFingerprintField added in v0.45.0

type ProviderOperationFingerprintField struct {
	Name  string
	Value string
}

ProviderOperationFingerprintField binds an action-specific executor input to the durable operation fingerprint without storing the raw input.

type ProviderOperationOutcome added in v0.45.0

type ProviderOperationOutcome struct {
	Status                ProviderOperationStatus
	Retryable             bool
	ProviderRequestID     string
	ProviderSessionEffect ProviderSessionEffect
	ResidualAccessExpires time.Time
}

func (ProviderOperationOutcome) Validate added in v0.45.0

func (o ProviderOperationOutcome) Validate() error

type ProviderOperationStatus added in v0.45.0

type ProviderOperationStatus string
const (
	ProviderOperationSucceeded       ProviderOperationStatus = "succeeded"
	ProviderOperationAlreadyComplete ProviderOperationStatus = "already_complete"
	ProviderOperationPending         ProviderOperationStatus = "pending"
	ProviderOperationUnsupported     ProviderOperationStatus = "unsupported"
	ProviderOperationConflict        ProviderOperationStatus = "conflict"
	ProviderOperationFailed          ProviderOperationStatus = "failed"
)

type ProviderOperationTarget added in v0.45.0

type ProviderOperationTarget struct {
	Provider           string
	ApplicationSubject string
	Subject            string
	ObjectID           string
}

ProviderOperationTarget identifies the provider-side object selected by an already-authorized host operation.

type ProviderProfileSyncRepository added in v0.45.0

type ProviderProfileSyncRepository interface {
	SyncProviderProfileTx(ctx context.Context, tx bun.IDB, profile *User) (*User, error)
}

ProviderProfileSyncRepository is the user-store capability required when a provider-driven sync updates an already-linked local user. Implementations must update provider-owned profile fields only; lifecycle and authorization fields remain under their dedicated state/version writers.

type ProviderRefreshClaim added in v0.45.0

type ProviderRefreshClaim struct {
	Session   ProviderSession
	Tokens    TokenEnvelope
	AttemptID string
	Acquired  bool
}

type ProviderRefreshCommit added in v0.45.0

type ProviderRefreshCommit struct {
	SessionID        string
	AttemptID        string
	BaseRevision     int64
	Tokens           TokenEnvelope
	AccessExpiresAt  time.Time
	RefreshExpiresAt time.Time
}

type ProviderRefreshReconcileRequest added in v0.45.0

type ProviderRefreshReconcileRequest struct {
	Session      ProviderSession
	AttemptID    string
	BaseRevision int64
}

type ProviderRefreshReconcileResult added in v0.45.0

type ProviderRefreshReconcileResult struct {
	Status ProviderRefreshReconcileStatus
	Tokens ProviderTokenSet
}

type ProviderRefreshReconcileStatus added in v0.45.0

type ProviderRefreshReconcileStatus string
const (
	ProviderRefreshReconciledTokens  ProviderRefreshReconcileStatus = "tokens"
	ProviderRefreshReconciledRevoked ProviderRefreshReconcileStatus = "revoked"
	ProviderRefreshReconcileUnknown  ProviderRefreshReconcileStatus = "unknown"
)

type ProviderRefreshRequest added in v0.45.0

type ProviderRefreshRequest struct {
	Session       ProviderSession
	AttemptID     string
	RefreshToken  Secret
	CurrentTokens ProviderTokenSet
}

type ProviderRefreshResult added in v0.45.0

type ProviderRefreshResult struct {
	Tokens ProviderTokenSet
}

type ProviderRemoteRevocationClaim added in v0.45.0

type ProviderRemoteRevocationClaim struct {
	Session        ProviderSession
	Tokens         TokenEnvelope
	RemoteRevision int64
	Attempt        int
	LeaseOwner     string
	LeaseUntil     time.Time
	LeaseRemaining time.Duration
}

type ProviderRemoteRevocationClaimPolicy added in v0.45.0

type ProviderRemoteRevocationClaimPolicy struct {
	// Deprecated: repositories use their authoritative database clock.
	Now         time.Time
	WorkerID    string
	Lease       time.Duration
	BatchSize   int
	MaxAttempts int
}

type ProviderRemoteRevocationCompletion added in v0.45.0

type ProviderRemoteRevocationCompletion struct {
	SessionID      string
	RemoteRevision int64
	LeaseOwner     string
	LeaseUntil     time.Time
	Outcome        ProviderRemoteRevocationOutcome
	// Deprecated: repositories derive the next attempt from their database
	// clock and RetryDelay.
	NextAttemptAt time.Time
	RetryDelay    time.Duration
	SafeErrorCode string
	Terminal      bool
}

type ProviderRemoteRevocationOutcome added in v0.45.0

type ProviderRemoteRevocationOutcome struct {
	Status                ProviderRemoteRevocationStatus
	Retryable             bool
	ResidualAccessExpires time.Time
}

func (ProviderRemoteRevocationOutcome) Validate added in v0.45.0

type ProviderRemoteRevocationRepository added in v0.45.0

type ProviderRemoteRevocationRepository interface {
	ClaimRemoteRevocations(
		context.Context,
		ProviderRemoteRevocationClaimPolicy,
	) ([]ProviderRemoteRevocationClaim, error)
	CompleteRemoteRevocation(context.Context, ProviderRemoteRevocationCompletion) error
}

type ProviderRemoteRevocationRetryResult added in v0.45.0

type ProviderRemoteRevocationRetryResult struct {
	Claimed   int
	Succeeded int
	Retried   int
	Terminal  int
}

type ProviderRemoteRevocationStatus added in v0.45.0

type ProviderRemoteRevocationStatus string
const (
	ProviderRemoteRevocationSucceeded   ProviderRemoteRevocationStatus = "succeeded"
	ProviderRemoteRevocationPending     ProviderRemoteRevocationStatus = "pending"
	ProviderRemoteRevocationUnsupported ProviderRemoteRevocationStatus = "unsupported"
	ProviderRemoteRevocationFailed      ProviderRemoteRevocationStatus = "failed"
)

type ProviderRevocationHook added in v0.45.0

type ProviderRevocationHook interface {
	RevokeProviderSession(ctx context.Context, request ProviderRevocationRequest) (ProviderRemoteRevocationOutcome, error)
}

type ProviderRevocationRequest added in v0.45.0

type ProviderRevocationRequest struct {
	Session           ProviderSession
	Reason            string
	ReasonCode        ProviderSessionReasonCode
	ReasonFingerprint ProviderAuditFingerprint
	Tokens            ProviderTokenSet
}

type ProviderSession added in v0.45.0

type ProviderSession struct {
	ID                  string
	LocalSessionID      string
	Principal           PrincipalSnapshot
	Binding             ProviderSessionBinding
	Status              ProviderSessionStatus
	TokenRevision       int64
	CreatedAt           time.Time
	LastSeenAt          time.Time
	IdleExpiresAt       time.Time
	MaxExpiresAt        time.Time
	RefreshAttemptID    string
	RefreshBaseRevision int64
	RefreshLeaseUntil   time.Time
	RevokedAt           time.Time
	// Deprecated: contains only the typed reason code after remediation.
	RevocationReason            string
	RevocationReasonCode        ProviderSessionReasonCode
	RevocationReasonFingerprint ProviderAuditFingerprint
	RemoteRevocation            ProviderRemoteRevocationOutcome
	RemoteAttemptCount          int
	RemoteNextAttemptAt         time.Time
	RemoteLeaseOwner            string
	RemoteLeaseUntil            time.Time
	RemoteRevision              int64
	RemoteSafeErrorCode         string
	RemoteWorkExpiresAt         time.Time
	RemoteTerminalAt            time.Time
}

ProviderSession never includes the browser handle, lookup hash, or provider tokens. ID is internal; LocalSessionID is safe for audit and CSRF keys.

func (ProviderSession) LogValue added in v0.45.0

func (s ProviderSession) LogValue() slog.Value

func (ProviderSession) String added in v0.45.0

func (s ProviderSession) String() string

type ProviderSessionActivityMetadata added in v0.45.0

type ProviderSessionActivityMetadata struct {
	Result              string
	Reason              ProviderSessionReason
	RemoteStatus        ProviderRemoteRevocationStatus
	RemoteRetryable     bool
	LocalOnly           bool
	Target              string
	LifecycleGeneration int64
}

type ProviderSessionBinding added in v0.45.0

type ProviderSessionBinding struct {
	Host          string
	ApplicationID string
	Environment   string
	TenantID      string
	Provider      string
	Issuer        string
	ClientID      string
}

ProviderSessionBinding prevents an opaque browser handle from being copied between applications, environments, issuers, or OAuth clients.

func (ProviderSessionBinding) Equal added in v0.45.0

func (ProviderSessionBinding) Validate added in v0.45.0

func (b ProviderSessionBinding) Validate() error

type ProviderSessionCleanupPolicy added in v0.45.0

type ProviderSessionCleanupPolicy struct {
	Now              time.Time
	SessionRetention time.Duration
	TokenRetention   time.Duration
	BatchSize        int
}

type ProviderSessionCleanupResult added in v0.45.0

type ProviderSessionCleanupResult struct {
	StateRecords   int64
	SessionRecords int64
	TokenRecords   int64
}

type ProviderSessionContext added in v0.45.0

type ProviderSessionContext struct {
	Session   ProviderSession
	Principal AuthenticatedPrincipal
}

func ProviderSessionFromContext added in v0.45.0

func ProviderSessionFromContext(ctx context.Context) (*ProviderSessionContext, bool)

type ProviderSessionCreate added in v0.45.0

type ProviderSessionCreate struct {
	Session    ProviderSession
	LookupHash []byte
	Tokens     TokenEnvelope
}

type ProviderSessionCreation added in v0.45.0

type ProviderSessionCreation struct {
	Handle    Secret
	Session   ProviderSession
	Principal AuthenticatedPrincipal
}

type ProviderSessionCreator added in v0.45.0

type ProviderSessionCreator interface {
	CreateProviderSession(ctx context.Context, principal AuthenticatedPrincipal, tokens ProviderTokenSet) (ProviderSessionCreation, error)
}

type ProviderSessionDeployment added in v0.45.0

type ProviderSessionDeployment string
const (
	ProviderSessionDeploymentDevelopment ProviderSessionDeployment = "development"
	ProviderSessionDeploymentTest        ProviderSessionDeployment = "test"
	ProviderSessionDeploymentProduction  ProviderSessionDeployment = "production"
	ProviderSessionDeploymentHardened    ProviderSessionDeployment = "hardened"
)

func (ProviderSessionDeployment) RequiresOperations added in v0.45.0

func (d ProviderSessionDeployment) RequiresOperations() bool

func (ProviderSessionDeployment) Validate added in v0.45.0

func (d ProviderSessionDeployment) Validate() error

type ProviderSessionEffect added in v0.45.0

type ProviderSessionEffect string
const (
	ProviderSessionEffectNone       ProviderSessionEffect = "none"
	ProviderSessionEffectCurrent    ProviderSessionEffect = "current"
	ProviderSessionEffectNamed      ProviderSessionEffect = "named"
	ProviderSessionEffectAllForUser ProviderSessionEffect = "all_for_user"
)

type ProviderSessionHTTP added in v0.45.0

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

func NewProviderSessionHTTP added in v0.45.0

func NewProviderSessionHTTP(cfg ProviderSessionHTTPConfig) (*ProviderSessionHTTP, error)

func (*ProviderSessionHTTP) ClearCookie added in v0.45.0

func (h *ProviderSessionHTTP) ClearCookie(c router.Context)

func (*ProviderSessionHTTP) Middleware added in v0.45.0

func (h *ProviderSessionHTTP) Middleware() router.MiddlewareFunc

func (*ProviderSessionHTTP) RotateCookie added in v0.45.0

func (h *ProviderSessionHTTP) RotateCookie(c router.Context, manager *ProviderSessionManager) error

func (*ProviderSessionHTTP) SetCookie added in v0.45.0

func (h *ProviderSessionHTTP) SetCookie(c router.Context, handle Secret) error

type ProviderSessionHTTPConfig added in v0.45.0

type ProviderSessionHTTPConfig struct {
	Resolver       ProviderSessionResolver
	Binding        ProviderSessionBinding
	Cookie         router.Cookie
	CookieDuration time.Duration
	AllowDomain    bool
	LocalJWTCookie string
	ContextKey     string
	CSRF           csrf.Config
	Origin         router.OriginProtectionConfig
	ErrorHandler   func(router.Context, error) error
}

type ProviderSessionInvalidationScope added in v0.45.0

type ProviderSessionInvalidationScope struct {
	ApplicationSubject string
	TenantID           string
	SessionID          string
	// PermissionVersion installs a durable authorization fence for the
	// subject and tenant. New sessions whose principal snapshot does not
	// carry this exact version are rejected after the fence is committed.
	PermissionVersion string
	// PermissionVersionObservedAt orders duplicate/out-of-order events so an
	// older delivery cannot roll the durable fence backward.
	PermissionVersionObservedAt time.Time
}

type ProviderSessionLifecycleFence added in v0.45.0

type ProviderSessionLifecycleFence struct {
	ApplicationSubject   string
	TenantID             string
	BlockedState         ProviderSessionLifecycleState
	CredentialsNotBefore time.Time
	EventObservedAt      time.Time
	Generation           int64
}

ProviderSessionLifecycleFence is the observable non-secret lifecycle state.

type ProviderSessionLifecycleInvalidator added in v0.45.0

type ProviderSessionLifecycleInvalidator interface {
	ApplyProviderSessionLifecycle(
		ctx context.Context,
		transition ProviderSessionLifecycleTransition,
	) (fence ProviderSessionLifecycleFence, revoked []ProviderSession, err error)
}

type ProviderSessionLifecycleOrdering added in v0.45.0

type ProviderSessionLifecycleOrdering string
const (
	// ProviderSessionLifecycleObservedOrder preserves externally observed event
	// ordering. Older or duplicate timestamps are no-ops.
	ProviderSessionLifecycleObservedOrder ProviderSessionLifecycleOrdering = "observed"
	// ProviderSessionLifecycleRepositoryOrder serializes a locally initiated
	// transition under the durable fence lock and advances generation
	// regardless of replica wall-clock skew.
	ProviderSessionLifecycleRepositoryOrder ProviderSessionLifecycleOrdering = "repository"
)

type ProviderSessionLifecycleRepository added in v0.45.0

type ProviderSessionLifecycleRepository interface {
	AdvanceProviderSessionLifecycle(
		ctx context.Context,
		transition ProviderSessionLifecycleTransition,
	) (fence ProviderSessionLifecycleFence, revoked []ProviderSession, err error)
}

ProviderSessionLifecycleRepository is the additive durable capability used by hardened lifecycle coordination and provider-session admission.

type ProviderSessionLifecycleState added in v0.45.0

type ProviderSessionLifecycleState string

ProviderSessionLifecycleState is the durable session-admission state for one application subject and optional tenant. The empty value means "unchanged" on a transition; persisted fences always use one of the named values.

const (
	ProviderSessionLifecycleActive    ProviderSessionLifecycleState = "active"
	ProviderSessionLifecycleSuspended ProviderSessionLifecycleState = "suspended"
	ProviderSessionLifecycleDisabled  ProviderSessionLifecycleState = "disabled"
	ProviderSessionLifecycleArchived  ProviderSessionLifecycleState = "archived"
)

type ProviderSessionLifecycleTransition added in v0.45.0

type ProviderSessionLifecycleTransition struct {
	ApplicationSubject    string
	TenantID              string
	BlockedState          ProviderSessionLifecycleState
	CredentialsNotBefore  time.Time
	AdvanceCredentials    bool
	EventObservedAt       time.Time
	Reason                string
	Ordering              ProviderSessionLifecycleOrdering
	QueueRemoteRevocation bool
}

ProviderSessionLifecycleTransition advances a durable lifecycle fence. BlockedState may be empty to leave the account state unchanged. An explicit active state is the only transition that clears a prior block.

func (ProviderSessionLifecycleTransition) Validate added in v0.45.0

type ProviderSessionLocalInvalidator added in v0.45.0

type ProviderSessionLocalInvalidator interface {
	InvalidateProviderSession(ctx context.Context, sessionID, reason string) error
	InvalidateUserProviderSessions(ctx context.Context, applicationSubject, reason string) error
}

ProviderSessionLocalInvalidator makes sessions unusable without invoking a remote provider hook. Lifecycle coordinators use this boundary before their one provider-specific mutation.

type ProviderSessionManager added in v0.45.0

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

func NewProviderSessionManager added in v0.45.0

func NewProviderSessionManager(cfg ProviderSessionManagerConfig) (*ProviderSessionManager, error)

func (*ProviderSessionManager) AccessToken added in v0.45.0

func (m *ProviderSessionManager) AccessToken(ctx context.Context, request UserTokenRequest) (Secret, error)

func (*ProviderSessionManager) ApplyProviderSessionLifecycle added in v0.45.0

func (*ProviderSessionManager) CreateProviderSession added in v0.45.0

func (*ProviderSessionManager) InvalidateProviderSession added in v0.45.0

func (m *ProviderSessionManager) InvalidateProviderSession(ctx context.Context, sessionID, reason string) error

func (*ProviderSessionManager) InvalidateProviderSessions added in v0.45.0

func (m *ProviderSessionManager) InvalidateProviderSessions(
	ctx context.Context,
	scope ProviderSessionInvalidationScope,
	limit int,
	reason string,
) (int, bool, error)

func (*ProviderSessionManager) InvalidateUserProviderSessions added in v0.45.0

func (m *ProviderSessionManager) InvalidateUserProviderSessions(ctx context.Context, applicationSubject, reason string) error

func (*ProviderSessionManager) ReencryptProviderSession added in v0.45.0

func (m *ProviderSessionManager) ReencryptProviderSession(ctx context.Context, handle Secret, binding ProviderSessionBinding) (ProviderSession, error)

func (*ProviderSessionManager) RefreshProviderSession added in v0.45.0

func (m *ProviderSessionManager) RefreshProviderSession(ctx context.Context, handle Secret, binding ProviderSessionBinding) (ProviderSession, error)

func (*ProviderSessionManager) ResolveProviderSession added in v0.45.0

func (*ProviderSessionManager) RetryRemoteRevocations added in v0.45.0

RetryRemoteRevocations executes already-locally-revoked remote work claimed through a bounded durable lease. It never changes local session usability.

func (*ProviderSessionManager) RevokeCurrentProviderSession added in v0.45.0

func (m *ProviderSessionManager) RevokeCurrentProviderSession(ctx context.Context, handle Secret, binding ProviderSessionBinding, reason string) error

func (*ProviderSessionManager) RevokeProviderSession added in v0.45.0

func (m *ProviderSessionManager) RevokeProviderSession(ctx context.Context, sessionID, reason string) error

func (*ProviderSessionManager) RevokeUserProviderSessions added in v0.45.0

func (m *ProviderSessionManager) RevokeUserProviderSessions(ctx context.Context, applicationSubject, reason string) error

func (*ProviderSessionManager) RotateProviderSessionHandle added in v0.45.0

func (m *ProviderSessionManager) RotateProviderSessionHandle(ctx context.Context, handle Secret, binding ProviderSessionBinding) (Secret, ProviderSession, error)

type ProviderSessionManagerConfig added in v0.45.0

type ProviderSessionManagerConfig struct {
	Repository     ProviderSessionRepository
	Cipher         TokenCipher
	Binding        ProviderSessionBinding
	IdleLifetime   time.Duration
	MaxLifetime    time.Duration
	TouchInterval  time.Duration
	RefreshLease   time.Duration
	Refresher      ProviderTokenRefresher
	Reconciler     ProviderTokenReconciler
	RevocationHook ProviderRevocationHook
	TargetRegistry *TokenTargetRegistry
	AccessPolicy   TokenAccessPolicy
	ActivitySink   ActivitySink
	Deployment     ProviderSessionDeployment
	Operations     *ProviderSessionOperationsConfig
}

type ProviderSessionOperationsConfig added in v0.45.0

type ProviderSessionOperationsConfig struct {
	Environment              string
	PostgresOwner            string
	EncryptionKeySource      string
	KeyRotationOwner         string
	ActiveKeyPolicy          string
	RetiredKeyPolicy         string
	CookiePolicyOwner        string
	IdleLifetime             time.Duration
	MaxLifetime              time.Duration
	StateRetention           time.Duration
	SessionRetention         time.Duration
	TokenRetention           time.Duration
	CleanupSchedule          string
	CleanupOwner             string
	MonitoringOwner          string
	OutagePolicy             string
	EmergencyRevocationOwner string
	EmergencyProcedure       string
}

ProviderSessionOperationsConfig is the production enablement gate. Values are intentionally supplied by the host/deployment rather than guessed by this library.

func (ProviderSessionOperationsConfig) Validate added in v0.45.0

func (c ProviderSessionOperationsConfig) Validate(binding ProviderSessionBinding, idle, maximum time.Duration) error

type ProviderSessionReason added in v0.45.0

type ProviderSessionReason struct {
	Code              ProviderSessionReasonCode
	DetailFingerprint ProviderAuditFingerprint
}

func NewProviderSessionReason added in v0.45.0

func NewProviderSessionReason(
	code ProviderSessionReasonCode,
	detail string,
) (ProviderSessionReason, error)

func ParseProviderSessionReason added in v0.45.0

func ParseProviderSessionReason(value string) ProviderSessionReason

func ProviderSessionReasonFromLegacy added in v0.45.0

func ProviderSessionReasonFromLegacy(detail string) ProviderSessionReason

type ProviderSessionReasonCode added in v0.45.0

type ProviderSessionReasonCode string
const (
	ProviderSessionReasonLogout               ProviderSessionReasonCode = "logout"
	ProviderSessionReasonAccountSuspended     ProviderSessionReasonCode = "account_suspended"
	ProviderSessionReasonFactorChanged        ProviderSessionReasonCode = "factor_changed"
	ProviderSessionReasonAuthorizationChange  ProviderSessionReasonCode = "authorization_changed"
	ProviderSessionReasonAdministrativeRevoke ProviderSessionReasonCode = "administrative_revoke"
	ProviderSessionReasonExpired              ProviderSessionReasonCode = "expired"
	ProviderSessionReasonRefreshUncertain     ProviderSessionReasonCode = "refresh_uncertain"
	ProviderSessionReasonLegacyExternal       ProviderSessionReasonCode = "legacy_external"
)

func (ProviderSessionReasonCode) Valid added in v0.45.0

func (c ProviderSessionReasonCode) Valid() bool

type ProviderSessionRepository added in v0.45.0

type ProviderSessionRepository interface {
	Create(ctx context.Context, input ProviderSessionCreate) (ProviderSession, error)
	Resolve(ctx context.Context, lookupHash []byte, binding ProviderSessionBinding, touchInterval time.Duration) (ProviderSessionResolution, error)
	Load(ctx context.Context, sessionID string) (ProviderSessionResolution, error)
	RotateHandle(ctx context.Context, sessionID string, expectedRevision int64, oldLookupHash, newLookupHash []byte) (ProviderSession, error)
	ClaimRefresh(ctx context.Context, sessionID string, expectedRevision int64, attemptID string, lease time.Duration) (ProviderRefreshClaim, error)
	CommitRefresh(ctx context.Context, input ProviderRefreshCommit) (ProviderSession, error)
	MarkRefreshUncertain(ctx context.Context, sessionID, attemptID string, baseRevision int64, reason string) error
	ReplaceCiphertext(ctx context.Context, sessionID string, expectedRevision int64, tokens TokenEnvelope) (ProviderSession, error)
	Revoke(ctx context.Context, sessionID, reason string) (ProviderSession, bool, error)
	RevokeUser(ctx context.Context, applicationSubject, reason string) ([]ProviderSession, error)
	UpdateRemoteRevocation(ctx context.Context, sessionID string, outcome ProviderRemoteRevocationOutcome) error
	Cleanup(ctx context.Context, policy ProviderSessionCleanupPolicy) (ProviderSessionCleanupResult, error)
}

ProviderSessionRepository is the composite atomic persistence boundary. Implementations must use database-authoritative time for transitions.

type ProviderSessionResolution added in v0.45.0

type ProviderSessionResolution struct {
	Session ProviderSession
	Tokens  TokenEnvelope
}

type ProviderSessionResolver added in v0.45.0

type ProviderSessionResolver interface {
	ResolveProviderSession(ctx context.Context, handle Secret, binding ProviderSessionBinding) (ProviderSession, AuthenticatedPrincipal, error)
}

type ProviderSessionRevoker added in v0.45.0

type ProviderSessionRevoker interface {
	RevokeCurrentProviderSession(ctx context.Context, handle Secret, binding ProviderSessionBinding, reason string) error
	RevokeProviderSession(ctx context.Context, sessionID, reason string) error
	RevokeUserProviderSessions(ctx context.Context, applicationSubject, reason string) error
}

type ProviderSessionScopeInvalidator added in v0.45.0

type ProviderSessionScopeInvalidator interface {
	InvalidateProviderSessions(
		ctx context.Context,
		scope ProviderSessionInvalidationScope,
		limit int,
		reason string,
	) (invalidated int, more bool, err error)
}

type ProviderSessionScopeRepository added in v0.45.0

type ProviderSessionScopeRepository interface {
	RevokeScope(
		ctx context.Context,
		scope ProviderSessionInvalidationScope,
		limit int,
		reason string,
	) (sessions []ProviderSession, more bool, err error)
}

type ProviderSessionStatus added in v0.45.0

type ProviderSessionStatus string
const (
	ProviderSessionAvailable  ProviderSessionStatus = "available"
	ProviderSessionRefreshing ProviderSessionStatus = "refreshing"
	ProviderSessionUncertain  ProviderSessionStatus = "uncertain"
	ProviderSessionRevoked    ProviderSessionStatus = "revoked"
	ProviderSessionExpired    ProviderSessionStatus = "expired"
)

func (ProviderSessionStatus) Usable added in v0.45.0

func (s ProviderSessionStatus) Usable() bool

type ProviderSessionStore added in v0.45.0

type ProviderSessionStore interface {
	Resolve(ctx context.Context, lookupHash []byte, binding ProviderSessionBinding, touchInterval time.Duration) (ProviderSessionResolution, error)
}

Logical views deliberately omit create/commit operations. They are useful for narrow consumers while the manager retains the composite repository.

type ProviderTokenReconciler added in v0.45.0

type ProviderTokenReconciler interface {
	ReconcileProviderRefresh(ctx context.Context, request ProviderRefreshReconcileRequest) (ProviderRefreshReconcileResult, error)
}

type ProviderTokenRefresher added in v0.45.0

type ProviderTokenRefresher interface {
	RefreshProviderTokens(ctx context.Context, request ProviderRefreshRequest) (ProviderRefreshResult, error)
}

type ProviderTokenSet added in v0.45.0

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

ProviderTokenSet keeps provider credentials opaque and non-serializable.

func NewProviderTokenSet added in v0.45.0

func NewProviderTokenSet(input ProviderTokenSetInput) (ProviderTokenSet, error)

func (ProviderTokenSet) AccessContext added in v0.45.0

func (s ProviderTokenSet) AccessContext() (ValidatedTokenContext, bool)

func (ProviderTokenSet) AccessExpiresAt added in v0.45.0

func (s ProviderTokenSet) AccessExpiresAt() time.Time

func (ProviderTokenSet) AccessToken added in v0.45.0

func (s ProviderTokenSet) AccessToken() Secret

func (ProviderTokenSet) AcquiredAt added in v0.45.0

func (s ProviderTokenSet) AcquiredAt() time.Time

func (ProviderTokenSet) Format added in v0.45.0

func (s ProviderTokenSet) Format(state fmt.State, _ rune)

func (ProviderTokenSet) GoString added in v0.45.0

func (s ProviderTokenSet) GoString() string

func (ProviderTokenSet) IDContext added in v0.45.0

func (s ProviderTokenSet) IDContext() (ValidatedTokenContext, bool)

func (ProviderTokenSet) IDExpiresAt added in v0.45.0

func (s ProviderTokenSet) IDExpiresAt() time.Time

func (ProviderTokenSet) IDToken added in v0.45.0

func (s ProviderTokenSet) IDToken() Secret

func (ProviderTokenSet) LogValue added in v0.45.0

func (s ProviderTokenSet) LogValue() slog.Value

func (ProviderTokenSet) MarshalJSON added in v0.45.0

func (s ProviderTokenSet) MarshalJSON() ([]byte, error)

func (ProviderTokenSet) MarshalText added in v0.45.0

func (s ProviderTokenSet) MarshalText() ([]byte, error)

func (ProviderTokenSet) Metadata added in v0.45.0

func (s ProviderTokenSet) Metadata() map[string]string

func (ProviderTokenSet) RefreshExpiresAt added in v0.45.0

func (s ProviderTokenSet) RefreshExpiresAt() time.Time

func (ProviderTokenSet) RefreshToken added in v0.45.0

func (s ProviderTokenSet) RefreshToken() Secret

func (ProviderTokenSet) Scopes added in v0.45.0

func (s ProviderTokenSet) Scopes() []string

func (ProviderTokenSet) String added in v0.45.0

func (s ProviderTokenSet) String() string

func (ProviderTokenSet) TokenType added in v0.45.0

func (s ProviderTokenSet) TokenType() string

type ProviderTokenSetInput added in v0.45.0

type ProviderTokenSetInput struct {
	AccessToken      Secret
	RefreshToken     Secret
	IDToken          Secret
	TokenType        string
	Scopes           []string
	AcquiredAt       time.Time
	AccessExpiresAt  time.Time
	RefreshExpiresAt time.Time
	IDExpiresAt      time.Time
	IDContext        *ValidatedTokenContext
	AccessContext    *ValidatedTokenContext
	Metadata         map[string]string
}

ProviderTokenSetInput is the construction boundary for a provider token set.

type ProviderTokenVault added in v0.45.0

type ProviderTokenVault interface {
	ClaimRefresh(ctx context.Context, sessionID string, expectedRevision int64, attemptID string, lease time.Duration) (ProviderRefreshClaim, error)
	CommitRefresh(ctx context.Context, input ProviderRefreshCommit) (ProviderSession, error)
	MarkRefreshUncertain(ctx context.Context, sessionID, attemptID string, baseRevision int64, reason string) error
	ReplaceCiphertext(ctx context.Context, sessionID string, expectedRevision int64, tokens TokenEnvelope) (ProviderSession, error)
}

type ProviderUserSession added in v0.45.0

type ProviderUserSession struct {
	SessionHandle Secret
	Binding       ProviderSessionBinding
	Principal     AuthenticatedPrincipal
	TokenTarget   string
	Capability    TokenTargetCapability
}

ProviderUserSession identifies the validated central provider session whose user token may be resolved internally. It cannot carry a raw token.

func (ProviderUserSession) Validate added in v0.45.0

func (s ProviderUserSession) Validate(provider, environment string, now time.Time) error

type PurgeablePermissionCacheStore added in v0.33.0

type PurgeablePermissionCacheStore interface {
	PurgeExpired(ctx context.Context) (purged int, err error)
}

PurgeablePermissionCacheStore optionally supports active cleanup of expired keys. Implementations backed by Redis can ignore this capability.

type RecoveryRequest added in v0.45.0

type RecoveryRequest struct {
	Operation AuthorizedOperationContext
	Email     string
	ReturnURL string
}

type RegisterUserHandler

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

Test handlers

func NewRegisterUserHandler added in v0.26.0

func NewRegisterUserHandler(repo RepositoryManager) *RegisterUserHandler

func (*RegisterUserHandler) Execute

func (*RegisterUserHandler) WithFeatureGate added in v0.26.0

func (h *RegisterUserHandler) WithFeatureGate(featureGate gate.FeatureGate) *RegisterUserHandler

type RegisterUserMessage

type RegisterUserMessage struct {
	FirstName string `json:"first_name"`
	LastName  string `json:"last_name"`
	Username  string `json:"username"`
	Email     string `json:"email"`
	Phone     string `json:"phone"`
	Role      string `json:"role"`
	Password  string `json:"password"`
	UseHashid bool
}

func (RegisterUserMessage) Type

func (e RegisterUserMessage) Type() string

type RegistrationCreatePayload

type RegistrationCreatePayload struct {
	FirstName       string `form:"first_name" json:"first_name"`
	LastName        string `form:"last_name" json:"last_name"`
	Email           string `form:"email" json:"email"`
	Phone           string `form:"phone_number" json:"phone_number"`
	Password        string `form:"password" json:"password"`
	ConfirmPassword string `form:"confirm_password" json:"confirm_password"`
}

RegistrationCreatePayload is the form paylaod

func (RegistrationCreatePayload) Validate

func (r RegistrationCreatePayload) Validate() *errors.Error

Validate will validate the payload

type RepositoryManager

type RepositoryManager interface {
	repository.Validator
	repository.TransactionManager
	Users() Users
	PasswordResets() repository.Repository[*PasswordReset]
}

RepositoryManager exposes all repositories

func NewRepositoryManager

func NewRepositoryManager(db *bun.DB) RepositoryManager

type ResourceRoleProvider added in v0.7.0

type ResourceRoleProvider interface {
	FindResourceRoles(ctx context.Context, identity Identity) (map[string]string, error)
}

ResourceRoleProvider is an optional interface for fetching resource-specific roles. If provided to an Auther, it will be used to embed fine-grained permissions into the JWT, upgrading it to a structured claims format.

type RoleCapableSession added in v0.7.0

type RoleCapableSession interface {
	Session // Embed the existing Session interface

	// CanRead checks if the role can read a specific resource
	CanRead(resource string) bool

	// CanEdit checks if the role can edit a specific resource
	CanEdit(resource string) bool

	// CanCreate checks if the role can create a specific resource
	CanCreate(resource string) bool

	// CanDelete checks if the role can delete a specific resource
	CanDelete(resource string) bool

	// HasRole checks if the user has a specific role
	HasRole(role string) bool

	// IsAtLeast checks if the user's role is at least the minimum required role
	IsAtLeast(minRole UserRole) bool
}

RoleCapableSession extends Session with role-based access control capabilities

type RoleFreshnessPolicy added in v0.45.0

type RoleFreshnessPolicy struct {
	Role   string
	Policy FreshnessOperationPolicy
}

type RoleValidator added in v0.7.0

type RoleValidator interface {
	// CanRead checks if the role can read a specific resource
	CanRead(resource string) bool

	// CanEdit checks if the role can edit a specific resource
	CanEdit(resource string) bool

	// CanCreate checks if the role can create a specific resource
	CanCreate(resource string) bool

	// CanDelete checks if the role can delete a specific resource
	CanDelete(resource string) bool

	// HasRole checks if the user has a specific role
	HasRole(role string) bool

	// IsAtLeast checks if the user's role is at least the minimum required role
	IsAtLeast(minRole UserRole) bool
}

RoleValidator defines the interface for role-based access control validation

type RouteAuthenticationMode added in v0.45.0

type RouteAuthenticationMode string
const (
	RouteAuthenticationProviderSession RouteAuthenticationMode = "provider_session"
	RouteAuthenticationLocalJWT        RouteAuthenticationMode = "local_jwt"
	RouteAuthenticationBearer          RouteAuthenticationMode = "bearer"
)

type RouteAuthenticator

type RouteAuthenticator struct {
	AuthErrorHandler func(c router.Context, err error) error // TODO: make functions
	ErrorHandler     func(c router.Context, err error) error // TODO: make functions
	// contains filtered or unexported fields
}

func NewHTTPAuthenticator

func NewHTTPAuthenticator(auther Authenticator, cfg Config, opts ...HTTPAuthenticatorOption) (*RouteAuthenticator, error)

func (*RouteAuthenticator) AuthCookieName added in v0.40.0

func (a *RouteAuthenticator) AuthCookieName() string

func (RouteAuthenticator) GetCookieDuration

func (a RouteAuthenticator) GetCookieDuration() time.Duration

func (RouteAuthenticator) GetExtendedCookieDuration

func (a RouteAuthenticator) GetExtendedCookieDuration() time.Duration

func (*RouteAuthenticator) GetRedirect

func (a *RouteAuthenticator) GetRedirect(ctx router.Context, def ...string) string

func (*RouteAuthenticator) GetRedirectOrDefault

func (a *RouteAuthenticator) GetRedirectOrDefault(ctx router.Context) string

func (*RouteAuthenticator) Impersonate

func (a *RouteAuthenticator) Impersonate(c router.Context, identifier string) error

func (*RouteAuthenticator) Login

func (a *RouteAuthenticator) Login(ctx router.Context, payload LoginPayload) error

func (*RouteAuthenticator) Logout

func (a *RouteAuthenticator) Logout(ctx router.Context)

func (*RouteAuthenticator) MakeClientRouteAuthErrorHandler

func (a *RouteAuthenticator) MakeClientRouteAuthErrorHandler(optional bool) func(router.Context, error) error

func (*RouteAuthenticator) ProtectedBrowserRoute added in v0.37.0

func (a *RouteAuthenticator) ProtectedBrowserRoute(cfg Config, errorHandler func(router.Context, error) error, config ...BrowserProtectionConfig) router.MiddlewareFunc

func (*RouteAuthenticator) ProtectedRoute

func (a *RouteAuthenticator) ProtectedRoute(cfg Config, errorHandler func(router.Context, error) error) router.MiddlewareFunc

func (*RouteAuthenticator) SetAuthCookie added in v0.44.0

func (a *RouteAuthenticator) SetAuthCookie(ctx router.Context, token string, opts ...AuthCookieOption) error

SetAuthCookie writes the normal go-auth browser session cookie for a token minted outside the password-login handler, such as an OIDC SSO callback.

func (*RouteAuthenticator) SetRedirect

func (a *RouteAuthenticator) SetRedirect(ctx router.Context)

func (*RouteAuthenticator) WithLogger added in v0.4.0

func (a *RouteAuthenticator) WithLogger(l Logger) *RouteAuthenticator

func (*RouteAuthenticator) WithLoggerProvider added in v0.31.0

func (a *RouteAuthenticator) WithLoggerProvider(provider LoggerProvider) *RouteAuthenticator

WithLoggerProvider overrides the logger provider used by the HTTP authenticator.

func (*RouteAuthenticator) WithValidationListeners added in v0.15.0

func (a *RouteAuthenticator) WithValidationListeners(listeners ...ValidationListener) *RouteAuthenticator

WithValidationListeners registers callbacks invoked immediately after token validation.

type RouteCredentialConfig added in v0.45.0

type RouteCredentialConfig struct {
	Mode                  RouteAuthenticationMode
	ProviderSessionCookie string
	LocalJWTCookie        string
	ErrorHandler          func(router.Context, error) error
}

type ScopedTokenOptions added in v0.29.0

type ScopedTokenOptions struct {
	// TTL overrides the default token expiration. Zero uses TokenService defaults.
	TTL time.Duration
	// Issuer overrides the default issuer if provided.
	Issuer string
	// Audience overrides the default audience if provided.
	Audience []string
	// IssuedAt overrides the issuance time. Zero uses time.Now().
	IssuedAt time.Time
	// Scopes sets the optional scopes claim on the minted token.
	Scopes []string
}

ScopedTokenOptions controls how MintScopedToken issues short-lived tokens.

type Secret added in v0.45.0

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

Secret is an opaque secret value. It must be explicitly revealed by trusted server-side code and fails closed when passed to common serializers.

func NewSecret added in v0.45.0

func NewSecret(value string) Secret

func (Secret) Format added in v0.45.0

func (s Secret) Format(state fmt.State, _ rune)

func (Secret) GoString added in v0.45.0

func (s Secret) GoString() string

func (Secret) IsZero added in v0.45.0

func (s Secret) IsZero() bool

func (Secret) LogValue added in v0.45.0

func (s Secret) LogValue() slog.Value

func (Secret) MarshalJSON added in v0.45.0

func (s Secret) MarshalJSON() ([]byte, error)

func (Secret) MarshalText added in v0.45.0

func (s Secret) MarshalText() ([]byte, error)

func (Secret) Reveal added in v0.45.0

func (s Secret) Reveal() string

func (Secret) String added in v0.45.0

func (s Secret) String() string

func (*Secret) UnmarshalText added in v0.45.0

func (s *Secret) UnmarshalText([]byte) error

type Session

type Session interface {
	GetUserID() string
	GetUserUUID() (uuid.UUID, error)
	GetAudience() []string
	GetIssuer() string
	GetIssuedAt() *time.Time
	GetData() map[string]any
}

Session holds attributes that are part of an auth session

type SessionObject

type SessionObject struct {
	UserID         string         `json:"user_id,omitempty"`
	Audience       []string       `json:"audience,omitempty"`
	Issuer         string         `json:"issuer,omitempty"`
	IssuedAt       *time.Time     `json:"issued_at,omitempty"`
	ExpirationDate *time.Time     `json:"expiration_date,omitempty"`
	Data           map[string]any `json:"data,omitempty"`
}

func GetRouterSession

func GetRouterSession(c router.Context, key string) (*SessionObject, error)

func (*SessionObject) CanCreate added in v0.7.0

func (s *SessionObject) CanCreate(resource string) bool

CanCreate checks if the role can create a specific resource

func (*SessionObject) CanDelete added in v0.7.0

func (s *SessionObject) CanDelete(resource string) bool

CanDelete checks if the role can delete a specific resource

func (*SessionObject) CanEdit added in v0.7.0

func (s *SessionObject) CanEdit(resource string) bool

CanEdit checks if the role can edit a specific resource

func (*SessionObject) CanRead added in v0.7.0

func (s *SessionObject) CanRead(resource string) bool

CanRead checks if the role can read a specific resource

func (*SessionObject) GetAudience

func (s *SessionObject) GetAudience() []string

func (*SessionObject) GetData

func (s *SessionObject) GetData() map[string]any

func (*SessionObject) GetIssuedAt

func (s *SessionObject) GetIssuedAt() *time.Time

func (*SessionObject) GetIssuer

func (s *SessionObject) GetIssuer() string

func (*SessionObject) GetUserID

func (s *SessionObject) GetUserID() string

func (*SessionObject) GetUserUUID

func (s *SessionObject) GetUserUUID() (uuid.UUID, error)

func (*SessionObject) HasRole added in v0.7.0

func (s *SessionObject) HasRole(role string) bool

HasRole checks if the user has a specific role

func (*SessionObject) IsAtLeast added in v0.7.0

func (s *SessionObject) IsAtLeast(minRole UserRole) bool

IsAtLeast checks if the user's role is at least the minimum required role

func (SessionObject) String

func (s SessionObject) String() string

type StateMachineOption added in v0.14.0

type StateMachineOption func(*userStateMachine)

StateMachineOption customizes state machine construction.

func WithStateMachineActivitySink added in v0.14.0

func WithStateMachineActivitySink(sink ActivitySink) StateMachineOption

WithStateMachineActivitySink sets the ActivitySink used to publish lifecycle events.

func WithStateMachineClock added in v0.14.0

func WithStateMachineClock(clock func() time.Time) StateMachineOption

WithStateMachineClock injects a custom clock (useful for tests).

func WithStateMachineHookErrorHandler added in v0.15.0

func WithStateMachineHookErrorHandler(handler HookErrorHandler) StateMachineOption

WithStateMachineHookErrorHandler overrides how hook failures are propagated. Provide a handler to convert hook errors into domain-specific responses, otherwise the default handler panics with guidance for developers.

func WithStateMachineLogger added in v0.14.0

func WithStateMachineLogger(logger Logger) StateMachineOption

WithStateMachineLogger overrides the logger used for sink failures.

func WithStateMachineLoggerProvider added in v0.31.0

func WithStateMachineLoggerProvider(provider LoggerProvider) StateMachineOption

WithStateMachineLoggerProvider overrides the logger provider used by the state machine.

type StateStoreMaintenance added in v0.45.0

type StateStoreMaintenance interface {
	CleanupExpired(ctx context.Context, before time.Time, limit int) (int64, error)
}

type StaticTokenKeyProvider added in v0.45.0

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

func NewStaticTokenKeyProvider added in v0.45.0

func NewStaticTokenKeyProvider(activeID string, keys ...TokenEncryptionKey) (*StaticTokenKeyProvider, error)

func (*StaticTokenKeyProvider) ActiveKey added in v0.45.0

func (*StaticTokenKeyProvider) Key added in v0.45.0

func (*StaticTokenKeyProvider) Retire added in v0.45.0

func (p *StaticTokenKeyProvider) Retire(keyID string) error

func (*StaticTokenKeyProvider) Rotate added in v0.45.0

type StatusAwareIdentity added in v0.45.0

type StatusAwareIdentity interface {
	Status() UserStatus
}

StatusAwareIdentity is implemented by identities that expose an account lifecycle status. Identity implementations that predate lifecycle support remain compatible and are treated as active.

type StatusUpdateOption added in v0.14.0

type StatusUpdateOption func(*User)

StatusUpdateOption allows callers to mutate the user record before persisting status changes.

func WithSuspendedAt added in v0.14.0

func WithSuspendedAt(at *time.Time) StatusUpdateOption

WithSuspendedAt sets the SuspendedAt timestamp during a status transition.

type StorePermissionVersionResolver added in v0.45.0

type StorePermissionVersionResolver struct {
	Store AuthorizationVersionStore
}

StorePermissionVersionResolver reads the current host-owned version.

func (StorePermissionVersionResolver) ResolvePermissionVersion added in v0.45.0

func (r StorePermissionVersionResolver) ResolvePermissionVersion(
	ctx context.Context,
	principal AuthenticatedPrincipal,
) (PermissionVersionResult, error)

type TemporaryPasswordResetRepository added in v0.42.0

type TemporaryPasswordResetRepository interface {
	ResetPasswordAndClearTemporaryPassword(ctx context.Context, id uuid.UUID, passwordHash string) error
	ResetPasswordAndClearTemporaryPasswordTx(ctx context.Context, tx bun.IDB, id uuid.UUID, passwordHash string) error
}

TemporaryPasswordResetRepository is an optional user repository capability for replacing a password hash and clearing temporary-password metadata together.

type TemporaryPasswordState added in v0.41.0

type TemporaryPasswordState struct {
	Temporary      bool
	ChangeRequired bool
	IssuedAt       time.Time
	ExpiresAt      time.Time
}

TemporaryPasswordState is the normalized state carried in user metadata.

func TemporaryPasswordStateFromMetadata added in v0.41.0

func TemporaryPasswordStateFromMetadata(metadata map[string]any) TemporaryPasswordState

TemporaryPasswordStateFromMetadata extracts temporary-password state from user metadata.

func (TemporaryPasswordState) Expired added in v0.41.0

func (s TemporaryPasswordState) Expired(now time.Time) bool

Expired reports whether the temporary password is past its expiry at the provided time.

type TokenAccessPolicy added in v0.45.0

type TokenAccessPolicy interface {
	AuthorizeProviderToken(ctx context.Context, request TokenAccessPolicyRequest) error
}

type TokenAccessPolicyRequest added in v0.45.0

type TokenAccessPolicyRequest struct {
	Session ProviderSession
	Target  TokenTarget
}

type TokenCipher added in v0.45.0

type TokenCipher interface {
	Seal(ctx context.Context, plaintext []byte, associatedData []byte) (TokenEnvelope, error)
	Open(ctx context.Context, envelope TokenEnvelope, associatedData []byte) ([]byte, error)
}

type TokenEncryptionKey added in v0.45.0

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

func NewTokenEncryptionKey added in v0.45.0

func NewTokenEncryptionKey(id string, material []byte, retired bool) (TokenEncryptionKey, error)

func (TokenEncryptionKey) Format added in v0.45.0

func (k TokenEncryptionKey) Format(state fmt.State, _ rune)

func (TokenEncryptionKey) GoString added in v0.45.0

func (k TokenEncryptionKey) GoString() string

func (TokenEncryptionKey) ID added in v0.45.0

func (k TokenEncryptionKey) ID() string

func (TokenEncryptionKey) LogValue added in v0.45.0

func (k TokenEncryptionKey) LogValue() slog.Value

func (TokenEncryptionKey) MarshalJSON added in v0.45.0

func (k TokenEncryptionKey) MarshalJSON() ([]byte, error)

func (TokenEncryptionKey) Material added in v0.45.0

func (k TokenEncryptionKey) Material() []byte

func (TokenEncryptionKey) Retired added in v0.45.0

func (k TokenEncryptionKey) Retired() bool

func (TokenEncryptionKey) String added in v0.45.0

func (k TokenEncryptionKey) String() string

type TokenEnvelope added in v0.45.0

type TokenEnvelope struct {
	Version    uint8
	Algorithm  string
	KeyID      string
	Nonce      []byte
	Ciphertext []byte
}

func (TokenEnvelope) Format added in v0.45.0

func (e TokenEnvelope) Format(state fmt.State, _ rune)

func (TokenEnvelope) GoString added in v0.45.0

func (e TokenEnvelope) GoString() string

func (TokenEnvelope) LogValue added in v0.45.0

func (e TokenEnvelope) LogValue() slog.Value

func (TokenEnvelope) MarshalJSON added in v0.45.0

func (e TokenEnvelope) MarshalJSON() ([]byte, error)

func (TokenEnvelope) String added in v0.45.0

func (e TokenEnvelope) String() string

type TokenIDer added in v0.29.0

type TokenIDer interface {
	TokenID() string
}

TokenIDer is an optional interface for claims that expose a token ID (jti).

type TokenKeyProvider added in v0.45.0

type TokenKeyProvider interface {
	ActiveKey(ctx context.Context) (TokenEncryptionKey, error)
	Key(ctx context.Context, keyID string) (TokenEncryptionKey, error)
}

type TokenService added in v0.7.0

type TokenService interface {
	// Generate creates a new JWT token for the given identity with resource-specific roles
	Generate(identity Identity, resourceRoles map[string]string) (string, error)

	// SignClaims validates required claims, assigns jti/token_use when needed,
	// and signs the provided custom claims.
	SignClaims(claims *JWTClaims) (string, error)

	// Validate parses and validates a token string, returning structured claims
	Validate(tokenString string) (AuthClaims, error)
}

TokenService provides transport-agnostic JWT operations

func NewTokenService added in v0.7.0

func NewTokenService(signingKey []byte, tokenExpiration int, issuer string, audience jwt.ClaimStrings, logger Logger, opts ...TokenServiceOption) TokenService

NewTokenService is the compatibility constructor. Invalid configuration produces a fail-closed service whose signing and validation methods return the configuration error. New code should use NewValidatedTokenService.

type TokenServiceAdapter added in v0.7.0

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

TokenServiceAdapter adapts TokenValidator to jwtware.TokenValidator interface

func NewTokenServiceAdapter added in v0.11.0

func NewTokenServiceAdapter(tokenValidator TokenValidator) *TokenServiceAdapter

NewTokenServiceAdapter creates a new TokenServiceAdapter

func (*TokenServiceAdapter) Validate added in v0.7.0

func (tsa *TokenServiceAdapter) Validate(tokenString string) (jwtware.AuthClaims, error)

Validate implements the jwtware.TokenValidator interface

type TokenServiceImpl added in v0.7.0

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

TokenServiceImpl implements the TokenService interface

func NewValidatedTokenService added in v0.45.0

func NewValidatedTokenService(signingKey []byte, tokenExpiration int, issuer string, audience jwt.ClaimStrings, logger Logger, opts ...TokenServiceOption) (*TokenServiceImpl, error)

NewValidatedTokenService creates a token service only when all signing and registered-claim trust-boundary requirements are configured.

func (*TokenServiceImpl) Generate added in v0.7.0

func (ts *TokenServiceImpl) Generate(identity Identity, resourceRoles map[string]string) (string, error)

Generate creates a JWT token with resource specific roles

func (*TokenServiceImpl) SignClaims added in v0.14.0

func (ts *TokenServiceImpl) SignClaims(claims *JWTClaims) (string, error)

SignClaims signs arbitrary JWT claims using the configured signing key.

func (*TokenServiceImpl) SignClaimsWithType added in v0.34.0

func (ts *TokenServiceImpl) SignClaimsWithType(claims *JWTClaims, tokenType string) (string, error)

SignClaimsWithType signs claims and annotates guardrail logs/errors with the provided token type.

func (*TokenServiceImpl) Stats added in v0.34.0

func (ts *TokenServiceImpl) Stats() TokenServiceStats

Stats returns runtime counters for token signing guardrails.

func (*TokenServiceImpl) Validate added in v0.7.0

func (ts *TokenServiceImpl) Validate(tokenString string) (AuthClaims, error)

Validate parses and validates a token string, returning structured claims

func (*TokenServiceImpl) ValidateSession added in v0.45.0

func (ts *TokenServiceImpl) ValidateSession(tokenString string) (AuthClaims, error)

ValidateSession validates a token and additionally requires session use.

type TokenServiceOption added in v0.34.0

type TokenServiceOption func(*TokenServiceImpl)

TokenServiceOption customizes TokenService behavior without changing the TokenService interface.

func WithClaimsMetadataStripKeys added in v0.34.0

func WithClaimsMetadataStripKeys(keys ...string) TokenServiceOption

WithClaimsMetadataStripKeys overrides the metadata keys that are removed by default minimization. Matching is case-insensitive and normalizes "-" to "_".

func WithTokenSizeGuardrails added in v0.34.0

func WithTokenSizeGuardrails(warnThresholdBytes, hardLimitBytes int) TokenServiceOption

WithTokenSizeGuardrails overrides warning and hard-limit thresholds for signed JWT size. Values <= 0 disable the respective threshold.

type TokenServiceStats added in v0.34.0

type TokenServiceStats struct {
	SignedTokens   uint64
	SizeWarnings   uint64
	SizeRejections uint64
}

TokenServiceStats exposes runtime counters for token signing operations.

type TokenTarget added in v0.45.0

type TokenTarget struct {
	Name           string
	Provider       string
	Issuer         string
	ClientID       string
	Audience       string
	Resource       string
	RequiredScopes []string
	TelemetryName  string
	RequirePolicy  bool
	Capability     TokenTargetCapability
}

type TokenTargetCapability added in v0.45.0

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

func NewTokenTargetCapability added in v0.45.0

func NewTokenTargetCapability() (TokenTargetCapability, error)

func (TokenTargetCapability) Format added in v0.45.0

func (c TokenTargetCapability) Format(state fmt.State, _ rune)

func (TokenTargetCapability) GoString added in v0.45.0

func (c TokenTargetCapability) GoString() string

func (TokenTargetCapability) MarshalJSON added in v0.45.0

func (c TokenTargetCapability) MarshalJSON() ([]byte, error)

func (TokenTargetCapability) String added in v0.45.0

func (c TokenTargetCapability) String() string

type TokenTargetRegistry added in v0.45.0

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

func NewTokenTargetRegistry added in v0.45.0

func NewTokenTargetRegistry(targets ...TokenTarget) (*TokenTargetRegistry, error)

func (*TokenTargetRegistry) Resolve added in v0.45.0

func (r *TokenTargetRegistry) Resolve(name string, capability TokenTargetCapability) (TokenTarget, error)

type TokenUseClaimer added in v0.45.0

type TokenUseClaimer interface {
	TokenUse() string
}

TokenUseClaimer is implemented by claims that identify the trust boundary in which the token may be used.

type TokenValidator added in v0.24.0

type TokenValidator interface {
	Validate(tokenString string) (AuthClaims, error)
}

TokenValidator validates tokens and extracts claims without tying callers to a specific signing implementation.

type TokenValidatorFunc added in v0.24.0

type TokenValidatorFunc func(tokenString string) (AuthClaims, error)

TokenValidatorFunc adapts a function into a TokenValidator.

func (TokenValidatorFunc) Validate added in v0.24.0

func (f TokenValidatorFunc) Validate(tokenString string) (AuthClaims, error)

Validate satisfies the TokenValidator interface.

type TransactionalIdentifierStore added in v0.45.0

type TransactionalIdentifierStore interface {
	ImmutableIdentifierStore
	CreateUserAndBind(ctx context.Context, users Users, user *User, provider, identifier string) (*User, error)
}

TransactionalIdentifierStore can create a user and bind its external identifier in one database transaction.

type TransactionalIdentifierSyncStore added in v0.45.0

type TransactionalIdentifierSyncStore interface {
	ImmutableIdentifierStore
	UpsertUserAndBind(ctx context.Context, users Users, user *User, provider, identifier string) (*User, error)
}

TransactionalIdentifierSyncStore can upsert provider-owned local profile data and preserve its immutable external binding in one transaction. Provider-driven sync must require this capability because compensating an update cannot safely reconstruct the previous user record.

type TransitionContext added in v0.14.0

type TransitionContext struct {
	Actor ActorRef
	User  *User
	From  UserStatus
	To    UserStatus
	Meta  TransitionMetadata
}

TransitionContext is passed into hooks for additional processing.

type TransitionHook added in v0.14.0

type TransitionHook func(ctx context.Context, tc TransitionContext) error

TransitionHook is executed before or after a transition.

type TransitionHookPhase added in v0.15.0

type TransitionHookPhase string

TransitionHookPhase identifies whether a hook ran before or after persistence.

const (
	HookPhaseBefore TransitionHookPhase = "before_transition"
	HookPhaseAfter  TransitionHookPhase = "after_transition"
)

type TransitionMetadata added in v0.14.0

type TransitionMetadata struct {
	Reason   string
	Metadata map[string]any
}

TransitionMetadata captures extra context for a transition.

type TransitionOption added in v0.14.0

type TransitionOption func(*transitionOptions)

TransitionOption customizes state machine behavior.

func WithAfterTransitionHook added in v0.14.0

func WithAfterTransitionHook(h TransitionHook) TransitionOption

WithAfterTransitionHook adds a hook executed after the status update succeeds.

func WithBeforeTransitionHook added in v0.14.0

func WithBeforeTransitionHook(h TransitionHook) TransitionOption

WithBeforeTransitionHook adds a hook executed before the status update.

func WithForceTransition added in v0.14.0

func WithForceTransition() TransitionOption

WithForceTransition bypasses validation rules (use sparingly).

func WithSuspensionTime added in v0.14.0

func WithSuspensionTime(t time.Time) TransitionOption

WithSuspensionTime overrides the timestamp recorded when entering the suspended state.

func WithTransitionMetadata added in v0.14.0

func WithTransitionMetadata(metadata map[string]any) TransitionOption

WithTransitionMetadata merges metadata into the transition context.

func WithTransitionReason added in v0.14.0

func WithTransitionReason(reason string) TransitionOption

WithTransitionReason sets the human-readable reason for the transition.

type User

type User struct {
	bun.BaseModel      `bun:"table:users,alias:usr"`
	ID                 uuid.UUID      `bun:"id,pk,nullzero,type:uuid" json:"id,omitempty"`
	Role               UserRole       `bun:"user_role,notnull" json:"user_role,omitempty"`
	Status             UserStatus     `bun:"status,notnull,default:'active'" json:"status,omitempty"`
	FirstName          string         `bun:"first_name,notnull" json:"first_name,omitempty"`
	LastName           string         `bun:"last_name,notnull" json:"last_name,omitempty"`
	Username           string         `bun:"username,notnull,unique" json:"username,omitempty"`
	ProfilePicture     string         `bun:"profile_picture" json:"profile_picture,omitempty"`
	Email              string         `bun:"email,notnull,unique" json:"email,omitempty"`
	ExternalID         string         `bun:"external_id,nullzero" json:"external_id,omitempty"`
	ExternalIDProvider string         `bun:"external_id_provider,nullzero" json:"external_id_provider,omitempty"`
	Phone              string         `bun:"phone_number" json:"phone_number,omitempty"`
	PasswordHash       string         `bun:"password_hash" json:"password_hash,omitempty"`
	EmailValidated     bool           `bun:"is_email_verified" json:"is_email_verified,omitempty"`
	LoginAttempts      int            `bun:"login_attempts" json:"login_attempts,omitempty"`
	LoginAttemptAt     *time.Time     `bun:"login_attempt_at" json:"login_attempt_at,omitempty"`
	LoggedInAt         *time.Time     `bun:"loggedin_at" json:"loggedin_at,omitempty"`
	SuspendedAt        *time.Time     `bun:"suspended_at,nullzero" json:"suspended_at,omitempty"`
	Metadata           map[string]any `bun:"metadata" json:"metadata,omitempty"`
	ResetedAt          *time.Time     `bun:"reseted_at,nullzero" json:"reseted_at,omitempty"`
	CreatedAt          *time.Time     `bun:"created_at,nullzero,default:current_timestamp" json:"created_at,omitempty"`
	UpdatedAt          *time.Time     `bun:"updated_at,nullzero,default:current_timestamp" json:"updated_at,omitempty"`
	DeletedAt          *time.Time     `bun:"deleted_at,soft_delete,nullzero" json:"deleted_at,omitempty"`
}

User is the user model

func FromContext added in v0.4.0

func FromContext(ctx context.Context) (*User, bool)

FromContext finds the user from the context.

func (*User) AddMetadata

func (u *User) AddMetadata(key string, val any) *User

AddMetadata will append information to a metadata attribute TODO: make a trigger to merge metadata in database! https://stackoverflow.com/a/42954907/125083

func (*User) EnsureStatus added in v0.14.0

func (u *User) EnsureStatus() *User

EnsureStatus sets a default status when empty to keep DB constraints satisfied.

func (*User) HasStatus added in v0.14.0

func (u *User) HasStatus(status UserStatus) bool

HasStatus reports whether the user is currently in the provided status.

func (*User) IsActive added in v0.14.0

func (u *User) IsActive() bool

IsActive returns true when the user is marked active.

func (*User) IsArchived added in v0.14.0

func (u *User) IsArchived() bool

IsArchived returns true when the user is archived.

func (*User) IsDisabled added in v0.14.0

func (u *User) IsDisabled() bool

IsDisabled returns true when the user is disabled.

func (*User) IsPending added in v0.14.0

func (u *User) IsPending() bool

IsPending returns true when the user is pending activation.

func (*User) IsSuspended added in v0.14.0

func (u *User) IsSuspended() bool

IsSuspended returns true when the user is suspended.

type UserIdentity added in v0.24.0

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

UserIdentity adapts a User into the Identity interface for token generation.

func (UserIdentity) Email added in v0.24.0

func (u UserIdentity) Email() string

Email returns the user's email address.

func (UserIdentity) ID added in v0.24.0

func (u UserIdentity) ID() string

ID returns the user's ID as a string.

func (UserIdentity) Metadata added in v0.41.0

func (u UserIdentity) Metadata() map[string]any

Metadata returns a copy of user metadata that is safe for auth decorators.

func (UserIdentity) Role added in v0.24.0

func (u UserIdentity) Role() string

Role returns the user's role as a string.

func (UserIdentity) Status added in v0.24.0

func (u UserIdentity) Status() UserStatus

Status returns the user's lifecycle status.

func (UserIdentity) Username added in v0.24.0

func (u UserIdentity) Username() string

Username returns the user's username.

type UserProvider

type UserProvider struct {
	Validator func(*User) error
	// contains filtered or unexported fields
}

UserProvider handles users

func NewUserProvider

func NewUserProvider(store UserTracker) *UserProvider

NewUserProvider will create a new UserProvider

func (UserProvider) FindIdentityByIdentifier

func (u UserProvider) FindIdentityByIdentifier(ctx context.Context, identfier string) (Identity, error)

func (UserProvider) VerifyIdentity

func (u UserProvider) VerifyIdentity(ctx context.Context, identifier, password string) (Identity, error)

VerifyIdentity will find the user, compare to the password, and return identity

func (*UserProvider) WithLogger added in v0.4.0

func (u *UserProvider) WithLogger(l Logger) *UserProvider

func (*UserProvider) WithLoggerProvider added in v0.31.0

func (u *UserProvider) WithLoggerProvider(provider LoggerProvider) *UserProvider

WithLoggerProvider overrides the logger provider used by the user provider.

func (*UserProvider) WithLoginAttemptPolicy added in v0.45.0

func (u *UserProvider) WithLoginAttemptPolicy(policy LoginAttemptPolicy) *UserProvider

type UserRole

type UserRole string

UserRole is the user's role

const (
	// RoleGuest is an guest role (ie. view)
	RoleGuest UserRole = "guest"
	// RoleMember us a member (i.e. view, edit)
	RoleMember UserRole = "member"
	// RoleAdmin is an admin role (i.e. view, edit, create)
	RoleAdmin UserRole = "admin"
	// RoleOwner is an admin role (i.e. view, edit, create, delete)
	RoleOwner UserRole = "owner"
)

func GetAllRoles added in v0.7.0

func GetAllRoles() []UserRole

GetAllRoles returns all predefined roles in hierarchical order

func ParseRole added in v0.7.0

func ParseRole(roleStr string) (UserRole, bool)

ParseRole safely parses a string into a UserRole type

func (UserRole) CanCreate added in v0.7.0

func (r UserRole) CanCreate() bool

CanCreate checks if this role can create resources

func (UserRole) CanDelete added in v0.7.0

func (r UserRole) CanDelete() bool

CanDelete checks if this role can delete resources

func (UserRole) CanEdit added in v0.7.0

func (r UserRole) CanEdit() bool

CanEdit checks if this role can edit resources

func (UserRole) CanRead added in v0.7.0

func (r UserRole) CanRead() bool

CanRead checks if this role can read resources

func (UserRole) IsAtLeast added in v0.7.0

func (r UserRole) IsAtLeast(minRole UserRole) bool

IsAtLeast checks if this role meets the minimum required level

func (UserRole) IsValid added in v0.7.0

func (r UserRole) IsValid() bool

IsValid checks if the role is one of the predefined valid roles

type UserStateMachine added in v0.14.0

type UserStateMachine interface {
	Transition(ctx context.Context, actor ActorRef, user *User, target UserStatus, opts ...TransitionOption) (*User, error)
	CurrentStatus(user *User) UserStatus
}

UserStateMachine defines lifecycle operations for users.

func NewUserStateMachine added in v0.14.0

func NewUserStateMachine(users Users, opts ...StateMachineOption) UserStateMachine

NewUserStateMachine returns the default implementation backed by the provided repository.

type UserStatus added in v0.14.0

type UserStatus string

UserStatus represents lifecycle states for a user account

const (
	// UserStatusPending indicates the account exists but is not yet active
	UserStatusPending UserStatus = "pending"
	// UserStatusActive represents a fully active account
	UserStatusActive UserStatus = "active"
	// UserStatusSuspended indicates temporary suspension
	UserStatusSuspended UserStatus = "suspended"
	// UserStatusDisabled indicates manual disablement with no path back to active except admin intervention
	UserStatusDisabled UserStatus = "disabled"
	// UserStatusArchived signals the record should be treated as deleted/read-only
	UserStatusArchived UserStatus = "archived"
)

func EnsureIdentityActive added in v0.45.0

func EnsureIdentityActive(identity Identity) (UserStatus, error)

EnsureIdentityActive applies the provider-neutral account lifecycle gate used by every authentication flow before issuing or handing off a session.

type UserTokenProvider added in v0.45.0

type UserTokenProvider interface {
	AccessToken(ctx context.Context, request UserTokenRequest) (Secret, error)
}

type UserTokenRequest added in v0.45.0

type UserTokenRequest struct {
	SessionHandle Secret
	Binding       ProviderSessionBinding
	Target        string
	Capability    TokenTargetCapability
}

type UserTracker

type UserTracker interface {
	GetByIdentifier(ctx context.Context, identifier string) (*User, error)
	TrackAttemptedLogin(ctx context.Context, user *User) error
	TrackSucccessfulLogin(ctx context.Context, user *User) error
}

UserTracker is a store we can use to retrieve users

type Users

type Users interface {
	repository.Repository[*User]

	TrackAttemptedLogin(ctx context.Context, user *User) error
	TrackAttemptedLoginTx(ctx context.Context, tx bun.IDB, user *User) error
	TrackSucccessfulLogin(ctx context.Context, user *User) error
	TrackSucccessfulLoginTx(ctx context.Context, tx bun.IDB, user *User) error

	Register(ctx context.Context, user *User) (*User, error)
	RegisterTx(ctx context.Context, tx bun.IDB, user *User) (*User, error)
	GetOrRegisterTx(ctx context.Context, tx bun.IDB, record *User) (*User, error)
	GetOrCreate(ctx context.Context, record *User) (*User, error)
	GetOrCreateTx(ctx context.Context, tx bun.IDB, record *User) (*User, error)
	Create(ctx context.Context, record *User, criteria ...repository.InsertCriteria) (*User, error)
	CreateTx(ctx context.Context, tx bun.IDB, record *User, criteria ...repository.InsertCriteria) (*User, error)
	Upsert(ctx context.Context, record *User, criteria ...repository.UpdateCriteria) (*User, error)
	UpsertTx(ctx context.Context, tx bun.IDB, record *User, criteria ...repository.UpdateCriteria) (*User, error)
	UpdateStatus(ctx context.Context, id uuid.UUID, status UserStatus, opts ...StatusUpdateOption) (*User, error)
	UpdateStatusTx(ctx context.Context, tx bun.IDB, id uuid.UUID, status UserStatus, opts ...StatusUpdateOption) (*User, error)
	Suspend(ctx context.Context, actor ActorRef, user *User, opts ...TransitionOption) (*User, error)
	Reinstate(ctx context.Context, actor ActorRef, user *User, opts ...TransitionOption) (*User, error)

	ResetPassword(ctx context.Context, id uuid.UUID, passwordHash string) error
	ResetPasswordTx(ctx context.Context, tx bun.IDB, id uuid.UUID, passwordHash string) error
}

func NewUsersRepository

func NewUsersRepository(db *bun.DB, opts ...UsersOption) Users

type UsersOption added in v0.14.0

type UsersOption func(*users)

func WithUsersStateMachine added in v0.14.0

func WithUsersStateMachine(sm UserStateMachine) UsersOption

func WithUsersStateMachineOptions added in v0.14.0

func WithUsersStateMachineOptions(options ...StateMachineOption) UsersOption

type ValidatedTokenContext added in v0.45.0

type ValidatedTokenContext struct {
	Issuer            string
	Subject           string
	Audiences         []string
	SessionID         string
	ClientID          string
	AssuranceLevel    string
	AssuranceMethods  []string
	AuthenticationAt  time.Time
	IssuedAt          time.Time
	ExpiresAt         time.Time
	TokenID           string
	TenantID          string
	OrganizationID    string
	PermissionVersion string
}

ValidatedTokenContext contains only independently validated, typed claims. It deliberately excludes arbitrary raw provider claim maps.

func (ValidatedTokenContext) Clone added in v0.45.0

type ValidationListener added in v0.23.0

type ValidationListener = jwtware.ValidationListener

ValidationListener aliases the jwtware listener so consumers can use auth helpers directly.

type WSAuthClaimsAdapter added in v0.9.0

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

WSAuthClaimsAdapter adapts go-auth AuthClaims to go-router's WSAuthClaims interface

func (*WSAuthClaimsAdapter) CanCreate added in v0.9.0

func (w *WSAuthClaimsAdapter) CanCreate(resource string) bool

CanCreate checks if the user can create a specific resource

func (*WSAuthClaimsAdapter) CanDelete added in v0.9.0

func (w *WSAuthClaimsAdapter) CanDelete(resource string) bool

CanDelete checks if the user can delete a specific resource

func (*WSAuthClaimsAdapter) CanEdit added in v0.9.0

func (w *WSAuthClaimsAdapter) CanEdit(resource string) bool

CanEdit checks if the user can edit a specific resource

func (*WSAuthClaimsAdapter) CanRead added in v0.9.0

func (w *WSAuthClaimsAdapter) CanRead(resource string) bool

CanRead checks if the user can read a specific resource

func (*WSAuthClaimsAdapter) HasRole added in v0.9.0

func (w *WSAuthClaimsAdapter) HasRole(role string) bool

HasRole checks if the user has a specific role

func (*WSAuthClaimsAdapter) IsAtLeast added in v0.9.0

func (w *WSAuthClaimsAdapter) IsAtLeast(minRole string) bool

IsAtLeast checks if the user's role is at least the minimum required role

func (*WSAuthClaimsAdapter) Role added in v0.9.0

func (w *WSAuthClaimsAdapter) Role() string

Role returns the user's role

func (*WSAuthClaimsAdapter) Subject added in v0.9.0

func (w *WSAuthClaimsAdapter) Subject() string

Subject returns the subject claim

func (*WSAuthClaimsAdapter) UserID added in v0.9.0

func (w *WSAuthClaimsAdapter) UserID() string

UserID returns the user ID

type WSTokenValidator added in v0.9.0

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

WSTokenValidator implements go-router's WSTokenValidator interface using the go-auth TokenValidator for seamless WebSocket authentication

func NewWSTokenValidator added in v0.9.0

func NewWSTokenValidator(tokenValidator TokenValidator) *WSTokenValidator

NewWSTokenValidator creates a new WebSocket token validator using the provided TokenValidator

func (*WSTokenValidator) Validate added in v0.9.0

func (w *WSTokenValidator) Validate(tokenString string) (router.WSAuthClaims, error)

Validate validates a token string and returns WebSocket-compatible auth claims

Directories

Path Synopsis
Package activitymap provides helpers to normalize auth activity events into transport-agnostic records for external activity systems.
Package activitymap provides helpers to normalize auth activity events into transport-agnostic records for external activity systems.
adapters
featuregate module
goadmin module
middleware
provider
auth0
Package auth0 provides Auth0 JWT validation and claims mapping for go-auth.
Package auth0 provides Auth0 JWT validation and claims mapping for go-auth.
auth0/sync
Package sync provides optional Auth0 user synchronization helpers.
Package sync provides optional Auth0 user synchronization helpers.
oidc
Package oidc implements generic OpenID Connect support for go-auth.
Package oidc implements generic OpenID Connect support for go-auth.
oidc/preset
Package preset contains thin provider conventions for generic OIDC.
Package preset contains thin provider conventions for generic OIDC.
supabase
Package supabase integrates Supabase Auth with go-auth's hardened OIDC and provider-session boundaries.
Package supabase integrates Supabase Auth with go-auth's hardened OIDC and provider-session boundaries.
Package social provides OAuth2 social login primitives for go-auth.
Package social provides OAuth2 social login primitives for go-auth.

Jump to

Keyboard shortcuts

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