security

package
v0.8.6 Latest Latest
Warning

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

Go to latest
Published: Jan 3, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

README

Security Extension v2.0.0

The security extension provides comprehensive production-ready security features for Forge applications including session management, CSRF protection, rate limiting, password hashing, JWT authentication, CORS, API keys, audit logging, and security headers.

📘 New in v2.0.0: Added CSRF protection, rate limiting, security headers, password hashing (Argon2id/bcrypt), JWT authentication, CORS, API key authentication, and audit logging. See SECURITY_FEATURES.md for details.

Features

Core Security Features (v1.x)
  • Session Management

    • Cryptographically secure session ID generation (256-bit)
    • Multiple backend support (in-memory, Redis planned)
    • Automatic session expiration and cleanup
    • Session renewal and idle timeout
    • Multi-session management per user
    • Optional IP address and user agent tracking
  • Cookie Management

    • Secure cookie handling with security flags
    • HttpOnly (XSS prevention)
    • Secure flag (HTTPS-only)
    • SameSite attribute (CSRF protection)
    • Domain and path scoping
    • Flexible expiration control
  • Middleware

    • Automatic session loading from cookies
    • Session context injection
    • Protected route support
    • Path exclusion support
    • Metrics and logging integration
New Security Features (v2.0.0)
  • 🛡️ CSRF Protection - Token-based CSRF protection with multiple token lookup methods
  • ⏱️ Rate Limiting - Token bucket rate limiting (per-IP, per-user, custom keys)
  • 🔒 Security Headers - Comprehensive HTTP security headers (CSP, HSTS, X-Frame-Options, etc.)
  • 🔐 Password Hashing - Argon2id and bcrypt with strength checking and validation
  • 🎫 JWT Authentication - Full JWT support with multiple signing algorithms
  • 🌐 CORS - Cross-Origin Resource Sharing with wildcard and preflight support
  • 🔑 API Key Management - Cryptographic API key generation, validation, and scope management
  • 📝 Audit Logging - Security event logging with sensitive data redaction

See SECURITY_FEATURES.md for complete documentation of new features.

Installation

The security extension is included with Forge. No additional installation required.

Quick Start

package main

import (
    "context"
    "net/http"
    "time"
    
    "github.com/xraph/forge"
    "github.com/xraph/forge/extensions/security"
)

func main() {
    app := forge.New()
    
    // Register security extension
    securityExt := security.NewExtension(
        security.WithSessionStore("inmemory"),
        security.WithSessionTTL(24 * time.Hour),
        security.WithCookieSecure(true),
        security.WithCookieHttpOnly(true),
    )
    
    app.RegisterExtension(securityExt)
    app.Start(context.Background())
    
    // Get services from DI container
    var sessionStore security.SessionStore
    var cookieManager *security.CookieManager
    
    app.Container().Resolve("security.SessionStore", &sessionStore)
    app.Container().Resolve("security.CookieManager", &cookieManager)
    
    // Create session middleware
    sessionMw := security.SessionMiddleware(security.SessionMiddlewareOptions{
        Store:         sessionStore,
        CookieManager: cookieManager,
        Config: security.SessionConfig{
            CookieName: "forge_session",
            TTL:        24 * time.Hour,
            AutoRenew:  true,
        },
        Logger:  app.Logger(),
        Metrics: app.Metrics(),
    })
    
    // Apply middleware
    app.Router().Use(sessionMw)
    
    // Define routes
    app.Router().POST("/login", loginHandler(sessionStore, cookieManager))
    app.Router().GET("/profile", profileHandler)
    app.Router().POST("/logout", logoutHandler(sessionStore, cookieManager))
    
    app.ListenAndServe(":8080")
}

func loginHandler(store security.SessionStore, cm *security.CookieManager) forge.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) error {
        // Authenticate user...
        
        // Create session
        session, err := security.CreateSession(
            r.Context(),
            w,
            "user123",
            store,
            cm,
            security.SessionConfig{
                CookieName: "forge_session",
                TTL:        24 * time.Hour,
            },
            map[string]interface{}{
                "username": "admin",
                "role":     "admin",
            },
        )
        
        if err != nil {
            return err
        }
        
        return forge.JSON(w, http.StatusOK, map[string]string{
            "session_id": session.ID,
        })
    }
}

func profileHandler(w http.ResponseWriter, r *http.Request) error {
    session, ok := security.GetSession(r.Context())
    if !ok {
        return forge.JSON(w, http.StatusUnauthorized, map[string]string{"error": "unauthorized"})
    }
    
    return forge.JSON(w, http.StatusOK, map[string]interface{}{
        "user_id": session.UserID,
        "data":    session.Data,
    })
}

func logoutHandler(store security.SessionStore, cm *security.CookieManager) forge.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) error {
        if err := security.DestroySession(r.Context(), w, store, cm, "forge_session"); err != nil {
            return err
        }
        
        return forge.JSON(w, http.StatusOK, map[string]string{"message": "logged out"})
    }
}

Configuration

Programmatic Configuration
security.NewExtension(
    // General
    security.WithEnabled(true),
    
    // Session
    security.WithSessionEnabled(true),
    security.WithSessionStore("inmemory"),
    security.WithSessionCookieName("forge_session"),
    security.WithSessionTTL(24 * time.Hour),
    security.WithSessionIdleTimeout(30 * time.Minute),
    security.WithSessionAutoRenew(true),
    
    // Redis (when using Redis store)
    security.WithRedisAddress("redis://localhost:6379"),
    security.WithRedisPassword("secret"),
    security.WithRedisDB(0),
    
    // Cookie
    security.WithCookieEnabled(true),
    security.WithCookieSecure(true),
    security.WithCookieHttpOnly(true),
    security.WithCookieSameSite("lax"),
    security.WithCookiePath("/"),
    security.WithCookieDomain("example.com"),
)
File-based Configuration
# config.yaml
extensions:
  security:
    enabled: true
    
    session:
      enabled: true
      store: inmemory
      cookie_name: forge_session
      ttl: 24h
      idle_timeout: 30m
      auto_renew: true
      track_ip_address: false
      track_user_agent: false
      
      redis:
        address: redis://localhost:6379
        password: ""
        db: 0
        pool_size: 10
    
    cookie:
      enabled: true
      secure: true
      http_only: true
      same_site: lax
      path: /
      domain: ""
      max_age: 0

Session Management

Creating Sessions
session, err := security.CreateSession(
    ctx,
    w,
    userID,
    sessionStore,
    cookieManager,
    security.SessionConfig{
        CookieName: "forge_session",
        TTL:        24 * time.Hour,
    },
    map[string]interface{}{
        "role": "admin",
        "email": "[email protected]",
    },
)
Accessing Sessions
// From middleware-injected context
session, ok := security.GetSession(r.Context())
if !ok {
    // No session found
    return
}

// Or panic if session is required
session := security.MustGetSession(r.Context())
Updating Sessions
session, _ := security.GetSession(r.Context())
session.Data["last_page"] = "/dashboard"

err := security.UpdateSession(r.Context(), sessionStore, 24 * time.Hour)
Destroying Sessions
// Destroy current session
err := security.DestroySession(ctx, w, sessionStore, cookieManager, "forge_session")

// Destroy all sessions for a user
err := sessionStore.DeleteByUserID(ctx, userID)
Session Properties
type Session struct {
    ID             string                 // Unique session identifier
    UserID         string                 // User identifier
    Data           map[string]interface{} // Custom session data
    CreatedAt      time.Time             // Creation timestamp
    ExpiresAt      time.Time             // Expiration timestamp
    LastAccessedAt time.Time             // Last access timestamp
    IPAddress      string                // Client IP (optional)
    UserAgent      string                // Client user agent (optional)
}
Setting Cookies
cookieManager.SetCookie(w, "theme", "dark", &security.CookieOptions{
    Path:     "/",
    MaxAge:   7 * 24 * 60 * 60, // 7 days
    Secure:   true,
    HttpOnly: true,
    SameSite: security.SameSiteLax,
})
Getting Cookies
value, err := cookieManager.GetCookie(r, "theme")
if err == security.ErrCookieNotFound {
    // Cookie doesn't exist
}
if cookieManager.HasCookie(r, "theme") {
    // Cookie exists
}
Deleting Cookies
cookieManager.DeleteCookie(w, "theme", nil)
Getting All Cookies
cookies := cookieManager.GetAllCookies(r)
for _, cookie := range cookies {
    fmt.Println(cookie.Name, cookie.Value)
}

Middleware

Session Middleware

Automatically loads sessions from cookies and injects into request context:

sessionMw := security.SessionMiddleware(security.SessionMiddlewareOptions{
    Store:         sessionStore,
    CookieManager: cookieManager,
    Config: security.SessionConfig{
        CookieName: "forge_session",
        TTL:        24 * time.Hour,
        AutoRenew:  true,
    },
    Logger:  app.Logger(),
    Metrics: app.Metrics(),
    
    // Optional callbacks
    OnSessionCreated: func(session *security.Session) {
        log.Printf("Session created: %s", session.ID)
    },
    OnSessionExpired: func(sessionID string) {
        log.Printf("Session expired: %s", sessionID)
    },
    
    // Skip paths
    SkipPaths: []string{"/health", "/public"},
})

app.Router().Use(sessionMw)
Require Session Middleware

Protects routes by requiring a valid session:

// With handler
unauthorizedHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    forge.JSON(w, http.StatusUnauthorized, map[string]string{"error": "unauthorized"})
})

protectedRouter := app.Router().Group("/api")
protectedRouter.Use(security.RequireSession(unauthorizedHandler))

// With handler function
protectedRouter.Use(security.RequireSessionFunc(func(w http.ResponseWriter, r *http.Request) {
    forge.JSON(w, http.StatusUnauthorized, map[string]string{"error": "unauthorized"})
}))

Security Best Practices

Production Checklist
  • Use HTTPS and set Secure: true for cookies
  • Use Redis for session storage in distributed systems
  • Set appropriate session TTL and idle timeout
  • Enable HttpOnly to prevent XSS attacks
  • Use SameSite: Lax or Strict for CSRF protection
  • Implement rate limiting on login endpoints
  • Rotate session IDs after privilege elevation
  • Clear sessions on logout
  • Monitor session metrics
  • Set up session cleanup jobs for expired sessions
Session Security
security.NewExtension(
    // Enable IP tracking to detect session hijacking
    security.WithSessionTrackIPAddress(true),
    
    // Enable user agent tracking
    security.WithSessionTrackUserAgent(true),
    
    // Short TTL for sensitive operations
    security.WithSessionTTL(15 * time.Minute),
    
    // Idle timeout
    security.WithSessionIdleTimeout(5 * time.Minute),
    
    // Auto-renew on activity
    security.WithSessionAutoRenew(true),
)
security.NewExtension(
    // Always use Secure in production (requires HTTPS)
    security.WithCookieSecure(true),
    
    // Prevent JavaScript access
    security.WithCookieHttpOnly(true),
    
    // CSRF protection (use 'strict' for sensitive apps)
    security.WithCookieSameSite("lax"),
    
    // Limit cookie scope
    security.WithCookieDomain("example.com"),
    security.WithCookiePath("/api"),
)
Validation Example
// Validate session security
func validateSession(r *http.Request, session *security.Session) error {
    // Check IP address if tracking is enabled
    if session.IPAddress != "" {
        clientIP := getClientIP(r)
        if session.IPAddress != clientIP {
            return errors.New("session hijacking detected: IP mismatch")
        }
    }
    
    // Check user agent if tracking is enabled
    if session.UserAgent != "" {
        clientUA := r.UserAgent()
        if session.UserAgent != clientUA {
            return errors.New("session hijacking detected: user agent mismatch")
        }
    }
    
    return nil
}

Metrics

The extension provides comprehensive metrics:

  • security.sessions.created: Total sessions created
  • security.sessions.retrieved: Total sessions retrieved
  • security.sessions.updated: Total sessions updated
  • security.sessions.deleted: Total sessions deleted
  • security.sessions.touched: Total sessions renewed
  • security.sessions.expired: Total expired sessions
  • security.sessions.active: Current active sessions (gauge)
  • security.sessions.cleaned_up: Total sessions cleaned up
  • security.sessions.not_found: Total session not found errors
  • security.sessions.accessed: Total session accesses

Error Handling

_, err := sessionStore.Get(ctx, sessionID)
switch {
case errors.Is(err, security.ErrSessionNotFound):
    // Session doesn't exist
case errors.Is(err, security.ErrSessionExpired):
    // Session has expired
case errors.Is(err, security.ErrInvalidSession):
    // Session data is corrupted
default:
    // Other error
}

_, err = cookieManager.GetCookie(r, "name")
switch {
case errors.Is(err, security.ErrCookieNotFound):
    // Cookie doesn't exist
case errors.Is(err, security.ErrInvalidCookie):
    // Cookie data is invalid
default:
    // Other error
}

Backend Implementations

In-Memory Store

Best for development and single-instance deployments:

security.NewExtension(
    security.WithSessionStore("inmemory"),
)

Characteristics:

  • ✅ Fast access
  • ✅ No external dependencies
  • ✅ Automatic cleanup
  • ❌ Not suitable for distributed systems
  • ❌ Sessions lost on restart
Redis Store (Planned)

Best for production and distributed systems:

security.NewExtension(
    security.WithSessionStore("redis"),
    security.WithRedisAddress("redis://localhost:6379"),
    security.WithRedisPassword("secret"),
    security.WithRedisDB(0),
)

Characteristics:

  • ✅ Distributed session sharing
  • ✅ Persistent across restarts
  • ✅ Automatic expiration (TTL)
  • ✅ High performance
  • ✅ Scalable

Advanced Usage

Custom Session Store

Implement the SessionStore interface:

type CustomStore struct {
    // Your implementation
}

func (s *CustomStore) Create(ctx context.Context, session *Session, ttl time.Duration) error {
    // Implementation
}

func (s *CustomStore) Get(ctx context.Context, sessionID string) (*Session, error) {
    // Implementation
}

// ... implement other methods
Session Events
sessionMw := security.SessionMiddleware(security.SessionMiddlewareOptions{
    // ... other options
    
    OnSessionCreated: func(session *security.Session) {
        // Log to audit trail
        auditLog.Record("session.created", session.UserID, session.ID)
        
        // Send analytics event
        analytics.Track("session_start", session.UserID)
    },
    
    OnSessionExpired: func(sessionID string) {
        // Clean up resources
        cleanup.SessionExpired(sessionID)
        
        // Update metrics
        metrics.Increment("sessions.expired.total")
    },
})
Multi-Tenancy
// Store tenant ID in session
session.Data["tenant_id"] = tenantID

// Access in middleware
func tenantMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        session, ok := security.GetSession(r.Context())
        if !ok {
            http.Error(w, "Unauthorized", http.StatusUnauthorized)
            return
        }
        
        tenantID, ok := session.Data["tenant_id"].(string)
        if !ok {
            http.Error(w, "Invalid session", http.StatusBadRequest)
            return
        }
        
        // Inject tenant into context
        ctx := context.WithValue(r.Context(), "tenant_id", tenantID)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

Testing

func TestSessionMiddleware(t *testing.T) {
    // Create test components
    logger := logger.NewNoOpLogger()
    metrics := metrics.NewNoOpMetrics()
    store := security.NewInMemorySessionStore(logger, metrics)
    cookieManager := security.NewCookieManager(security.DefaultCookieOptions())
    
    // Create session
    session, _ := security.NewSession("user123", 1*time.Hour)
    store.Create(context.Background(), session, 1*time.Hour)
    
    // Create test request with session cookie
    req := httptest.NewRequest("GET", "/", nil)
    req.AddCookie(&http.Cookie{
        Name:  "forge_session",
        Value: session.ID,
    })
    
    // Create middleware
    mw := security.SessionMiddleware(security.SessionMiddlewareOptions{
        Store:         store,
        CookieManager: cookieManager,
        Config: security.SessionConfig{
            CookieName: "forge_session",
            TTL:        1 * time.Hour,
        },
        Logger:  logger,
        Metrics: metrics,
    })
    
    // Test handler
    handler := mw(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        loadedSession, ok := security.GetSession(r.Context())
        assert.True(t, ok)
        assert.Equal(t, session.ID, loadedSession.ID)
    }))
    
    // Execute
    rr := httptest.NewRecorder()
    handler.ServeHTTP(rr, req)
}

Examples

See the examples/security-example directory for a complete working example.

FAQ

Q: Should I use in-memory or Redis for sessions?

A: Use in-memory for development and single-instance deployments. Use Redis for production multi-instance deployments.

Q: How do I handle session fixation attacks?

A: Regenerate session IDs after authentication or privilege escalation:

// Delete old session
sessionStore.Delete(ctx, oldSessionID)

// Create new session
newSession, _ := security.CreateSession(ctx, w, userID, ...)

Q: How do I implement "Remember Me" functionality?

A: Use two cookies - a short-lived session cookie and a long-lived remember-me token:

// Short-lived session
security.CreateSession(ctx, w, userID, store, cm, 
    SessionConfig{TTL: 2 * time.Hour}, nil)

// Long-lived remember token
cookieManager.SetCookie(w, "remember_token", token, &CookieOptions{
    MaxAge: 30 * 24 * 60 * 60, // 30 days
    Secure: true,
    HttpOnly: true,
})

Q: How do I handle concurrent logins?

A: Store multiple sessions per user or implement single-session enforcement:

// Single session enforcement
sessionStore.DeleteByUserID(ctx, userID) // Delete existing sessions
security.CreateSession(ctx, w, userID, ...) // Create new session

References

Documentation

Index

Constants

View Source
const (
	CSPSelf          = "'self'"
	CSPNone          = "'none'"
	CSPUnsafeInline  = "'unsafe-inline'"
	CSPUnsafeEval    = "'unsafe-eval'"
	CSPStrictDynamic = "'strict-dynamic'"
	CSPData          = "data:"
	CSPBlob          = "blob:"
	CSPHTTPS         = "https:"
)

Common CSP source values.

View Source
const (
	// MaxPasswordLength is the maximum password length to prevent DoS attacks.
	MaxPasswordLength = 72 // bcrypt limitation
)

Variables

View Source
var (
	ErrAPIKeyMissing = errors.New("api key missing")
	ErrAPIKeyInvalid = errors.New("api key invalid")
	ErrAPIKeyExpired = errors.New("api key expired")
	ErrAPIKeyRevoked = errors.New("api key revoked")
)

API Key errors.

View Source
var (
	// ErrCookieNotFound is returned when a cookie is not found.
	ErrCookieNotFound = errors.New("cookie not found")
	// ErrInvalidCookie is returned when cookie data is invalid.
	ErrInvalidCookie = errors.New("invalid cookie")
)
View Source
var (
	ErrCSRFTokenMissing = errors.New("csrf token missing")
	ErrCSRFTokenInvalid = errors.New("csrf token invalid")
	ErrCSRFTokenExpired = errors.New("csrf token expired")
)

CSRF errors.

View Source
var (
	ErrJWTMissing     = errors.New("jwt token missing")
	ErrJWTInvalid     = errors.New("jwt token invalid")
	ErrJWTExpired     = errors.New("jwt token expired")
	ErrJWTNotYetValid = errors.New("jwt token not yet valid")
)

JWT errors.

View Source
var (
	ErrInvalidHash         = errors.New("invalid password hash format")
	ErrIncompatibleVersion = errors.New("incompatible argon2 version")
	ErrPasswordTooLong     = errors.New("password exceeds maximum length")
)

Password hashing errors.

View Source
var (
	// ErrSessionNotFound is returned when a session is not found.
	ErrSessionNotFound = errors.New("session not found")
	// ErrSessionExpired is returned when a session has expired.
	ErrSessionExpired = errors.New("session expired")
	// ErrInvalidSession is returned when session data is invalid.
	ErrInvalidSession = errors.New("invalid session")
)

Functions

func APIKeyMiddleware

func APIKeyMiddleware(manager *APIKeyManager) forge.Middleware

APIKeyMiddleware returns a middleware function for API key authentication.

func AuditMiddleware

func AuditMiddleware(auditLogger *AuditLogger) forge.Middleware

AuditMiddleware returns a middleware for audit logging.

func CORSMiddleware

func CORSMiddleware(manager *CORSManager) forge.Middleware

CORSMiddleware returns a middleware function for CORS handling.

func CSRFMiddleware

func CSRFMiddleware(csrf *CSRFProtection, cookieManager *CookieManager) forge.Middleware

CSRFMiddleware returns a middleware function for CSRF protection.

func ConstantTimeCompare

func ConstantTimeCompare(a, b string) bool

ConstantTimeCompare performs constant-time comparison of two strings Use this when comparing API keys to prevent timing attacks.

func DestroySession

func DestroySession(
	ctx context.Context,
	w http.ResponseWriter,
	store SessionStore,
	cookieManager *CookieManager,
	cookieName string,
) error

DestroySession destroys the session and deletes the cookie.

func GenerateRandomPassword

func GenerateRandomPassword(length int) (string, error)

GenerateRandomPassword generates a cryptographically secure random password.

func GenerateSessionID

func GenerateSessionID() (string, error)

GenerateSessionID generates a cryptographically secure session ID.

func GetCSRFToken

func GetCSRFToken(w http.ResponseWriter) (string, bool)

GetCSRFToken retrieves the CSRF token from response header (helper for templates/responses).

func HashAPIKey

func HashAPIKey(key string, hasher *PasswordHasher) (string, error)

HashAPIKey creates a hash of an API key for secure storage This allows you to store hashed keys in a database.

func JWTMiddleware

func JWTMiddleware(jwtManager *JWTManager) forge.Middleware

JWTMiddleware returns a middleware function for JWT authentication.

func LogAdminEvent

func LogAdminEvent(auditLogger *AuditLogger, ctx context.Context, eventType string, result string, userID string, action string, metadata map[string]any)

LogAdminEvent logs an administrative action.

func LogAuthEvent

func LogAuthEvent(auditLogger *AuditLogger, ctx context.Context, eventType string, result string, userID string, metadata map[string]any)

LogAuthEvent logs an authentication event.

func LogDataEvent

func LogDataEvent(auditLogger *AuditLogger, ctx context.Context, eventType string, result string, userID string, resource string, metadata map[string]any)

LogDataEvent logs a data access/modification event.

func LogSecurityEvent

func LogSecurityEvent(auditLogger *AuditLogger, ctx context.Context, eventType string, result string, message string, metadata map[string]any)

LogSecurityEvent logs a security-related event.

func NewExtensionWithConfig

func NewExtensionWithConfig(config Config) forge.Extension

NewExtensionWithConfig creates a new security extension with a complete config. This is for backward compatibility or when config is fully known at initialization.

func RateLimitMiddleware

func RateLimitMiddleware(limiter *MemoryRateLimiter) forge.Middleware

RateLimitMiddleware returns a middleware function for rate limiting.

func RequireRoles

func RequireRoles(roles ...string) forge.Middleware

RequireRoles returns a middleware that checks if the user has required roles.

func RequireScopes

func RequireScopes(scopes ...string) forge.Middleware

RequireScopes returns a middleware that checks if the API key has required scopes.

func RequireSession

func RequireSession(unauthorizedHandler forge.Handler) forge.Middleware

RequireSession creates middleware that requires a valid session.

func RequireSessionFunc

func RequireSessionFunc(unauthorizedHandler forge.Handler) forge.Middleware

RequireSessionFunc creates middleware that requires a valid session with a handler function.

func RequireSessionSimple added in v0.5.0

func RequireSessionSimple() forge.Middleware

RequireSessionSimple creates middleware that returns 401 Unauthorized if no session exists.

func SecurityHeadersMiddleware

func SecurityHeadersMiddleware(manager *SecurityHeadersManager) forge.Middleware

SecurityHeadersMiddleware returns a middleware function for setting security headers.

func SessionMiddleware

func SessionMiddleware(opts SessionMiddlewareOptions) forge.Middleware

SessionMiddleware creates middleware for session management.

func UpdateSession

func UpdateSession(
	ctx context.Context,
	store SessionStore,
	ttl time.Duration,
) error

UpdateSession updates the session data in the store.

func ValidatePassword

func ValidatePassword(password string, minLength, maxLength int, requireUpper, requireLower, requireDigit, requireSpecial bool) error

ValidatePassword validates a password against common requirements.

func VerifyAPIKeyHash

func VerifyAPIKeyHash(key, hash string, hasher *PasswordHasher) (bool, error)

VerifyAPIKeyHash verifies an API key against a hash.

Types

type APIKeyConfig

type APIKeyConfig struct {
	// Enabled determines if API key authentication is enabled
	Enabled bool

	// KeyLookup defines where to find the API key:
	// - "header:<name>" - look in header (default: "header:X-API-Key")
	// - "query:<name>" - look in query parameter
	// - "cookie:<name>" - look in cookie
	// Can specify multiple separated by comma
	KeyLookup string

	// KeyPrefix is the prefix before the key (optional)
	// Example: "ApiKey" or "Bearer"
	KeyPrefix string

	// SkipPaths is a list of paths to skip API key authentication
	SkipPaths []string

	// AutoApplyMiddleware automatically applies API key middleware globally
	AutoApplyMiddleware bool

	// ErrorHandler is called when API key validation fails
	ErrorHandler func(forge.Context, error) error

	// Validator is a custom function to validate API keys
	// If not set, uses the built-in validator
	Validator func(ctx context.Context, key string) (*APIKeyInfo, error)
}

APIKeyConfig holds API key authentication configuration.

func DefaultAPIKeyConfig

func DefaultAPIKeyConfig() APIKeyConfig

DefaultAPIKeyConfig returns the default API key configuration.

type APIKeyInfo

type APIKeyInfo struct {
	Key        string         // The API key
	Name       string         // Friendly name for the key
	UserID     string         // Associated user ID
	Scopes     []string       // Allowed scopes/permissions
	RateLimit  int            // Rate limit for this key
	ExpiresAt  *time.Time     // Expiration time (nil = never expires)
	CreatedAt  time.Time      // Creation time
	LastUsedAt *time.Time     // Last usage time
	Revoked    bool           // Whether the key is revoked
	Metadata   map[string]any // Additional metadata
}

APIKeyInfo represents information about an API key.

func GetAPIKeyInfo

func GetAPIKeyInfo(ctx forge.Context) (*APIKeyInfo, bool)

GetAPIKeyInfo retrieves API key info from Forge context.

func GetAPIKeyInfoFromStdContext added in v0.5.0

func GetAPIKeyInfoFromStdContext(ctx context.Context) (*APIKeyInfo, bool)

GetAPIKeyInfoFromStdContext retrieves API key info from standard context (for backward compatibility).

func (*APIKeyInfo) HasScope

func (info *APIKeyInfo) HasScope(scope string) bool

HasScope checks if the API key has a specific scope.

func (*APIKeyInfo) IsExpired

func (info *APIKeyInfo) IsExpired() bool

IsExpired checks if the API key is expired.

type APIKeyManager

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

APIKeyManager manages API keys.

func NewAPIKeyManager

func NewAPIKeyManager(config APIKeyConfig, logger forge.Logger) *APIKeyManager

NewAPIKeyManager creates a new API key manager.

func (*APIKeyManager) CreateAPIKey

func (m *APIKeyManager) CreateAPIKey(info *APIKeyInfo) (string, error)

CreateAPIKey creates and stores a new API key.

func (*APIKeyManager) DeleteAPIKey

func (m *APIKeyManager) DeleteAPIKey(key string)

DeleteAPIKey deletes an API key.

func (*APIKeyManager) GenerateAPIKey

func (m *APIKeyManager) GenerateAPIKey(prefix string) (string, error)

GenerateAPIKey generates a new cryptographically secure API key.

func (*APIKeyManager) GetAPIKey

func (m *APIKeyManager) GetAPIKey(key string) (*APIKeyInfo, bool)

GetAPIKey retrieves API key information.

func (*APIKeyManager) ListAPIKeys

func (m *APIKeyManager) ListAPIKeys(userID string) []*APIKeyInfo

ListAPIKeys returns all API keys for a user.

func (*APIKeyManager) RevokeAPIKey

func (m *APIKeyManager) RevokeAPIKey(key string) error

RevokeAPIKey revokes an API key.

func (*APIKeyManager) UpdateLastUsed

func (m *APIKeyManager) UpdateLastUsed(key string)

UpdateLastUsed updates the last used timestamp for an API key.

func (*APIKeyManager) ValidateAPIKey

func (m *APIKeyManager) ValidateAPIKey(ctx context.Context, key string) (*APIKeyInfo, error)

ValidateAPIKey validates an API key.

type AuditConfig

type AuditConfig struct {
	// Enabled determines if audit logging is enabled
	Enabled bool

	// Level determines what events to log
	// Options: "all", "auth", "data", "admin"
	Level string

	// IncludePaths is a list of path patterns to audit (empty = all paths)
	// Example: ["/api/admin/*", "/api/users/*"]
	IncludePaths []string

	// ExcludePaths is a list of path patterns to exclude from auditing
	// Example: ["/health", "/metrics"]
	ExcludePaths []string

	// LogRequestBody logs the request body (be careful with sensitive data)
	LogRequestBody bool

	// LogResponseBody logs the response body (be careful with sensitive data)
	LogResponseBody bool

	// SensitiveHeaders are headers that should be redacted in logs
	SensitiveHeaders []string

	// SensitiveFields are JSON fields that should be redacted in logs
	SensitiveFields []string

	// MaxBodySize is the maximum body size to log (in bytes)
	// Default: 1024 (1KB)
	MaxBodySize int

	// AutoApplyMiddleware automatically applies audit middleware globally
	AutoApplyMiddleware bool

	// Handler is called for each audit log entry
	// If not set, uses the default logger
	Handler func(*AuditEntry)
}

AuditConfig holds audit logging configuration.

func DefaultAuditConfig

func DefaultAuditConfig() AuditConfig

DefaultAuditConfig returns the default audit configuration.

type AuditEntry

type AuditEntry struct {
	// Timestamp of the event
	Timestamp time.Time `json:"timestamp"`

	// Event type (e.g., "auth.login", "auth.logout", "data.create", "data.update")
	EventType string `json:"event_type"`

	// Event category ("auth", "data", "admin", "security")
	Category string `json:"category"`

	// Result of the event ("success", "failure", "error")
	Result string `json:"result"`

	// User information
	UserID   string `json:"user_id,omitempty"`
	Username string `json:"username,omitempty"`
	Email    string `json:"email,omitempty"`

	// Request information
	Method    string            `json:"method"`
	Path      string            `json:"path"`
	Query     string            `json:"query,omitempty"`
	IPAddress string            `json:"ip_address"`
	UserAgent string            `json:"user_agent,omitempty"`
	Headers   map[string]string `json:"headers,omitempty"`
	RequestID string            `json:"request_id,omitempty"`
	SessionID string            `json:"session_id,omitempty"`

	// Request/Response data
	RequestBody  string `json:"request_body,omitempty"`
	ResponseBody string `json:"response_body,omitempty"`
	StatusCode   int    `json:"status_code,omitempty"`

	// Timing information
	Duration time.Duration `json:"duration,omitempty"`

	// Additional context
	Message  string         `json:"message,omitempty"`
	Metadata map[string]any `json:"metadata,omitempty"`

	// Error information
	Error string `json:"error,omitempty"`
}

AuditEntry represents a security audit log entry.

type AuditLogger

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

AuditLogger handles security audit logging.

func NewAuditLogger

func NewAuditLogger(config AuditConfig, logger forge.Logger) *AuditLogger

NewAuditLogger creates a new audit logger.

func (*AuditLogger) Log

func (al *AuditLogger) Log(entry *AuditEntry)

Log writes an audit log entry.

type CORSConfig

type CORSConfig struct {
	// Enabled determines if CORS is enabled
	Enabled bool

	// AllowOrigins is a list of allowed origins
	// Use ["*"] to allow all origins (not recommended for production)
	// Example: ["https://example.com", "https://app.example.com"]
	AllowOrigins []string

	// AllowMethods is a list of allowed HTTP methods
	// Default: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]
	AllowMethods []string

	// AllowHeaders is a list of allowed request headers
	// Use ["*"] to allow all headers (not recommended for production, and cannot be used with AllowCredentials)
	// Default: ["Origin", "Content-Type", "Accept", "Authorization"]
	AllowHeaders []string

	// ExposeHeaders is a list of headers exposed to the browser
	// Default: []
	ExposeHeaders []string

	// AllowCredentials indicates if credentials are allowed
	// Default: false
	// Note: Cannot be true when AllowOrigins is ["*"]
	AllowCredentials bool

	// MaxAge indicates how long (in seconds) the results of a preflight request can be cached
	// Default: 3600 (1 hour)
	MaxAge int

	// AllowPrivateNetwork allows requests from private networks
	// Default: false
	AllowPrivateNetwork bool

	// SkipPaths is a list of paths to skip CORS handling
	SkipPaths []string

	// AutoApplyMiddleware automatically applies CORS middleware globally
	AutoApplyMiddleware bool
}

CORSConfig holds CORS configuration.

func DefaultCORSConfig

func DefaultCORSConfig() CORSConfig

DefaultCORSConfig returns the default CORS configuration.

func SecureCORSConfig

func SecureCORSConfig(allowedOrigins []string) CORSConfig

SecureCORSConfig returns a more restrictive CORS configuration.

type CORSManager

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

CORSManager manages CORS policies.

func NewCORSManager

func NewCORSManager(config CORSConfig, logger forge.Logger) *CORSManager

NewCORSManager creates a new CORS manager.

type CSPBuilder

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

CSPBuilder helps build Content Security Policy directives.

func NewCSPBuilder

func NewCSPBuilder() *CSPBuilder

NewCSPBuilder creates a new CSP builder.

func (*CSPBuilder) BaseURI

func (b *CSPBuilder) BaseURI(sources ...string) *CSPBuilder

BaseURI sets the base-uri directive.

func (*CSPBuilder) BlockAllMixedContent

func (b *CSPBuilder) BlockAllMixedContent() *CSPBuilder

BlockAllMixedContent adds the block-all-mixed-content directive.

func (*CSPBuilder) Build

func (b *CSPBuilder) Build() string

Build constructs the CSP header value.

func (*CSPBuilder) ChildSrc

func (b *CSPBuilder) ChildSrc(sources ...string) *CSPBuilder

ChildSrc sets the child source directive.

func (*CSPBuilder) ConnectSrc

func (b *CSPBuilder) ConnectSrc(sources ...string) *CSPBuilder

ConnectSrc sets the connect source directive.

func (*CSPBuilder) DefaultSrc

func (b *CSPBuilder) DefaultSrc(sources ...string) *CSPBuilder

DefaultSrc sets the default source directive.

func (*CSPBuilder) FontSrc

func (b *CSPBuilder) FontSrc(sources ...string) *CSPBuilder

FontSrc sets the font source directive.

func (*CSPBuilder) FormAction

func (b *CSPBuilder) FormAction(sources ...string) *CSPBuilder

FormAction sets the form-action directive.

func (*CSPBuilder) FrameAncestors

func (b *CSPBuilder) FrameAncestors(sources ...string) *CSPBuilder

FrameAncestors sets the frame-ancestors directive.

func (*CSPBuilder) FrameSrc

func (b *CSPBuilder) FrameSrc(sources ...string) *CSPBuilder

FrameSrc sets the frame source directive.

func (*CSPBuilder) ImgSrc

func (b *CSPBuilder) ImgSrc(sources ...string) *CSPBuilder

ImgSrc sets the image source directive.

func (*CSPBuilder) MediaSrc

func (b *CSPBuilder) MediaSrc(sources ...string) *CSPBuilder

MediaSrc sets the media source directive.

func (*CSPBuilder) ObjectSrc

func (b *CSPBuilder) ObjectSrc(sources ...string) *CSPBuilder

ObjectSrc sets the object source directive.

func (*CSPBuilder) ReportTo

func (b *CSPBuilder) ReportTo(group string) *CSPBuilder

ReportTo sets the report-to directive.

func (*CSPBuilder) ReportURI

func (b *CSPBuilder) ReportURI(uri string) *CSPBuilder

ReportURI sets the report-uri directive.

func (*CSPBuilder) ScriptSrc

func (b *CSPBuilder) ScriptSrc(sources ...string) *CSPBuilder

ScriptSrc sets the script source directive.

func (*CSPBuilder) StyleSrc

func (b *CSPBuilder) StyleSrc(sources ...string) *CSPBuilder

StyleSrc sets the style source directive.

func (*CSPBuilder) UpgradeInsecureRequests

func (b *CSPBuilder) UpgradeInsecureRequests() *CSPBuilder

UpgradeInsecureRequests adds the upgrade-insecure-requests directive.

func (*CSPBuilder) WorkerSrc

func (b *CSPBuilder) WorkerSrc(sources ...string) *CSPBuilder

WorkerSrc sets the worker source directive.

type CSRFConfig

type CSRFConfig struct {
	// Enabled determines if CSRF protection is enabled
	Enabled bool

	// TokenLength is the length of the CSRF token in bytes (default: 32)
	TokenLength int

	// TokenLookup defines where to find the token:
	// - "header:<name>" - look in header
	// - "form:<name>" - look in form field
	// - "query:<name>" - look in query parameter
	// Default: "header:X-CSRF-Token"
	TokenLookup string

	// CookieName is the name of the CSRF cookie (default: "csrf_token")
	CookieName string

	// CookiePath is the path for the CSRF cookie (default: "/")
	CookiePath string

	// CookieDomain is the domain for the CSRF cookie
	CookieDomain string

	// CookieSecure indicates if the cookie should only be sent over HTTPS
	CookieSecure bool

	// CookieHTTPOnly indicates if the cookie should be inaccessible to JavaScript
	// Note: For CSRF tokens, this should be false so JavaScript can read it
	CookieHTTPOnly bool

	// CookieSameSite specifies the SameSite attribute
	CookieSameSite string

	// TTL is the token time-to-live (default: 12 hours)
	TTL time.Duration

	// SafeMethods are HTTP methods that don't require CSRF protection
	// Default: GET, HEAD, OPTIONS, TRACE
	SafeMethods []string

	// SkipPaths is a list of paths to skip CSRF protection
	SkipPaths []string

	// AutoApplyMiddleware automatically applies CSRF middleware globally
	AutoApplyMiddleware bool

	// ErrorHandler is called when CSRF validation fails
	ErrorHandler func(forge.Context, error) error
}

CSRFConfig holds CSRF protection configuration.

func DefaultCSRFConfig

func DefaultCSRFConfig() CSRFConfig

DefaultCSRFConfig returns the default CSRF configuration.

type CSRFProtection

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

CSRFProtection manages CSRF token generation and validation.

func NewCSRFProtection

func NewCSRFProtection(config CSRFConfig, logger forge.Logger) *CSRFProtection

NewCSRFProtection creates a new CSRF protection instance.

func (*CSRFProtection) DeleteToken

func (c *CSRFProtection) DeleteToken(sessionID string)

DeleteToken removes a CSRF token for a session.

func (*CSRFProtection) GenerateToken

func (c *CSRFProtection) GenerateToken() (string, error)

GenerateToken generates a new CSRF token.

func (*CSRFProtection) GetToken

func (c *CSRFProtection) GetToken(sessionID string) (string, bool)

GetToken retrieves the CSRF token for a session.

func (*CSRFProtection) SetToken

func (c *CSRFProtection) SetToken(sessionID, token string)

SetToken stores a CSRF token for a session.

func (*CSRFProtection) ValidateToken

func (c *CSRFProtection) ValidateToken(sessionID, providedToken string) error

ValidateToken validates a CSRF token against the stored token.

type Config

type Config struct {
	// Enabled determines if the security extension is enabled
	Enabled bool `json:"enabled" yaml:"enabled"`

	// Session configuration
	Session SessionConfig `json:"session" yaml:"session"`

	// Cookie configuration
	Cookie CookieConfig `json:"cookie" yaml:"cookie"`

	// CSRF protection configuration
	CSRF CSRFConfig `json:"csrf" yaml:"csrf"`

	// Rate limiting configuration
	RateLimit RateLimitConfig `json:"rate_limit" yaml:"rate_limit"`

	// Security headers configuration
	SecurityHeaders SecurityHeadersConfig `json:"security_headers" yaml:"security_headers"`

	// Password hashing configuration
	PasswordHasher PasswordHasherConfig `json:"password_hasher" yaml:"password_hasher"`

	// JWT configuration
	JWT JWTConfig `json:"jwt" yaml:"jwt"`

	// CORS configuration
	CORS CORSConfig `json:"cors" yaml:"cors"`

	// API Key configuration
	APIKey APIKeyConfig `json:"api_key" yaml:"api_key"`

	// Audit logging configuration
	Audit AuditConfig `json:"audit" yaml:"audit"`

	// RequireConfig requires config from ConfigManager
	RequireConfig bool `json:"-" yaml:"-"`
}

Config holds the security extension configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns the default security configuration.

func (*Config) Validate

func (c *Config) Validate() error

Validate validates the security configuration.

type ConfigOption

type ConfigOption func(*Config)

ConfigOption configures the security extension.

func WithAPIKeyConfig

func WithAPIKeyConfig(config APIKeyConfig) ConfigOption

WithAPIKeyConfig sets the complete API key config.

func WithAPIKeyEnabled

func WithAPIKeyEnabled(enabled bool) ConfigOption

WithAPIKeyEnabled enables or disables API key authentication.

func WithAuditConfig

func WithAuditConfig(config AuditConfig) ConfigOption

WithAuditConfig sets the complete audit config.

func WithAuditEnabled

func WithAuditEnabled(enabled bool) ConfigOption

WithAuditEnabled enables or disables audit logging.

func WithAuditLevel

func WithAuditLevel(level string) ConfigOption

WithAuditLevel sets the audit logging level.

func WithAutoApplyAPIKey

func WithAutoApplyAPIKey(autoApply bool) ConfigOption

WithAutoApplyAPIKey enables or disables automatic global API key middleware application.

func WithAutoApplyAudit

func WithAutoApplyAudit(autoApply bool) ConfigOption

WithAutoApplyAudit enables or disables automatic global audit middleware application.

func WithAutoApplyCORS

func WithAutoApplyCORS(autoApply bool) ConfigOption

WithAutoApplyCORS enables or disables automatic global CORS middleware application.

func WithAutoApplyCSRF

func WithAutoApplyCSRF(autoApply bool) ConfigOption

WithAutoApplyCSRF enables or disables automatic global CSRF middleware application.

func WithAutoApplyJWT

func WithAutoApplyJWT(autoApply bool) ConfigOption

WithAutoApplyJWT enables or disables automatic global JWT middleware application.

func WithAutoApplyMiddleware

func WithAutoApplyMiddleware(autoApply bool) ConfigOption

WithAutoApplyMiddleware enables or disables automatic global middleware application.

func WithAutoApplyRateLimit

func WithAutoApplyRateLimit(autoApply bool) ConfigOption

WithAutoApplyRateLimit enables or disables automatic global rate limiting middleware application.

func WithAutoApplySecurityHeaders

func WithAutoApplySecurityHeaders(autoApply bool) ConfigOption

WithAutoApplySecurityHeaders enables or disables automatic global security headers middleware application.

func WithCORSAllowCredentials added in v0.7.0

func WithCORSAllowCredentials(allow bool) ConfigOption

WithCORSAllowCredentials sets whether credentials are allowed in CORS requests.

func WithCORSAllowPrivateNetwork added in v0.7.0

func WithCORSAllowPrivateNetwork(allow bool) ConfigOption

WithCORSAllowPrivateNetwork sets whether private network access is allowed.

func WithCORSConfig

func WithCORSConfig(config CORSConfig) ConfigOption

WithCORSConfig sets the complete CORS config.

func WithCORSEnabled

func WithCORSEnabled(enabled bool) ConfigOption

WithCORSEnabled enables or disables CORS.

func WithCORSExposeHeaders added in v0.7.0

func WithCORSExposeHeaders(headers []string) ConfigOption

WithCORSExposeHeaders sets the CORS headers exposed to the browser.

func WithCORSHeaders added in v0.7.0

func WithCORSHeaders(headers []string) ConfigOption

WithCORSHeaders sets the allowed CORS request headers.

func WithCORSMaxAge added in v0.7.0

func WithCORSMaxAge(maxAge int) ConfigOption

WithCORSMaxAge sets the CORS preflight cache duration in seconds.

func WithCORSMaxAgeDuration added in v0.7.0

func WithCORSMaxAgeDuration(duration time.Duration) ConfigOption

WithCORSMaxAgeDuration sets the CORS preflight cache duration from a time.Duration.

func WithCORSMethods added in v0.7.0

func WithCORSMethods(methods []string) ConfigOption

WithCORSMethods sets the allowed CORS HTTP methods.

func WithCORSOrigins

func WithCORSOrigins(origins []string) ConfigOption

WithCORSOrigins sets the allowed CORS origins.

func WithCORSSkipPaths added in v0.7.0

func WithCORSSkipPaths(paths []string) ConfigOption

WithCORSSkipPaths sets paths to skip CORS handling.

func WithCSRFConfig

func WithCSRFConfig(config CSRFConfig) ConfigOption

WithCSRFConfig sets the complete CSRF config.

func WithCSRFEnabled

func WithCSRFEnabled(enabled bool) ConfigOption

WithCSRFEnabled enables or disables CSRF protection.

func WithConfig

func WithConfig(config Config) ConfigOption

WithConfig sets the complete config.

func WithCookieDomain

func WithCookieDomain(domain string) ConfigOption

WithCookieDomain sets the cookie domain.

func WithCookieEnabled

func WithCookieEnabled(enabled bool) ConfigOption

WithCookieEnabled sets whether cookie management is enabled.

func WithCookieHttpOnly

func WithCookieHttpOnly(httpOnly bool) ConfigOption

WithCookieHttpOnly sets whether cookies should be inaccessible to JavaScript.

func WithCookiePath

func WithCookiePath(path string) ConfigOption

WithCookiePath sets the cookie path.

func WithCookieSameSite

func WithCookieSameSite(sameSite string) ConfigOption

WithCookieSameSite sets the SameSite attribute for cookies.

func WithCookieSecure

func WithCookieSecure(secure bool) ConfigOption

WithCookieSecure sets whether cookies should only be sent over HTTPS.

func WithEnabled

func WithEnabled(enabled bool) ConfigOption

WithEnabled sets whether the security extension is enabled.

func WithJWTConfig

func WithJWTConfig(config JWTConfig) ConfigOption

WithJWTConfig sets the complete JWT config.

func WithJWTEnabled

func WithJWTEnabled(enabled bool) ConfigOption

WithJWTEnabled enables or disables JWT authentication.

func WithJWTSigningKey

func WithJWTSigningKey(key string) ConfigOption

WithJWTSigningKey sets the JWT signing key.

func WithPasswordHasherConfig

func WithPasswordHasherConfig(config PasswordHasherConfig) ConfigOption

WithPasswordHasherConfig sets the complete password hasher config.

func WithRateLimitConfig

func WithRateLimitConfig(config RateLimitConfig) ConfigOption

WithRateLimitConfig sets the complete rate limit config.

func WithRateLimitEnabled

func WithRateLimitEnabled(enabled bool) ConfigOption

WithRateLimitEnabled enables or disables rate limiting.

func WithRateLimitPerIP

func WithRateLimitPerIP(requests int, window time.Duration) ConfigOption

WithRateLimitPerIP creates a rate limiter that limits by IP address.

func WithRateLimitPerUser

func WithRateLimitPerUser(requests int, window time.Duration) ConfigOption

WithRateLimitPerUser creates a rate limiter that limits by user ID Note: This requires session middleware to be active.

func WithRedisAddress

func WithRedisAddress(address string) ConfigOption

WithRedisAddress sets the Redis server address.

func WithRedisDB

func WithRedisDB(db int) ConfigOption

WithRedisDB sets the Redis database number.

func WithRedisPassword

func WithRedisPassword(password string) ConfigOption

WithRedisPassword sets the Redis password.

func WithRequireConfig

func WithRequireConfig(require bool) ConfigOption

WithRequireConfig requires config from ConfigManager.

func WithSecureHeaders

func WithSecureHeaders() ConfigOption

WithSecureHeaders applies secure header presets.

func WithSecurePasswordHasher

func WithSecurePasswordHasher() ConfigOption

WithSecurePasswordHasher applies secure password hashing settings.

func WithSecurityHeadersConfig

func WithSecurityHeadersConfig(config SecurityHeadersConfig) ConfigOption

WithSecurityHeadersConfig sets the complete security headers config.

func WithSecurityHeadersEnabled

func WithSecurityHeadersEnabled(enabled bool) ConfigOption

WithSecurityHeadersEnabled enables or disables security headers.

func WithSessionAutoRenew

func WithSessionAutoRenew(autoRenew bool) ConfigOption

WithSessionAutoRenew enables or disables automatic session renewal.

func WithSessionCookieName

func WithSessionCookieName(name string) ConfigOption

WithSessionCookieName sets the session cookie name.

func WithSessionEnabled

func WithSessionEnabled(enabled bool) ConfigOption

WithSessionEnabled sets whether session management is enabled.

func WithSessionIdleTimeout

func WithSessionIdleTimeout(timeout time.Duration) ConfigOption

WithSessionIdleTimeout sets the session idle timeout.

func WithSessionStore

func WithSessionStore(store string) ConfigOption

WithSessionStore sets the session store backend.

func WithSessionTTL

func WithSessionTTL(ttl time.Duration) ConfigOption

WithSessionTTL sets the session TTL.

func WithSkipPaths

func WithSkipPaths(paths []string) ConfigOption

WithSkipPaths sets the paths to skip session handling.

type CookieConfig

type CookieConfig struct {
	// Enabled determines if cookie management is enabled
	Enabled bool `json:"enabled" yaml:"enabled"`

	// Secure indicates if cookies should only be sent over HTTPS
	Secure bool `json:"secure" yaml:"secure"`

	// HttpOnly indicates if cookies should be inaccessible to JavaScript
	HttpOnly bool `json:"http_only" yaml:"http_only"`

	// SameSite specifies the SameSite attribute
	SameSite string `json:"same_site" yaml:"same_site"`

	// Path specifies the cookie path
	Path string `json:"path" yaml:"path"`

	// Domain specifies the cookie domain
	Domain string `json:"domain" yaml:"domain"`

	// MaxAge specifies the cookie lifetime in seconds
	MaxAge int `json:"max_age" yaml:"max_age"`
}

CookieConfig holds cookie-specific configuration.

type CookieManager

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

CookieManager manages HTTP cookies with security best practices.

func NewCookieManager

func NewCookieManager(defaults CookieOptions) *CookieManager

NewCookieManager creates a new cookie manager with default options.

func (*CookieManager) DeleteCookie

func (cm *CookieManager) DeleteCookie(w http.ResponseWriter, name string, opts *CookieOptions)

DeleteCookie deletes a cookie by setting MaxAge to -1.

func (*CookieManager) GetAllCookies

func (cm *CookieManager) GetAllCookies(r *http.Request) []*http.Cookie

GetAllCookies returns all cookies from the request.

func (*CookieManager) GetCookie

func (cm *CookieManager) GetCookie(r *http.Request, name string) (string, error)

GetCookie gets a cookie from the request.

func (*CookieManager) HasCookie

func (cm *CookieManager) HasCookie(r *http.Request, name string) bool

HasCookie checks if a cookie exists in the request.

func (*CookieManager) SetCookie

func (cm *CookieManager) SetCookie(w http.ResponseWriter, name, value string, opts *CookieOptions)

SetCookie sets a cookie on the response.

type CookieOptions

type CookieOptions struct {
	// Path specifies the cookie path
	Path string

	// Domain specifies the cookie domain
	Domain string

	// MaxAge specifies the cookie lifetime in seconds
	MaxAge int

	// Expires specifies the cookie expiration time
	Expires time.Time

	// Secure indicates if the cookie should only be sent over HTTPS
	Secure bool

	// HttpOnly indicates if the cookie should be inaccessible to JavaScript
	HttpOnly bool

	// SameSite specifies the SameSite attribute
	SameSite SameSiteMode
}

CookieOptions holds options for creating a cookie.

func DefaultCookieOptions

func DefaultCookieOptions() CookieOptions

DefaultCookieOptions returns secure default cookie options.

type Extension

type Extension struct {
	*forge.BaseExtension
	// contains filtered or unexported fields
}

Extension implements forge.Extension and forge.MiddlewareExtension for comprehensive security features.

func NewExtension

func NewExtension(opts ...ConfigOption) *Extension

NewExtension creates a new security extension with functional options. Config is loaded from ConfigManager by default, with options providing overrides.

Example:

// Load from ConfigManager (tries "extensions.security", then "security")
security.NewExtension()

// Override specific fields
security.NewExtension(
    security.WithSessionStore("redis"),
    security.WithRedisAddress("redis://localhost:6379"),
)

// Require config from ConfigManager
security.NewExtension(security.WithRequireConfig(true))

func (*Extension) APIKeyManager

func (e *Extension) APIKeyManager() *APIKeyManager

APIKeyManager returns the API key manager instance.

func (*Extension) AuditLogger

func (e *Extension) AuditLogger() *AuditLogger

AuditLogger returns the audit logger instance.

func (*Extension) CORSManager

func (e *Extension) CORSManager() *CORSManager

CORSManager returns the CORS manager instance.

func (*Extension) CSRFProtection

func (e *Extension) CSRFProtection() *CSRFProtection

CSRFProtection returns the CSRF protection instance.

func (*Extension) CookieManager

func (e *Extension) CookieManager() *CookieManager

CookieManager returns the cookie manager (for advanced usage).

func (*Extension) Health

func (e *Extension) Health(ctx context.Context) error

Health checks if the security extension is healthy.

func (*Extension) JWTManager

func (e *Extension) JWTManager() *JWTManager

JWTManager returns the JWT manager instance.

func (*Extension) Middlewares

func (e *Extension) Middlewares() []forge.Middleware

Middlewares returns global middlewares for session management This implements the forge.MiddlewareExtension interface.

func (*Extension) PasswordHasher

func (e *Extension) PasswordHasher() *PasswordHasher

PasswordHasher returns the password hasher instance.

func (*Extension) RateLimiter

func (e *Extension) RateLimiter() *MemoryRateLimiter

RateLimiter returns the rate limiter instance.

func (*Extension) Register

func (e *Extension) Register(app forge.App) error

Register registers the security extension with the app.

func (*Extension) SecurityHeadersManager

func (e *Extension) SecurityHeadersManager() *SecurityHeadersManager

SecurityHeadersManager returns the security headers manager.

func (*Extension) SessionStore

func (e *Extension) SessionStore() SessionStore

SessionStore returns the session store (for advanced usage).

func (*Extension) Start

func (e *Extension) Start(ctx context.Context) error

Start starts the security extension.

func (*Extension) Stop

func (e *Extension) Stop(ctx context.Context) error

Stop stops the security extension.

type InMemorySessionStore

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

InMemorySessionStore implements SessionStore using an in-memory map with automatic cleanup of expired sessions. Not recommended for production use in distributed environments.

func NewInMemorySessionStore

func NewInMemorySessionStore(logger forge.Logger, metrics forge.Metrics) *InMemorySessionStore

NewInMemorySessionStore creates a new in-memory session store.

func (*InMemorySessionStore) Cleanup

func (s *InMemorySessionStore) Cleanup(ctx context.Context) (int, error)

Cleanup removes expired sessions.

func (*InMemorySessionStore) Connect

func (s *InMemorySessionStore) Connect(ctx context.Context) error

Connect establishes connection (no-op for in-memory).

func (*InMemorySessionStore) Count

func (s *InMemorySessionStore) Count(ctx context.Context) (int64, error)

Count returns the total number of active sessions.

func (*InMemorySessionStore) Create

func (s *InMemorySessionStore) Create(ctx context.Context, session *Session, ttl time.Duration) error

Create creates a new session.

func (*InMemorySessionStore) Delete

func (s *InMemorySessionStore) Delete(ctx context.Context, sessionID string) error

Delete removes a session by ID.

func (*InMemorySessionStore) DeleteByUserID

func (s *InMemorySessionStore) DeleteByUserID(ctx context.Context, userID string) error

DeleteByUserID removes all sessions for a user.

func (*InMemorySessionStore) Disconnect

func (s *InMemorySessionStore) Disconnect(ctx context.Context) error

Disconnect closes connection (no-op for in-memory).

func (*InMemorySessionStore) Get

func (s *InMemorySessionStore) Get(ctx context.Context, sessionID string) (*Session, error)

Get retrieves a session by ID.

func (*InMemorySessionStore) Ping

Ping checks if the store is accessible (always true for in-memory).

func (*InMemorySessionStore) Touch

func (s *InMemorySessionStore) Touch(ctx context.Context, sessionID string, ttl time.Duration) error

Touch updates the last accessed time and extends TTL.

func (*InMemorySessionStore) Update

func (s *InMemorySessionStore) Update(ctx context.Context, session *Session, ttl time.Duration) error

Update updates an existing session.

type JWTClaims

type JWTClaims struct {
	UserID   string         `json:"user_id"`
	Username string         `json:"username,omitempty"`
	Email    string         `json:"email,omitempty"`
	Roles    []string       `json:"roles,omitempty"`
	Metadata map[string]any `json:"metadata,omitempty"`
	jwt.RegisteredClaims
}

JWTClaims represents JWT claims.

func GetJWTClaims

func GetJWTClaims(ctx forge.Context) (*JWTClaims, bool)

GetJWTClaims retrieves JWT claims from Forge context.

func GetJWTClaimsFromStdContext added in v0.5.0

func GetJWTClaimsFromStdContext(ctx context.Context) (*JWTClaims, bool)

GetJWTClaimsFromStdContext retrieves JWT claims from standard context (for backward compatibility).

type JWTConfig

type JWTConfig struct {
	// Enabled determines if JWT authentication is enabled
	Enabled bool

	// SigningKey is the secret key for signing tokens (for HS256/HS384/HS512)
	SigningKey string

	// SigningMethod is the JWT signing algorithm
	// Options: HS256, HS384, HS512, RS256, RS384, RS512, ES256, ES384, ES512
	// Default: HS256
	SigningMethod string

	// TokenLookup defines where to find the token:
	// - "header:<name>" - look in header (default: "header:Authorization")
	// - "query:<name>" - look in query parameter
	// - "cookie:<name>" - look in cookie
	// - "form:<name>" - look in form field
	// Can specify multiple separated by comma: "header:Authorization,cookie:jwt"
	TokenLookup string

	// TokenPrefix is the prefix before the token in Authorization header
	// Default: "Bearer"
	TokenPrefix string

	// Issuer is the JWT issuer (iss claim)
	Issuer string

	// Audience is the JWT audience (aud claim)
	Audience string

	// TTL is the token time-to-live
	// Default: 1 hour
	TTL time.Duration

	// RefreshTTL is the refresh token time-to-live
	// Default: 7 days
	RefreshTTL time.Duration

	// SkipPaths is a list of paths to skip JWT authentication
	SkipPaths []string

	// AutoApplyMiddleware automatically applies JWT middleware globally
	AutoApplyMiddleware bool

	// ErrorHandler is called when JWT validation fails
	ErrorHandler func(forge.Context, error) error
}

JWTConfig holds JWT configuration.

func DefaultJWTConfig

func DefaultJWTConfig() JWTConfig

DefaultJWTConfig returns the default JWT configuration.

type JWTManager

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

JWTManager manages JWT token generation and validation.

func NewJWTManager

func NewJWTManager(config JWTConfig, logger forge.Logger) (*JWTManager, error)

NewJWTManager creates a new JWT manager.

func (*JWTManager) GenerateRefreshToken

func (jm *JWTManager) GenerateRefreshToken(userID string) (string, error)

GenerateRefreshToken generates a new refresh token.

func (*JWTManager) GenerateToken

func (jm *JWTManager) GenerateToken(claims *JWTClaims) (string, error)

GenerateToken generates a new JWT token.

func (*JWTManager) ValidateToken

func (jm *JWTManager) ValidateToken(tokenString string) (*JWTClaims, error)

ValidateToken validates a JWT token and returns the claims.

type MemoryRateLimiter

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

MemoryRateLimiter implements in-memory rate limiting.

func NewMemoryRateLimiter

func NewMemoryRateLimiter(config RateLimitConfig, logger forge.Logger, metrics forge.Metrics) *MemoryRateLimiter

NewMemoryRateLimiter creates a new in-memory rate limiter.

func (*MemoryRateLimiter) Allow

func (rl *MemoryRateLimiter) Allow(key string) (bool, *RateLimitInfo)

Allow checks if a request is allowed based on rate limit.

type PasswordHasher

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

PasswordHasher handles password hashing and verification.

func NewPasswordHasher

func NewPasswordHasher(config PasswordHasherConfig) *PasswordHasher

NewPasswordHasher creates a new password hasher.

func (*PasswordHasher) Hash

func (ph *PasswordHasher) Hash(password string) (string, error)

Hash creates a hash of the password using the configured algorithm.

func (*PasswordHasher) NeedsRehash

func (ph *PasswordHasher) NeedsRehash(hash string) (bool, error)

NeedsRehash checks if the hash needs to be rehashed with current parameters This is useful when upgrading hashing parameters.

func (*PasswordHasher) Verify

func (ph *PasswordHasher) Verify(password, hash string) (bool, error)

Verify checks if the password matches the hash.

type PasswordHasherConfig

type PasswordHasherConfig struct {
	// Algorithm specifies the hashing algorithm ("argon2id", "bcrypt")
	// Default: "argon2id" (recommended)
	Algorithm string

	// Argon2 parameters
	Argon2Memory      uint32 // Memory in KiB (default: 64MB = 65536)
	Argon2Iterations  uint32 // Number of iterations (default: 3)
	Argon2Parallelism uint8  // Degree of parallelism (default: 4)
	Argon2SaltLength  uint32 // Salt length in bytes (default: 16)
	Argon2KeyLength   uint32 // Derived key length (default: 32)

	// Bcrypt parameters
	BcryptCost int // Cost factor 4-31 (default: 12)
}

PasswordHasherConfig holds password hashing configuration.

func DefaultPasswordHasherConfig

func DefaultPasswordHasherConfig() PasswordHasherConfig

DefaultPasswordHasherConfig returns the default password hasher configuration.

func SecurePasswordHasherConfig

func SecurePasswordHasherConfig() PasswordHasherConfig

SecurePasswordHasherConfig returns a more secure configuration Use this for high-security applications (slower but more secure).

type PasswordStrength

type PasswordStrength int

PasswordStrength represents password strength levels.

const (
	PasswordVeryWeak PasswordStrength = iota
	PasswordWeak
	PasswordFair
	PasswordStrong
	PasswordVeryStrong
)

func CheckPasswordStrength

func CheckPasswordStrength(password string) PasswordStrength

CheckPasswordStrength evaluates password strength.

func (PasswordStrength) String

func (ps PasswordStrength) String() string

String returns the string representation of password strength.

type RateLimitConfig

type RateLimitConfig struct {
	// Enabled determines if rate limiting is enabled
	Enabled bool

	// RequestsPerWindow is the maximum number of requests allowed per window
	RequestsPerWindow int

	// Window is the time window for rate limiting
	Window time.Duration

	// SkipPaths is a list of paths to skip rate limiting
	SkipPaths []string

	// AutoApplyMiddleware automatically applies rate limiting middleware globally
	AutoApplyMiddleware bool

	// Store specifies the rate limit store backend ("memory", "redis")
	// For now, only memory is implemented
	Store string
}

RateLimitConfig holds rate limiting configuration.

func DefaultRateLimitConfig

func DefaultRateLimitConfig() RateLimitConfig

DefaultRateLimitConfig returns the default rate limit configuration.

type RateLimitInfo

type RateLimitInfo struct {
	Limit      int           // Maximum requests allowed
	Remaining  int           // Remaining requests in current window
	Reset      time.Time     // When the rate limit resets
	RetryAfter time.Duration // How long to wait before retrying
}

RateLimitInfo contains information about the current rate limit status.

type RedisConfig

type RedisConfig struct {
	// Address is the Redis server address
	Address string `json:"address" yaml:"address"`

	// Password is the Redis password
	Password string `json:"password" yaml:"password"`

	// DB is the Redis database number
	DB int `json:"db" yaml:"db"`

	// PoolSize is the connection pool size
	PoolSize int `json:"pool_size" yaml:"pool_size"`
}

RedisConfig holds Redis-specific configuration.

type SameSiteMode

type SameSiteMode string

SameSiteMode represents the SameSite attribute for cookies.

const (
	// SameSiteDefault uses the browser's default behavior.
	SameSiteDefault SameSiteMode = "default"
	// SameSiteLax allows cookies for top-level navigation.
	SameSiteLax SameSiteMode = "lax"
	// SameSiteStrict only sends cookies for same-site requests.
	SameSiteStrict SameSiteMode = "strict"
	// SameSiteNone allows cookies for cross-site requests (requires Secure).
	SameSiteNone SameSiteMode = "none"
)

type SecurityHeadersConfig

type SecurityHeadersConfig struct {
	// Enabled determines if security headers are enabled
	Enabled bool

	// XFrameOptions prevents clickjacking attacks
	// Values: "DENY", "SAMEORIGIN", "ALLOW-FROM https://example.com"
	// Default: "SAMEORIGIN"
	XFrameOptions string

	// XContentTypeOptions prevents MIME-sniffing attacks
	// Value: "nosniff"
	// Default: "nosniff"
	XContentTypeOptions string

	// XSSProtection enables XSS filter in older browsers
	// Values: "0" (disable), "1" (enable), "1; mode=block" (enable and block)
	// Default: "1; mode=block"
	// Note: Modern browsers use CSP instead
	XSSProtection string

	// ContentSecurityPolicy defines CSP rules
	// Example: "default-src 'self'; script-src 'self' 'unsafe-inline'"
	// Default: "" (not set)
	ContentSecurityPolicy string

	// ContentSecurityPolicyReportOnly enables CSP in report-only mode
	// Useful for testing CSP without breaking the site
	ContentSecurityPolicyReportOnly string

	// StrictTransportSecurity enforces HTTPS
	// Example: "max-age=31536000; includeSubDomains; preload"
	// Default: "max-age=31536000; includeSubDomains"
	StrictTransportSecurity string

	// ReferrerPolicy controls referrer information
	// Values: "no-referrer", "no-referrer-when-downgrade", "origin",
	//         "origin-when-cross-origin", "same-origin", "strict-origin",
	//         "strict-origin-when-cross-origin", "unsafe-url"
	// Default: "strict-origin-when-cross-origin"
	ReferrerPolicy string

	// PermissionsPolicy controls browser features
	// Example: "geolocation=(self), microphone=()"
	// Default: ""
	PermissionsPolicy string

	// CrossOriginEmbedderPolicy controls document embedding
	// Values: "unsafe-none", "require-corp", "credentialless"
	// Default: "" (not set)
	CrossOriginEmbedderPolicy string

	// CrossOriginOpenerPolicy controls cross-origin window interaction
	// Values: "unsafe-none", "same-origin-allow-popups", "same-origin"
	// Default: "" (not set)
	CrossOriginOpenerPolicy string

	// CrossOriginResourcePolicy controls resource loading
	// Values: "same-site", "same-origin", "cross-origin"
	// Default: "" (not set)
	CrossOriginResourcePolicy string

	// RemoveServerHeader removes the Server header
	// Default: true
	RemoveServerHeader bool

	// RemovePoweredBy removes the X-Powered-By header
	// Default: true
	RemovePoweredBy bool

	// CustomHeaders allows setting custom security headers
	CustomHeaders map[string]string

	// SkipPaths is a list of paths to skip security headers
	SkipPaths []string

	// AutoApplyMiddleware automatically applies security headers middleware globally
	AutoApplyMiddleware bool
}

SecurityHeadersConfig holds security headers configuration.

func DefaultSecurityHeadersConfig

func DefaultSecurityHeadersConfig() SecurityHeadersConfig

DefaultSecurityHeadersConfig returns the default security headers configuration.

func SecureHeadersPreset

func SecureHeadersPreset() SecurityHeadersConfig

SecureHeadersPreset returns a preset configuration for secure headers.

type SecurityHeadersManager

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

SecurityHeadersManager manages security headers.

func NewSecurityHeadersManager

func NewSecurityHeadersManager(config SecurityHeadersConfig, logger forge.Logger) *SecurityHeadersManager

NewSecurityHeadersManager creates a new security headers manager.

type Session

type Session struct {
	// ID is the unique session identifier
	ID string `json:"id"`

	// UserID is the user identifier (optional)
	UserID string `json:"user_id,omitempty"`

	// Data holds arbitrary session data
	Data map[string]any `json:"data"`

	// CreatedAt is when the session was created
	CreatedAt time.Time `json:"created_at"`

	// ExpiresAt is when the session expires
	ExpiresAt time.Time `json:"expires_at"`

	// LastAccessedAt is when the session was last accessed
	LastAccessedAt time.Time `json:"last_accessed_at"`

	// IPAddress of the client that created the session
	IPAddress string `json:"ip_address,omitempty"`

	// UserAgent of the client that created the session
	UserAgent string `json:"user_agent,omitempty"`
}

Session represents a user session with metadata and data.

func CreateSession

func CreateSession(
	ctx context.Context,
	w http.ResponseWriter,
	userID string,
	store SessionStore,
	cookieManager *CookieManager,
	config SessionConfig,
	metadata map[string]any,
) (*Session, error)

CreateSession creates a new session and sets the session cookie.

func GetSession

func GetSession(ctx context.Context) (*Session, bool)

GetSession retrieves the session from standard context (for backward compatibility).

func GetSessionFromForgeContext added in v0.5.0

func GetSessionFromForgeContext(ctx forge.Context) (*Session, bool)

GetSessionFromForgeContext retrieves the session from Forge context.

func MustGetSession

func MustGetSession(ctx context.Context) *Session

MustGetSession retrieves the session from context or panics.

func MustGetSessionFromForgeContext added in v0.5.0

func MustGetSessionFromForgeContext(ctx forge.Context) *Session

MustGetSessionFromForgeContext retrieves the session from Forge context or panics.

func NewSession

func NewSession(userID string, ttl time.Duration) (*Session, error)

NewSession creates a new session with the given TTL.

func (*Session) DeleteData

func (s *Session) DeleteData(key string)

DeleteData removes a value from session data (implements shared.Session).

func (*Session) GetCreatedAt

func (s *Session) GetCreatedAt() time.Time

GetCreatedAt returns when the session was created (implements shared.Session).

func (*Session) GetData

func (s *Session) GetData(key string) (any, bool)

GetData retrieves a value from session data (implements shared.Session).

func (*Session) GetExpiresAt

func (s *Session) GetExpiresAt() time.Time

GetExpiresAt returns when the session expires (implements shared.Session).

func (*Session) GetID

func (s *Session) GetID() string

GetID returns the session ID (implements shared.Session).

func (*Session) GetLastAccessedAt

func (s *Session) GetLastAccessedAt() time.Time

GetLastAccessedAt returns when the session was last accessed (implements shared.Session).

func (*Session) GetUserID

func (s *Session) GetUserID() string

GetUserID returns the user ID (implements shared.Session).

func (*Session) IsExpired

func (s *Session) IsExpired() bool

IsExpired returns true if the session has expired.

func (*Session) IsValid

func (s *Session) IsValid() bool

IsValid returns true if the session is valid.

func (*Session) SetData

func (s *Session) SetData(key string, value any)

SetData sets a value in session data (implements shared.Session).

func (*Session) Touch

func (s *Session) Touch()

Touch updates the last accessed timestamp.

type SessionConfig

type SessionConfig struct {
	// Enabled determines if session management is enabled
	Enabled bool `json:"enabled" yaml:"enabled"`

	// Store specifies the session store backend ("inmemory", "redis")
	Store string `json:"store" yaml:"store"`

	// CookieName is the name of the session cookie
	CookieName string `json:"cookie_name" yaml:"cookie_name"`

	// TTL is the session time-to-live
	TTL time.Duration `json:"ttl" yaml:"ttl"`

	// IdleTimeout is the session idle timeout
	IdleTimeout time.Duration `json:"idle_timeout" yaml:"idle_timeout"`

	// AutoRenew automatically extends session TTL on access
	AutoRenew bool `json:"auto_renew" yaml:"auto_renew"`

	// AutoApplyMiddleware automatically applies session middleware globally
	AutoApplyMiddleware bool `json:"auto_apply_middleware" yaml:"auto_apply_middleware"`

	// SkipPaths is a list of paths to skip session handling (when auto-applied)
	SkipPaths []string `json:"skip_paths" yaml:"skip_paths"`

	// TrackIPAddress stores the client IP address in session
	TrackIPAddress bool `json:"track_ip_address" yaml:"track_ip_address"`

	// TrackUserAgent stores the client user agent in session
	TrackUserAgent bool `json:"track_user_agent" yaml:"track_user_agent"`

	// Redis configuration (used when Store is "redis")
	Redis RedisConfig `json:"redis" yaml:"redis"`
}

SessionConfig holds session-specific configuration.

type SessionContextKey

type SessionContextKey struct{}

SessionContextKey is the context key for storing the session.

type SessionMiddlewareOptions

type SessionMiddlewareOptions struct {
	// Store is the session store to use
	Store SessionStore

	// CookieManager is the cookie manager to use
	CookieManager *CookieManager

	// Config is the session configuration
	Config SessionConfig

	// Logger for logging
	Logger forge.Logger

	// Metrics for metrics
	Metrics forge.Metrics

	// OnSessionCreated is called when a new session is created
	OnSessionCreated func(session *Session)

	// OnSessionExpired is called when a session expires
	OnSessionExpired func(sessionID string)

	// SkipPaths is a list of paths to skip session handling
	SkipPaths []string
}

SessionMiddlewareOptions holds options for the session middleware.

type SessionStore

type SessionStore interface {
	// Create creates a new session with the given TTL
	Create(ctx context.Context, session *Session, ttl time.Duration) error

	// Get retrieves a session by ID
	Get(ctx context.Context, sessionID string) (*Session, error)

	// Update updates an existing session
	Update(ctx context.Context, session *Session, ttl time.Duration) error

	// Delete removes a session by ID
	Delete(ctx context.Context, sessionID string) error

	// DeleteByUserID removes all sessions for a user
	DeleteByUserID(ctx context.Context, userID string) error

	// Touch updates the last accessed time and extends TTL
	Touch(ctx context.Context, sessionID string, ttl time.Duration) error

	// Cleanup removes expired sessions (for stores that don't auto-expire)
	Cleanup(ctx context.Context) (int, error)

	// Count returns the total number of active sessions
	Count(ctx context.Context) (int64, error)

	// Connect establishes connection to the backend
	Connect(ctx context.Context) error

	// Disconnect closes connection to the backend
	Disconnect(ctx context.Context) error

	// Ping checks if the backend is reachable
	Ping(ctx context.Context) error
}

SessionStore defines the interface for session storage backends.

Jump to

Keyboard shortcuts

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