security

package module
v1.13.4 Latest Latest
Warning

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

Go to latest
Published: Nov 6, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

README

Forge Security: HTTP security middleware for Go

Forge Security is the security extension for Forge, the Go backend framework. One extension gives your service security headers, per-IP rate limiting, CORS, CSRF protection, JWT issuing and verification, cookie sessions, API key checks, Argon2id and bcrypt password hashing, and audit logging. You switch each piece on with an option, and the ones you mark as auto-applied wrap every route in your app.

Go CI Go Reference Apache 2.0

Documentation · Quick start · Features · Middleware · JWT · Sessions · Passwords · Configuration · FAQ

Quick start

You need Go 1.26 or later. Add Forge and the extension:

go get github.com/xraph/forge@latest
go get github.com/xraph/forge/extensions/security@latest

Save this as main.go. It adds security headers and a five-requests-a-minute rate limit to every route, issues a JWT from /token, and protects /me with that token and the admin role:

package main

import (
	"context"
	"log"
	"net/http"
	"os"
	"time"

	"github.com/xraph/forge"
	"github.com/xraph/forge/extensions/security"
)

func main() {
	sec := security.NewExtension(
		security.WithJWTSigningKey(os.Getenv("JWT_SIGNING_KEY")),
		security.WithAutoApplySecurityHeaders(true),
		security.WithRateLimitPerIP(5, time.Minute),
		security.WithAutoApplyRateLimit(true),
	)

	app := forge.NewApp(forge.AppConfig{
		Name:        "security-demo",
		HTTPAddress: ":8080",
		Extensions:  []forge.Extension{sec},
	})

	// The JWT manager exists once the extension has registered.
	err := app.RegisterHookFn(forge.PhaseAfterRegister, "routes", func(_ context.Context, app forge.App) error {
		jwt := sec.JWTManager()
		router := app.Router()

		err := router.POST("/token", func(ctx forge.Context) error {
			token, err := jwt.GenerateToken(&security.JWTClaims{
				UserID: "user-42",
				Roles:  []string{"admin"},
			})
			if err != nil {
				return err
			}

			return ctx.JSON(http.StatusOK, map[string]string{"token": token})
		})
		if err != nil {
			return err
		}

		return router.GET("/me", func(ctx forge.Context) error {
			claims, ok := security.GetJWTClaims(ctx)
			if !ok {
				return forge.Unauthorized("no token")
			}

			return ctx.JSON(http.StatusOK, map[string]any{
				"user":  claims.UserID,
				"roles": claims.Roles,
			})
		}, forge.WithMiddleware(security.JWTMiddleware(jwt), security.RequireRoles("admin")))
	})
	if err != nil {
		log.Fatal(err)
	}

	if err := app.Run(); err != nil {
		log.Fatal(err)
	}
}

Run it with a signing key, then get a token and use it:

go mod tidy
JWT_SIGNING_KEY=a-long-random-secret-for-local-testing go run .

TOKEN=$(curl -s -X POST http://localhost:8080/token | jq -r .token)
curl -i -H "Authorization: Bearer $TOKEN" http://localhost:8080/me
# HTTP/1.1 200 OK
# X-Content-Type-Options: nosniff
# X-Frame-Options: SAMEORIGIN
# X-Ratelimit-Limit: 5
# {"roles":["admin"],"user":"user-42"}

curl http://localhost:8080/me
# Unauthorized

Call it a few more times and you'll get 429 Rate limit exceeded with a Retry-After header. The limit counts every request from your IP, the token call included.

Leave out JWT_SIGNING_KEY and the app refuses to start. That is the default behaviour: JWT is enabled out of the box, and an HMAC signing method needs a key, so a bare security.NewExtension() fails with "signing key is required for HMAC signing methods". Pass WithJWTSigningKey, or WithJWTEnabled(false) if you don't need tokens.

JWTMiddleware stores the verified claims with ctx.Set. RequireRoles reads them further down the chain, and the handler reads them with security.GetJWTClaims(ctx).

Features

You need Forge Security gives you
Security headers on every response X-Frame-Options, X-Content-Type-Options, HSTS, Referrer-Policy and more, with a stricter WithSecureHeaders() preset and a CSP builder
Rate limiting in Go An in-memory token bucket per client IP, with X-Ratelimit-* and Retry-After headers
CORS for a browser front end Allowed origins (including *.example.com patterns), methods, headers, credentials, preflight caching and private network access
CSRF protection A double-submit token in a cookie and the X-CSRF-Token header, checked on unsafe methods
JWT authentication JWTManager to issue and verify HMAC-signed tokens, JWTMiddleware, and RequireRoles
Cookie sessions An in-memory session store, CreateSession, SessionMiddleware, RequireSession and DestroySession
API keys APIKeyManager to create, validate, revoke and list keys, APIKeyMiddleware, and RequireScopes
Password storage Argon2id (default) or bcrypt through PasswordHasher, plus strength checks and rehash detection
An audit trail Structured audit entries for requests and for auth, data, admin and security events, with sensitive headers and fields redacted

Every manager is registered in the Vessel container, so you can inject *security.PasswordHasher, *security.JWTManager, *security.APIKeyManager and the rest by type. The extension also has accessors (sec.JWTManager(), sec.SessionStore(), sec.CookieManager() and so on) that return them once it has registered.

Global and route middleware

Each feature has an auto-apply switch. When it's on, the extension hands that middleware to Forge, and Forge installs it in front of every route, including /_/health and /_/metrics.

Feature Auto-apply option Middleware you can use per route
Security headers WithAutoApplySecurityHeaders(true) SecurityHeadersMiddleware(manager)
Rate limiting WithAutoApplyRateLimit(true) RateLimitMiddleware(limiter)
CORS WithAutoApplyCORS(true) CORSMiddleware(manager)
CSRF WithAutoApplyCSRF(true) CSRFMiddleware(csrf, cookieManager)
JWT WithAutoApplyJWT(true) JWTMiddleware(jwtManager), then RequireRoles(...)
API keys WithAutoApplyAPIKey(true) APIKeyMiddleware(manager), then RequireScopes(...)
Audit WithAutoApplyAudit(true) AuditMiddleware(auditLogger)
Sessions WithAutoApplyMiddleware(true) SessionMiddleware(opts), then RequireSession(...) or RequireSessionSimple()

Global middleware runs before route middleware. What it stores with ctx.Set (the session, JWT claims, API key info) is visible to your route middleware and your handler, so an auto-applied JWTMiddleware and a handler that calls security.GetJWTClaims(ctx) work together. None of these middlewares put their values in the request context, though. Read them through the forge.Context, not ctx.Context().

The rate limiter keys on X-Real-IP, then the first X-Forwarded-For address, then the connection's address. Those headers are whatever the client sends, so put the service behind a proxy that overwrites them before you rely on the limit.

JWT

JWTManager.GenerateToken(&security.JWTClaims{...}) fills in the issuer, audience, issued-at, not-before, a 1-hour expiry (TTL) and a random token ID, then signs. ValidateToken checks the signature, the time claims, and the issuer and audience when you've configured them. GenerateRefreshToken(userID) issues a token with RefreshTTL (seven days by default).

JWTClaims carries UserID, Username, Email, Roles and Metadata on top of the registered claims. JWTMiddleware reads the token from Authorization: Bearer ... by default. Set TokenLookup in JWTConfig to a comma-separated list such as header:Authorization,query:token,cookie:jwt to look elsewhere.

The signing key is used as raw bytes, so in practice you use the HMAC methods: HS256 (the default), HS384 or HS512. Keep the key out of your source and pass it in from the environment or a secrets store.

Sessions and cookies

Sessions live in the in-memory store. WithSessionStore("redis") passes validation but fails at registration with "redis session store not yet implemented", so for now sessions don't survive a restart or span replicas.

Create a session at sign-in, then protect routes with the session middleware on the route itself:

err := router.POST("/login", func(ctx forge.Context) error {
	session, err := security.CreateSession(ctx.Context(), ctx.Response(), "user-42",
		sec.SessionStore(), sec.CookieManager(),
		security.SessionConfig{CookieName: "forge_session", TTL: 24 * time.Hour},
		map[string]any{"plan": "pro"},
	)
	if err != nil {
		return err
	}

	return ctx.JSON(http.StatusOK, map[string]string{"session": session.ID})
})

sessions := security.SessionMiddleware(security.SessionMiddlewareOptions{
	Store:         sec.SessionStore(),
	CookieManager: sec.CookieManager(),
	Config:        security.SessionConfig{CookieName: "forge_session", TTL: 24 * time.Hour},
})

err = router.GET("/account", func(ctx forge.Context) error {
	session, ok := security.GetSessionFromForgeContext(ctx)
	if !ok {
		return forge.Unauthorized("sign in first")
	}

	plan, _ := session.GetData("plan")

	return ctx.JSON(http.StatusOK, map[string]any{"user": session.UserID, "plan": plan})
}, forge.WithMiddleware(sessions, security.RequireSessionSimple()))

SessionMiddleware stores the session with ctx.Set, so security.GetSessionFromForgeContext(ctx) finds it. security.GetSession(ctx.Context()) reads the request context under security.SessionContextKey{}, and nothing in the extension puts it there.

Like the JWT manager, sec.SessionStore() and sec.CookieManager() are only set after the extension registers, so define these routes in a forge.PhaseAfterRegister hook. Cookies default to Secure, HttpOnly and SameSite=Lax. A browser won't send a Secure cookie over plain HTTP, so during local development you'll want WithCookieSecure(false).

Password hashing

hasher, err := forge.Inject[*security.PasswordHasher](app.Container())
if err != nil {
	return err
}

hash, err := hasher.Hash(plain)       // Argon2id by default
ok, err := hasher.Verify(plain, hash) // works for Argon2id and bcrypt hashes
stale, _ := hasher.NeedsRehash(hash)  // true when the cost parameters differ from the config

The default is Argon2id with 64 MiB of memory, 3 iterations and 4 lanes. WithSecurePasswordHasher() raises that to 256 MiB, 4 iterations and 8 lanes. Set Algorithm: "bcrypt" in PasswordHasherConfig if you need bcrypt (cost 12 by default). CheckPasswordStrength, ValidatePassword and GenerateRandomPassword cover the usual sign-up checks.

API keys, CSRF, CORS and audit

API keys are held in memory by APIKeyManager. Create them at startup or from your own admin endpoint, then guard routes:

keys := sec.APIKeyManager()

_, err := keys.CreateAPIKey(&security.APIKeyInfo{
	Name:   "reporting",
	UserID: "user-42",
	Scopes: []string{"reports:read"},
})
if err != nil {
	return err
}

err = router.GET("/reports", listReports,
	forge.WithMiddleware(security.APIKeyMiddleware(keys), security.RequireScopes("reports:read")),
)

The middleware reads X-API-Key by default and rejects expired or revoked keys. If you store keys yourself, HashAPIKey and VerifyAPIKeyHash hash them with the password hasher.

CSRF protection is on by default but only auto-applied when you ask for it. On the first safe request (GET, HEAD, OPTIONS or TRACE) from a client without a token, the middleware sets a csrf_token cookie and returns the token in an X-Csrf-Token response header. Later safe requests pass straight through. Your front end sends the token back in X-CSRF-Token on POST, PUT, PATCH and DELETE, and a missing or wrong token gets a 403. Tokens are kept in memory for 12 hours.

CORS defaults to allowing every origin without credentials. For a browser app on another domain, name the origin and allow credentials:

security.NewExtension(
	security.WithJWTEnabled(false),
	security.WithCORSOrigins([]string{"https://app.example.com"}),
	security.WithCORSAllowCredentials(true),
	security.WithAutoApplyCORS(true),
	security.WithSecureHeaders(),
	security.WithAutoApplySecurityHeaders(true),
)

The audit logger writes entries through the app's logger, or to AuditConfig.Handler if you set one. The default level, auth, keeps auth and security events. WithAuditLevel("all") records everything. You can log events yourself with LogAuthEvent, LogDataEvent, LogAdminEvent and LogSecurityEvent.

Configuration

Configure the extension with options, or under extensions.security (falling back to security) in your config file. Your options win over the file and the file wins over the defaults, one field at a time, so session.cookie_name: sid in YAML renames the cookie and leaves the session TTL at 24 hours. Every key is snake_case, inside every section, so the JWT key is jwt.signing_key. Files that used the Go field names (jwt.SigningKey) still apply, with a warning at startup naming the new key. A top-level enabled: false turns the whole extension off.

Area Options
Whole extension WithEnabled, WithConfig, WithRequireConfig. NewExtensionWithConfig(cfg) is NewExtension(WithConfig(cfg))
Sessions WithSessionEnabled, WithSessionStore, WithSessionCookieName, WithSessionTTL, WithSessionIdleTimeout, WithSessionAutoRenew, WithAutoApplyMiddleware, WithSkipPaths, WithRedisAddress, WithRedisPassword, WithRedisDB
Cookies WithCookieEnabled, WithCookieSecure, WithCookieHttpOnly, WithCookieSameSite, WithCookiePath, WithCookieDomain
Headers WithSecurityHeadersEnabled, WithSecurityHeadersConfig, WithSecureHeaders, WithAutoApplySecurityHeaders
Rate limiting WithRateLimitEnabled, WithRateLimitConfig, WithRateLimitPerIP, WithAutoApplyRateLimit
CORS WithCORSEnabled, WithCORSConfig, WithCORSOrigins, WithCORSMethods, WithCORSHeaders, WithCORSExposeHeaders, WithCORSAllowCredentials, WithCORSMaxAge, WithCORSMaxAgeDuration, WithCORSAllowPrivateNetwork, WithCORSSkipPaths, WithAutoApplyCORS
CSRF WithCSRFEnabled, WithCSRFConfig, WithAutoApplyCSRF
JWT WithJWTEnabled, WithJWTConfig, WithJWTSigningKey, WithAutoApplyJWT
API keys WithAPIKeyEnabled, WithAPIKeyConfig, WithAutoApplyAPIKey
Passwords WithPasswordHasherConfig, WithSecurePasswordHasher
Audit WithAuditEnabled, WithAuditConfig, WithAuditLevel, WithAutoApplyAudit
Default Value
Enabled features All of them, with every auto-apply switch off
Session in-memory, cookie forge_session, 24-hour TTL, 30-minute idle timeout, auto-renew on
Rate limit 100 requests a minute per client, skipping /health and /metrics
Headers X-Frame-Options: SAMEORIGIN, nosniff, HSTS for one year with subdomains, strict-origin-when-cross-origin
JWT HS256, 1-hour tokens, 7-day refresh tokens, no signing key
CORS every origin, no credentials, preflight cached for an hour

Documentation

Topic Where
Features and usage Security features
Configuration reference Security configuration
Function reference Security functions
Go API pkg.go.dev
Middleware and lifecycle hooks in Forge Middleware guide, lifecycle guide

Examples

examples/security-auto-middleware turns on auto-applied session middleware and builds login and profile routes. Its handlers read the session with security.GetSession(r.Context()), and the session middleware never puts it in the request context, so they don't find it today. Use GetSessionFromForgeContext as the session pattern above does.

FAQ

How do I add rate limiting to a Go API?

Add security.WithRateLimitPerIP(100, time.Minute) and security.WithAutoApplyRateLimit(true) to the extension. Every route then gets a per-IP token bucket and a 429 when it runs out. Remember that the client IP comes from X-Real-IP or X-Forwarded-For when those are present.

Why does my Forge app fail with "signing key is required for HMAC signing methods"?

JWT is enabled by default and has no key. Pass security.WithJWTSigningKey(...), or security.WithJWTEnabled(false) if you don't use tokens.

Which password hashing algorithm should I use in Go?

The default, Argon2id, is the one to pick for new systems. Verify reads both Argon2id and bcrypt hashes, so you can keep old bcrypt hashes working. NeedsRehash only compares cost parameters within the same algorithm, so if you're moving users from bcrypt to Argon2id, check for the $2 prefix yourself and rehash after a successful sign-in.

Can I store sessions in Redis?

Not yet. The config accepts redis, but registration fails until a Redis store is implemented. You can pass your own SessionStore implementation to SessionMiddleware and CreateSession in the meantime.

How do I add CSRF protection to forms in a Go web app?

Turn on WithAutoApplyCSRF(true). Read the token from the X-Csrf-Token response header (or the csrf_token cookie) on a GET, and send it back in the X-CSRF-Token header on every state-changing request.

Contributing

Security is its own Go module in the Forge repository. Build and test it from its directory the way CI does:

cd extensions/security
GOWORK=off go build ./...
GOWORK=off go vet ./...
GOWORK=off go test -short -count=1 ./...
golangci-lint run ./...

AGENTS.md has the pinned lint version and the repository conventions. Commits follow Conventional Commits, for example fix(security): ....

License

Forge Security is part of Forge and is available under the Apache License 2.0.

Documentation

Index

Constants

View Source
const (
	// SessionStoreKey is the DI key for the session store.
	SessionStoreKey = "security:session"
	// SessionStoreKeyLegacy is the legacy DI key for the session store.
	SessionStoreKeyLegacy = "security.SessionStore"

	// CookieManagerKey is the DI key for the cookie manager.
	CookieManagerKey = "security:cookie"
	// CookieManagerKeyLegacy is the legacy DI key for the cookie manager.
	CookieManagerKeyLegacy = "security.CookieManager"

	// CSRFProtectionKey is the DI key for CSRF protection.
	CSRFProtectionKey = "security.CSRFProtection"
	// RateLimiterKey is the DI key for the rate limiter.
	RateLimiterKey = "security.RateLimiter"
	// SecurityHeadersKey is the DI key for security headers manager.
	SecurityHeadersKey = "security.SecurityHeadersManager"
	// PasswordHasherKey is the DI key for the password hasher.
	PasswordHasherKey = "security.PasswordHasher"
	// JWTManagerKey is the DI key for the JWT manager.
	JWTManagerKey = "security.JWTManager"
	// CORSManagerKey is the DI key for the CORS manager.
	CORSManagerKey = "security.CORSManager"
	// APIKeyManagerKey is the DI key for the API key manager.
	APIKeyManagerKey = "security.APIKeyManager"
	// AuditLoggerKey is the DI key for the audit logger.
	AuditLoggerKey = "security.AuditLogger"
)

DI container keys for security extension services.

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

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 `yaml:"enabled"`

	// 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 `yaml:"key_lookup"`

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

	// SkipPaths is a list of paths to skip API key authentication
	SkipPaths []string `yaml:"skip_paths"`

	// AutoApplyMiddleware automatically applies API key middleware globally
	AutoApplyMiddleware bool `yaml:"auto_apply_middleware"`

	// ErrorHandler is called when API key validation fails
	ErrorHandler func(forge.Context, error) error `yaml:"-"`

	// 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) `yaml:"-"`
}

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

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 `yaml:"enabled"`

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

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

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

	// LogRequestBody logs the request body (be careful with sensitive data)
	LogRequestBody bool `yaml:"log_request_body"`

	// LogResponseBody logs the response body (be careful with sensitive data)
	LogResponseBody bool `yaml:"log_response_body"`

	// SensitiveHeaders are headers that should be redacted in logs
	SensitiveHeaders []string `yaml:"sensitive_headers"`

	// SensitiveFields are JSON fields that should be redacted in logs
	SensitiveFields []string `yaml:"sensitive_fields"`

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

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

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

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 `yaml:"enabled"`

	// 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 `yaml:"allow_origins"`

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

	// 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 `yaml:"allow_headers"`

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

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

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

	// AllowPrivateNetwork allows requests from private networks
	// Default: false
	AllowPrivateNetwork bool `yaml:"allow_private_network"`

	// SkipPaths is a list of paths to skip CORS handling
	SkipPaths []string `yaml:"skip_paths"`

	// AutoApplyMiddleware automatically applies CORS middleware globally
	AutoApplyMiddleware bool `yaml:"auto_apply_middleware"`
}

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 `yaml:"enabled"`

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

	// 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 `yaml:"token_lookup"`

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

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

	// CookieDomain is the domain for the CSRF cookie
	CookieDomain string `yaml:"cookie_domain"`

	// CookieSecure indicates if the cookie should only be sent over HTTPS
	CookieSecure bool `yaml:"cookie_secure"`

	// 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 `yaml:"cookie_http_only"`

	// CookieSameSite specifies the SameSite attribute
	CookieSameSite string `yaml:"cookie_same_site"`

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

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

	// SkipPaths is a list of paths to skip CSRF protection
	SkipPaths []string `yaml:"skip_paths"`

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

	// ErrorHandler is called when CSRF validation fails
	ErrorHandler func(forge.Context, error) error `yaml:"-"`
}

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

func WithCORSAllowCredentials(allow bool) ConfigOption

WithCORSAllowCredentials sets whether credentials are allowed in CORS requests.

func WithCORSAllowPrivateNetwork

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

func WithCORSExposeHeaders(headers []string) ConfigOption

WithCORSExposeHeaders sets the CORS headers exposed to the browser.

func WithCORSHeaders

func WithCORSHeaders(headers []string) ConfigOption

WithCORSHeaders sets the allowed CORS request headers.

func WithCORSMaxAge

func WithCORSMaxAge(maxAge int) ConfigOption

WithCORSMaxAge sets the CORS preflight cache duration in seconds.

func WithCORSMaxAgeDuration

func WithCORSMaxAgeDuration(duration time.Duration) ConfigOption

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

func WithCORSMethods

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

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"`
	//nolint:embeddedstructfieldcheck // moving it reorders an exported struct and breaks callers' unkeyed literals
	jwt.RegisteredClaims
}

JWTClaims represents JWT claims.

func GetJWTClaims

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

GetJWTClaims retrieves JWT claims from Forge context.

func GetJWTClaimsFromStdContext

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 `yaml:"enabled"`

	// SigningKey is the secret key for signing tokens (for HS256/HS384/HS512)
	SigningKey string `yaml:"signing_key"`

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

	// 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 `yaml:"token_lookup"`

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

	// Issuer is the JWT issuer (iss claim)
	Issuer string `yaml:"issuer"`

	// Audience is the JWT audience (aud claim)
	Audience string `yaml:"audience"`

	// TTL is the token time-to-live
	// Default: 1 hour
	TTL time.Duration `yaml:"ttl"`

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

	// SkipPaths is a list of paths to skip JWT authentication
	SkipPaths []string `yaml:"skip_paths"`

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

	// ErrorHandler is called when JWT validation fails
	ErrorHandler func(forge.Context, error) error `yaml:"-"`
}

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 `yaml:"algorithm"`

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

	// Bcrypt parameters
	BcryptCost int `yaml:"bcrypt_cost"` // 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 `yaml:"enabled"`

	// RequestsPerWindow is the maximum number of requests allowed per window
	RequestsPerWindow int `yaml:"requests_per_window"`

	// Window is the time window for rate limiting
	Window time.Duration `yaml:"window"`

	// SkipPaths is a list of paths to skip rate limiting
	SkipPaths []string `yaml:"skip_paths"`

	// AutoApplyMiddleware automatically applies rate limiting middleware globally
	AutoApplyMiddleware bool `yaml:"auto_apply_middleware"`

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

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 `yaml:"enabled"`

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

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

	// 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 `yaml:"xss_protection"`

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

	// ContentSecurityPolicyReportOnly enables CSP in report-only mode
	// Useful for testing CSP without breaking the site
	ContentSecurityPolicyReportOnly string `yaml:"content_security_policy_report_only"`

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

	// 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 `yaml:"referrer_policy"`

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

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

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

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

	// RemoveServerHeader removes the Server header
	// Default: true
	RemoveServerHeader bool `yaml:"remove_server_header"`

	// RemovePoweredBy removes the X-Powered-By header
	// Default: true
	RemovePoweredBy bool `yaml:"remove_powered_by"`

	// CustomHeaders allows setting custom security headers
	CustomHeaders map[string]string `yaml:"custom_headers"`

	// SkipPaths is a list of paths to skip security headers
	SkipPaths []string `yaml:"skip_paths"`

	// AutoApplyMiddleware automatically applies security headers middleware globally
	AutoApplyMiddleware bool `yaml:"auto_apply_middleware"`
}

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

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

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