auth

package
v1.1.4 Latest Latest
Warning

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

Go to latest
Published: Feb 12, 2026 License: AGPL-3.0 Imports: 53 Imported by: 0

README

Auth Package

This package provides OAuth 2.0 authentication for Lesser, enabling secure access to local user accounts.

Overview

The auth package implements:

  • OAuth 2.0 with PKCE (Proof Key for Code Exchange) for enhanced security
  • JWT (JSON Web Token) based access tokens
  • Refresh token support for long-lived sessions
  • Middleware for protecting endpoints
  • Scope-based authorization

Lesser is passwordless by design: users authenticate via WebAuthn/passkeys and/or wallet signatures. OAuth tokens are still presented as Authorization: Bearer …, but Lesser does not support password-based login or password grant flows.

Components

OAuthService

The main OAuth service that handles:

  • Client validation
  • Authorization code generation
  • PKCE verification
  • Token generation and validation
  • JWT signing and verification
Middleware

Authentication middleware that:

  • Extracts and validates JWT tokens from requests
  • Provides user context to handlers
  • Enforces scope requirements
  • Validates user ownership of resources

Usage

Basic Setup
import "github.com/equaltoai/lesser/pkg/auth"

// Create OAuth service
oauthSvc := auth.NewOAuthService("your-jwt-secret")

// Register a client
oauthSvc.RegisterClient(&auth.Client{
    ID:          "my-app",
    Secret:      "client-secret",
    Name:        "My Application",
    RedirectURI: "https://myapp.com/callback",
})
Protecting Endpoints
// Create middleware
authMiddleware := auth.NewMiddleware()

// In your Lambda handler
func handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    // Verify authentication
    claims, err := authMiddleware.RequireAuth(ctx, request)
    if err != nil {
        return common.Unauthorized(err), nil
    }
    
    // Check user matches resource owner
    if err := authMiddleware.RequireUser(claims, username); err != nil {
        return common.Forbidden(err), nil
    }
    
    // Check required scope
    if err := authMiddleware.RequireScope(claims, auth.ScopeWrite); err != nil {
        return common.Forbidden(err), nil
    }
    
    // User is authenticated and authorized
    // ... handle request ...
}
OAuth Flow
  1. Authorization Request

    GET /oauth/authorize?
      response_type=code&
      client_id=my-app&
      redirect_uri=https://myapp.com/callback&
      code_challenge=CHALLENGE&
      code_challenge_method=S256&
      scope=read write&
      state=RANDOM_STATE
    
  2. User Authorization

    • Users authenticate via the passwordless auth UI (WebAuthn/passkeys and/or wallet challenge + signature).
    • See docs/architecture/auth/PASSWORDLESS_OAUTH.md for the end-to-end flow and endpoints.
  3. Authorization Code Response

    HTTP/1.1 302 Found
    Location: https://myapp.com/callback?code=AUTH_CODE&state=RANDOM_STATE
    
  4. Token Exchange

    POST /oauth/token
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=authorization_code&
    code=AUTH_CODE&
    client_id=my-app&
    client_secret=client-secret&
    code_verifier=VERIFIER&
    redirect_uri=https://myapp.com/callback
    
  5. Token Response

    {
      "access_token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
      "token_type": "Bearer",
      "expires_in": 3600,
      "refresh_token": "REFRESH_TOKEN",
      "scope": "read write"
    }
    

Security Considerations

PKCE Required

All authorization requests must include PKCE parameters:

  • code_challenge: Base64URL encoded SHA256 hash of the code verifier
  • code_challenge_method: Must be "S256"
  • code_verifier: Random string used in token exchange
Token Expiration
  • Access tokens expire after 1 hour
  • Refresh tokens expire after 30 days
  • Authorization codes expire after 10 minutes
JWT Claims

Access tokens include:

{
  "sub": "username",
  "username": "username",
  "client_id": "my-app",
  "scopes": ["read", "write"],
  "iat": 1234567890,
  "exp": 1234571490
}

Scopes

  • read: Read access to user data
  • write: Write access to create/update activities

Storage

OAuth data is stored in DynamoDB:

  • Authorization codes: PK=AUTHCODE#{code}, SK=CODE
  • Refresh tokens: PK=REFRESHTOKEN#{token}, SK=TOKEN

Both include automatic expiration handling.

Configuration

Environment variables:

  • JWT_SECRET: Secret key for signing JWT tokens (required in production)

Testing

# Run OAuth package tests
go test ./pkg/auth/...

# Run OAuth storage tests
GO_ENV=test go test ./pkg/storage/dynamodb/... -run OAuth

Future Enhancements

  1. User Authentication

    • Expand passwordless login UI (passkeys/wallets)
    • Account recovery UX (recovery codes / social recovery)
    • Multi-factor authentication (passwordless-friendly)
  2. Client Management

    • Dynamic client registration
    • Client credentials from database
    • Multiple redirect URIs per client
  3. Advanced OAuth Features

    • OpenID Connect support
    • Token introspection endpoint
    • Token revocation endpoint
    • Client credentials grant type
  4. Security Enhancements

    • Rate limiting
    • Brute force protection
    • Token rotation on refresh
    • Encrypted token storage

Documentation

Overview

Package auth provides common password validation and security utilities for authentication.

Package auth provides universal authentication context and utilities for consolidating authentication patterns across the Lesser application.

Package auth provides centralized authentication extraction functions This consolidates the auth extraction patterns found across 80+ handler files

Index

Constants

View Source
const (
	ScopeRead  = "read"
	ScopeWrite = "write"
	ScopeAdmin = "admin"
)

Scopes define the permissions that can be granted

View Source
const (
	GrantTypeAuthorizationCode = "authorization_code"
	GrantTypeRefreshToken      = "refresh_token"
)

Grant types

View Source
const (
	// Access token duration: 1 hour is reasonable for external client applications
	// Balances security with usability - clients should use refresh tokens for longer sessions
	AccessTokenDuration = 1 * time.Hour
	// Refresh tokens should be rotated regularly
	RefreshTokenDuration = 7 * 24 * time.Hour // 7 days
	// Authorization codes must be very short-lived
	AuthCodeDuration = 5 * time.Minute
	// Token family tracking for refresh token rotation
	RefreshTokenFamilyExpiry = 30 * 24 * time.Hour // 30 days for family tracking
)

Token expiration times

View Source
const (
	ClientClassWeb   = "web"
	ClientClassCLI   = "cli"
	ClientClassAgent = "agent"
)

Client classes identify the client category that minted an access token. These are used for server-side policy decisions (e.g., automation safety rails) without relying on spoofable headers.

View Source
const (
	// Login attempts before lockout
	MaxLoginAttempts = 5
	MaxIPAttempts    = 20

	// Lockout durations
	AccountLockoutDuration = 30 * time.Minute
	IPLockoutDuration      = 1 * time.Hour

	// Time windows for counting attempts
	AttemptWindow = 15 * time.Minute

	// Rate limit keys
	RateLimitTypeAccount = "account"
	RateLimitTypeIP      = "ip"
)

Rate limiting constants

View Source
const (
	// Read scopes
	ReadNotifications = "read:notifications"
	ReadFollows       = "read:follows"
	ReadBlocks        = "read:blocks"
	ReadFilters       = "read:filters"

	// Write scopes
	WriteNotifications = "write:notifications"
	WriteFollows       = "write:follows"
	WriteBlocks        = "write:blocks"
	WriteFilters       = "write:filters"
)

OAuth 2.0 Scopes

View Source
const (
	SessionDuration               = 7 * 24 * time.Hour // 7 days (reduced from 30)
	ShortAccessTokenDuration      = 1 * time.Hour      // Align with client app expectations
	RefreshTokenRotationWindow    = 1 * time.Hour      // Reduced grace period (from 24h)
	MaxSessionsPerUser            = 10                 // Limit concurrent sessions
	SessionInactivityTimeout      = 24 * time.Hour     // Auto-logout after inactivity
	DeviceTrustPromotionThreshold = 7 * 24 * time.Hour // Days until device can be trusted

	// Device trust levels
	TrustLevelTrusted   = "trusted"
	TrustLevelUntrusted = "untrusted"
)

Session constants - enhanced security

View Source
const (
	ChallengeDuration     = 5 * time.Minute // WebAuthn challenges expire after 5 minutes
	MaxCredentialsPerUser = 10              // Maximum passkeys per user
)

WebAuthn constants

View Source
const AuthContextKey = "auth_context"

AuthContextKey is the key used to store AuthContext in request context.

View Source
const (
	// ContextKeyAuthenticatedAccount is the key for storing authenticated account in context
	ContextKeyAuthenticatedAccount contextKey = "authenticated_account"
)
View Source
const DefaultBcryptCost = 12

DefaultBcryptCost is the default cost factor for bcrypt hashing

View Source
const OAuthClientSecretHashPrefix = common.OAuthClientSecretHashPrefix

OAuthClientSecretHashPrefix marks hashed secrets stored for OAuth clients.

View Source
const (
	SecurityActionDeny = "deny"
)

Security action constants

Variables

View Source
var (
	// ErrUnsupportedAgentKeyType is returned when the requested key type is not supported.
	ErrUnsupportedAgentKeyType = errors.New("unsupported agent key type")
	// ErrInvalidAgentPublicKey is returned when a provided agent public key cannot be parsed.
	ErrInvalidAgentPublicKey = errors.New("invalid agent public key")
	// ErrInvalidAgentSignature is returned when a provided signature cannot be verified.
	ErrInvalidAgentSignature = errors.New("invalid agent signature")
)
View Source
var (
	ErrInvalidCSRF = errors.New("invalid CSRF token")
	ErrExpiredCSRF = errors.New("expired CSRF token")
	ErrMissingCSRF = errors.New("missing CSRF token")
)

CSRF-related errors

View Source
var (
	// Basic password length errors
	ErrPasswordTooShort = apperrors.PasswordTooShort(8)
	ErrPasswordTooLong  = apperrors.PasswordTooLong(72)

	// Length requirement error for policy validation
	ErrPasswordInsufficientLength = apperrors.PasswordInsufficientLength()

	// Passwordless enforcement
	ErrPasswordAuthDisabled = errors.New("password authentication is disabled")

	// Password processing errors
	ErrPasswordHashFailed = apperrors.PasswordHashingFailed(errors.New("password hashing failed"))

	// Character requirement errors
	ErrPasswordMissingUppercase   = apperrors.PasswordMissingRequirement("uppercase letter")
	ErrPasswordMissingLowercase   = apperrors.PasswordMissingRequirement("lowercase letter")
	ErrPasswordMissingNumber      = apperrors.PasswordMissingRequirement("number")
	ErrPasswordMissingSpecialChar = apperrors.PasswordMissingRequirement("special character")

	// Content validation errors
	ErrPasswordContainsUsername  = apperrors.PasswordContainsUsername()
	ErrPasswordTooCommon         = apperrors.PasswordTooCommon()
	ErrPasswordSequentialPattern = apperrors.PasswordSequentialPattern()
	ErrPasswordRepeatedPattern   = apperrors.PasswordRepeatedPattern()

	// Session security errors
	ErrCSRFTokenGeneration     = apperrors.CSRFTokenGenerationFailed(errors.New("CSRF token generation failed"))
	ErrSessionIDGeneration     = apperrors.SessionIDGenerationFailed(errors.New("session ID generation failed"))
	ErrCookieEntropyGeneration = apperrors.CookieEntropyGenerationFailed(errors.New("cookie entropy generation failed"))
	ErrCSRFTokenRotation       = apperrors.CSRFTokenRotationFailed(errors.New("CSRF token rotation failed"))
	ErrCSRFValidationFailed    = apperrors.CSRFValidationFailed()

	// OAuth token validation errors
	ErrUnexpectedSigningMethod = apperrors.UnexpectedSigningMethod()
	ErrSessionIDMismatch       = apperrors.SessionIDMismatch()
	ErrIPAddressMismatch       = apperrors.IPAddressMismatch()
	ErrTokenVersionMismatch    = apperrors.TokenVersionMismatch()
	ErrTokenTooOld             = apperrors.TokenTooOld()

	// Wallet authentication errors
	ErrNonceGeneration          = apperrors.NonceGenerationFailed(errors.New("nonce generation failed"))
	ErrChallengeStorage         = apperrors.ChallengeStorageFailed(errors.New("challenge storage failed"))
	ErrChallengeRetrieval       = apperrors.ChallengeRetrievalFailed(errors.New("challenge retrieval failed"))
	ErrChallengeExpired         = apperrors.WalletChallengeExpired()
	ErrMessageMismatch          = apperrors.MessageMismatch()
	ErrAddressMismatch          = apperrors.WalletAddressMismatch()
	ErrSignatureVerification    = apperrors.SignatureVerificationFailed()
	ErrWalletCheck              = apperrors.WalletCheckFailed(errors.New("wallet check failed"))
	ErrWalletStorage            = apperrors.WalletStorageFailed(errors.New("wallet storage failed"))
	ErrWalletRetrieval          = apperrors.WalletRetrievalFailed(errors.New("wallet retrieval failed"))
	ErrWalletDeletion           = apperrors.WalletDeletionFailed(errors.New("wallet deletion failed"))
	ErrWalletAlreadyLinked      = apperrors.WalletAlreadyLinked()
	ErrInvalidSignatureFormat   = apperrors.InvalidSignatureFormat()
	ErrInvalidSignatureLength   = apperrors.InvalidSignatureLength()
	ErrPublicKeyRecovery        = apperrors.PublicKeyRecoveryFailed(errors.New("public key recovery failed"))
	ErrSignatureAddressMismatch = apperrors.SignatureAddressMismatch()

	// Social recovery errors
	ErrTrusteeActorIDRequired    = apperrors.TrusteeActorIDRequired()
	ErrInsufficientTrustees      = apperrors.InsufficientTrustees()
	ErrRecoveryTokenGeneration   = apperrors.RecoveryTokenGenerationFailed(errors.New("recovery token generation failed"))
	ErrRecoveryRequestNotFound   = apperrors.RecoveryRequestNotFound()
	ErrRecoveryRequestNotPending = apperrors.RecoveryRequestNotPending()
	ErrRecoveryRequestExpired    = apperrors.RecoveryRequestExpired()
	ErrTrusteeAlreadyVoted       = apperrors.TrusteeAlreadyVoted()

	// Social recovery repository operation errors
	ErrTrusteeStorage           = apperrors.TrusteeStorageFailed(errors.New("trustee storage failed"))
	ErrTrusteeDeletion          = apperrors.TrusteeDeletionFailed(errors.New("trustee deletion failed"))
	ErrTrusteeRetrieval         = apperrors.TrusteeRetrievalFailed(errors.New("trustee retrieval failed"))
	ErrRecoveryRequestStorage   = apperrors.RecoveryRequestStorageFailed(errors.New("recovery request storage failed"))
	ErrRecoveryRequestRetrieval = apperrors.RecoveryRequestRetrievalFailed(errors.New("recovery request retrieval failed"))
	ErrRecoveryRequestUpdate    = apperrors.RecoveryRequestUpdateFailed(errors.New("recovery request update failed"))
	ErrRecoveryTokenStorage     = apperrors.RecoveryTokenStorageFailed(errors.New("recovery token storage failed"))

	// WebAuthn service errors
	ErrWebAuthnServiceInit        = apperrors.WebAuthnServiceInitFailed(errors.New("WebAuthn service init failed"))
	ErrUserRetrieval              = apperrors.UserRetrievalFailed(errors.New("user retrieval failed"))
	ErrCredentialRetrieval        = apperrors.CredentialRetrievalFailed(errors.New("credential retrieval failed"))
	ErrRegistrationBegin          = apperrors.RegistrationBeginFailed(errors.New("registration begin failed"))
	ErrLoginBegin                 = apperrors.LoginBeginFailed(errors.New("login begin failed"))
	ErrSessionDataSerialization   = apperrors.SessionDataSerializationFailed(errors.New("session data serialization failed"))
	ErrSessionDataDeserialization = apperrors.SessionDataDeserializationFailed(errors.New("session data deserialization failed"))
	ErrWebAuthnChallengeStorage   = apperrors.WebAuthnChallengeStorageFailed(errors.New("WebAuthn challenge storage failed"))
	ErrCredentialResponse         = apperrors.CredentialResponseParseFailed(errors.New("credential response parse failed"))
	ErrCredentialCreation         = apperrors.CredentialCreationFailed(errors.New("credential creation failed"))
	ErrCredentialValidation       = apperrors.CredentialValidationFailed(errors.New("credential validation failed"))
	ErrCredentialStorage          = apperrors.CredentialStorageFailed(errors.New("credential storage failed"))
	ErrMaxCredentialsReached      = apperrors.MaxCredentialsReached()
	ErrInvalidSessionDataType     = apperrors.InvalidSessionDataType()
	ErrLastAuthMethodDelete       = apperrors.LastAuthMethodDelete()

	// Recovery code errors
	ErrRecoveryCodeGeneration = apperrors.RecoveryCodeGenerationFailed(errors.New("recovery code generation failed"))
	ErrRecoveryCodeHashing    = apperrors.RecoveryCodeHashingFailed(errors.New("recovery code hashing failed"))
	ErrRecoveryCodeStorage    = apperrors.RecoveryCodeStorageFailed(errors.New("recovery code storage failed"))
	ErrRecoveryCodeRetrieval  = apperrors.RecoveryCodeRetrievalFailed(errors.New("recovery code retrieval failed"))
	ErrRecoveryCodeMarkUsed   = apperrors.RecoveryCodeMarkUsedFailed(errors.New("recovery code mark used failed"))
	ErrRecoveryCodeClear      = apperrors.RecoveryCodeClearFailed(errors.New("recovery code clear failed"))

	// Secrets Manager errors
	ErrAWSConfigLoad              = apperrors.AWSConfigLoadFailed(errors.New("AWS config load failed"))
	ErrSecretsManagerConnection   = apperrors.SecretsManagerConnectionFailed(errors.New("secrets manager connection failed"))
	ErrInvalidPrivateKeyFormat    = apperrors.InvalidPrivateKeyFormat()
	ErrSecretValueMarshal         = apperrors.SecretValueMarshalFailed(errors.New("secret value marshal failed"))
	ErrSecretCreation             = apperrors.SecretCreationFailed(errors.New("secret creation failed"))
	ErrPrivateKeyRetrieval        = apperrors.PrivateKeyRetrievalFailed(errors.New("private key retrieval failed"))
	ErrSecretValueUnmarshal       = apperrors.SecretValueUnmarshalFailed(errors.New("secret value unmarshal failed"))
	ErrRetrievedPrivateKeyInvalid = apperrors.RetrievedPrivateKeyInvalid()
	ErrSecretDeletion             = apperrors.SecretDeletionFailed(errors.New("secret deletion failed"))
	ErrRSAKeyPairGeneration       = apperrors.RSAKeyPairGenerationFailed(errors.New("RSA key pair generation failed"))
	ErrPrivateKeyMarshal          = apperrors.PrivateKeyMarshalFailed(errors.New("private key marshal failed"))
	ErrPublicKeyMarshal           = apperrors.PublicKeyMarshalFailed(errors.New("public key marshal failed"))
	ErrGeneratedPrivateKeyStorage = apperrors.GeneratedPrivateKeyStorageFailed(errors.New("generated private key storage failed"))
	ErrKeyPairGenerationRotation  = apperrors.KeyPairGenerationRotationFailed(errors.New("key pair generation rotation failed"))
	ErrPEMBlockDecode             = apperrors.PEMBlockDecodeFailed()
	ErrPrivateKeyParse            = apperrors.PrivateKeyParseFailed(errors.New("private key parse failed"))
	ErrSecretValueNil             = apperrors.SecretValueNil()
	ErrSecretRetrievalRetries     = apperrors.SecretRetrievalRetriesFailed(errors.New("secret retrieval retries failed"))

	// Audit logging errors
	ErrAuditEventMarshal          = apperrors.AuditEventMarshalFailed(errors.New("audit event marshal failed"))
	ErrSIEMRequestCreation        = apperrors.SIEMRequestCreationFailed(errors.New("SIEM request creation failed"))
	ErrSIEMTransmission           = apperrors.SIEMTransmissionFailed(errors.New("SIEM transmission failed"))
	ErrSIEMResponseError          = apperrors.SIEMResponseError()
	ErrAuditRepositoryUnavailable = apperrors.AuditRepositoryUnavailable()

	// Rate limiting operation errors
	ErrIPRateLimitCheck       = apperrors.IPRateLimitCheckFailed(errors.New("IP rate limit check failed"))
	ErrAccountRateLimitCheck  = apperrors.AccountRateLimitCheckFailed(errors.New("account rate limit check failed"))
	ErrRecordIPAttempt        = apperrors.RecordIPAttemptFailed(errors.New("record IP attempt failed"))
	ErrRecordAccountAttempt   = apperrors.RecordAccountAttemptFailed(errors.New("record account attempt failed"))
	ErrGetIPAttemptCount      = apperrors.GetIPAttemptCountFailed(errors.New("get IP attempt count failed"))
	ErrGetAccountAttemptCount = apperrors.GetAccountAttemptCountFailed(errors.New("get account attempt count failed"))
	ErrImposeIPLockout        = apperrors.ImposeIPLockoutFailed(errors.New("impose IP lockout failed"))
	ErrImposeAccountLockout   = apperrors.ImposeAccountLockoutFailed(errors.New("impose account lockout failed"))

	// Session management errors
	ErrRefreshTokenGeneration    = apperrors.RefreshTokenGenerationFailed(errors.New("refresh token generation failed"))
	ErrDeviceIDRetrieval         = apperrors.DeviceIDRetrievalFailed(errors.New("device ID retrieval failed"))
	ErrSessionStorage            = apperrors.SessionStorageFailed(errors.New("session storage failed"))
	ErrNewRefreshTokenGeneration = apperrors.NewRefreshTokenGenerationFailed(errors.New("new refresh token generation failed"))
	ErrSessionUpdate             = apperrors.SessionUpdateFailed(errors.New("session update failed"))
	ErrUserSessionsRetrieval     = apperrors.UserSessionsRetrievalFailed(errors.New("user sessions retrieval failed"))
	ErrOldestSessionRemoval      = apperrors.OldestSessionRemovalFailed(errors.New("oldest session removal failed"))
	ErrInvalidRefreshToken       = apperrors.RefreshTokenInvalid()
	ErrSessionNotFound           = apperrors.SessionNotFound("")
	ErrSessionExpired            = apperrors.SessionExpired()
	ErrDeviceNotFound            = apperrors.DeviceNotFound("")

	// Device fingerprinting errors
	ErrUserDevicesRetrieval = apperrors.UserDevicesRetrievalFailed(errors.New("user devices retrieval failed"))
	ErrDeviceCreation       = apperrors.DeviceCreationFailed(errors.New("device creation failed"))
	ErrMaxDevicesExceeded   = apperrors.MaxDevicesExceeded()

	// Device ownership errors
	ErrDeviceOwnershipMismatch = apperrors.DeviceOwnershipMismatch()

	// JWT validation errors
	ErrJWTUnexpectedSigningMethod = apperrors.JWTUnexpectedSigningMethod()

	// Recovery federation errors
	ErrInvalidActivityObject           = apperrors.InvalidActivityObject()
	ErrNotRecoveryConfirmationActivity = apperrors.NotRecoveryConfirmationActivity()
	ErrMissingRequestID                = apperrors.MissingRequestID()
	ErrFailedToDecodePEM               = apperrors.FailedToDecodePEM()
	ErrUnsupportedPrivateKeyType       = apperrors.UnsupportedPrivateKeyType()
	ErrSecretsManagerNotAvailable      = apperrors.SecretsManagerNotAvailable()
	ErrSigningActorRetrievalFailed     = apperrors.SigningActorRetrievalFailed(errors.New("signing actor retrieval failed"))
	ErrRecoveryConfirmationFailed      = apperrors.RecoveryConfirmationFailed(errors.New("recovery confirmation failed"))
	ErrActorRetrievalFailed            = apperrors.ActorRetrievalFailed(errors.New("actor retrieval failed"))
	ErrPrivateKeyParseFailed           = apperrors.PrivateKeyParseFailed(errors.New("private key parse failed"))
	ErrPublicKeyMarshalFailed          = apperrors.PublicKeyMarshalFailed(errors.New("public key marshal failed"))
	ErrSystemActorKeyRetrievalFailed   = apperrors.SystemActorKeyRetrievalFailed(errors.New("system actor key retrieval failed"))
	ErrSystemActorKeyRotationFailed    = apperrors.SystemActorKeyRotationFailed(errors.New("system actor key rotation failed"))

	// Session lifecycle errors
	ErrSessionSecurityValidationFailed = apperrors.SessionSecurityValidationFailed("")
	ErrSessionCannotBeExtended         = apperrors.SessionCannotBeExtended("")
	ErrSessionMaxLifetimeReached       = apperrors.SessionMaxLifetimeReached()
	ErrSessionExtensionDisabled        = apperrors.SessionExtensionDisabled()
	ErrConcurrentSessionLimitExceeded  = apperrors.ConcurrentSessionLimitExceeded()
	ErrRefreshTokenRotationFailed      = apperrors.RefreshTokenRotationFailed(errors.New("refresh token rotation failed"))
	ErrInvalidRefreshTokenProvided     = apperrors.InvalidRefreshTokenProvided()
	ErrSessionSecurityCheckFailed      = apperrors.SessionSecurityCheckFailed(errors.New("session security check failed"))

	// Auth service operation errors
	ErrSessionCreationFailed         = apperrors.SessionCreationFailed(errors.New("session creation failed"))
	ErrAccessTokenGenerationFailed   = apperrors.AccessTokenGenerationFailed(errors.New("access token generation failed"))
	ErrPasswordHashingFailed         = apperrors.PasswordHashingFailed(errors.New("password hashing failed"))
	ErrPasswordUpdateFailed          = apperrors.PasswordUpdateFailed(errors.New("password update failed"))
	ErrSignatureVerificationFailed   = apperrors.SignatureVerificationFailed()
	ErrUserRetrievalFailed           = apperrors.UserRetrievalFailed(errors.New("user retrieval failed"))
	ErrRecoveryTokenGenerationFailed = apperrors.RecoveryTokenGenerationFailed(errors.New("recovery token generation failed"))
	ErrRecoveryTokenStorageFailed    = apperrors.RecoveryTokenStorageFailed(errors.New("recovery token storage failed"))

	// Common authentication errors (moved from service.go)
	ErrInvalidCredentials    = apperrors.InvalidCredentials()
	ErrUserNotFound          = apperrors.UserNotFound("")
	ErrUserSuspended         = apperrors.UserSuspended("")
	ErrUserNotApproved       = apperrors.UserNotApproved("")
	ErrInvalidToken          = apperrors.TokenInvalid("")
	ErrWebAuthnNotConfigured = apperrors.WebAuthnNotConfigured()
)

Legacy error variables for backwards compatibility These are now wrappers around the centralized error system

View Source
var (
	// ErrMissingAuthHeader is returned when Authorization header is missing
	ErrMissingAuthHeader = errors.New("missing authorization header")
	// ErrInvalidAuthHeader is returned when Authorization header is malformed
	ErrInvalidAuthHeader = errors.New("invalid authorization header")
)
View Source
var (
	// ErrInvalidGrant is returned when the authorization code is invalid or expired
	ErrInvalidGrant = errors.New("invalid_grant")
	// ErrInvalidClient is returned when the client is not authorized
	ErrInvalidClient = errors.New("invalid_client")
	// ErrInvalidRequest is returned when the request is malformed
	ErrInvalidRequest = errors.New("invalid_request")
	// ErrUnauthorizedClient is returned when the client is not authorized for this grant type
	ErrUnauthorizedClient = errors.New("unauthorized_client")
	// ErrUnsupportedGrantType is returned when the grant type is not supported
	ErrUnsupportedGrantType = errors.New("unsupported_grant_type")
	// ErrInvalidCodeChallenge is returned when the code challenge doesn't match
	ErrInvalidCodeChallenge = errors.New("invalid_code_challenge")
	// ErrInvalidScope is returned when requested scopes are invalid
	ErrInvalidScope = errors.New("invalid_scope")
	// ErrInvalidAPIKey is returned when the API key is invalid
	ErrInvalidAPIKey = errors.New("invalid_api_key")
)
View Source
var (
	ErrTooManyAttempts = errors.New("too many login attempts")
	ErrAccountLocked   = errors.New("account temporarily locked")
	ErrIPRateLimited   = errors.New("IP address rate limited")
)

Rate limiting errors

View Source
var (
	// ErrTokenReuse indicates a refresh token was reused (security breach)
	ErrTokenReuse = errors.New("refresh token reuse detected")
	// ErrExpiredRefreshToken indicates the refresh token has expired
	ErrExpiredRefreshToken = errors.New("refresh token expired")
)
View Source
var (
	ErrChallengeNotFound    = errors.New("challenge not found or expired")
	ErrCredentialNotFound   = errors.New("credential not found")
	ErrInvalidCredential    = errors.New("invalid credential")
	ErrUserHasNoCredentials = errors.New("user has no credentials")
)

WebAuthn errors

View Source
var DefaultPasswordStrengthConfig = PasswordStrengthConfig{
	MinLength:  8,
	LongLength: 16,
	LongBonus:  1,

	RequireAllCharacterTypesForLongBonus: true,
	SequentialPenalty:                    2,
	SequentialPatternMinRun:              4,
	RepeatedPenalty:                      1,
}

DefaultPasswordStrengthConfig matches the built-in strength scoring used by PasswordStrength.

View Source
var DefaultPolicy = PasswordPolicy{
	MinLength:              12,
	RequireUppercase:       true,
	RequireLowercase:       true,
	RequireNumbers:         true,
	RequireSpecialChars:    true,
	PreventCommonPasswords: true,
}

DefaultPolicy defines the default password requirements

Functions

func AdminAuth

func AdminAuth(config MiddlewareConfig) apptheory.Middleware

AdminAuth creates middleware specifically for admin operations

func CSRFMiddleware

func CSRFMiddleware(manager *CSRFManager) func(http.HandlerFunc) http.HandlerFunc

CSRFMiddleware creates middleware for CSRF protection

func ConstantTimeCompare

func ConstantTimeCompare(a, b string) bool

ConstantTimeCompare performs a constant-time comparison of two strings

func ConstantTimeComparePadded

func ConstantTimeComparePadded(a, b string) bool

ConstantTimeComparePadded performs a constant-time comparison without early exit on length mismatch. Length still influences runtime due to required padding work; for secrets of fixed length this is acceptable.

func ConstantTimeDelay

func ConstantTimeDelay()

ConstantTimeDelay adds a small random delay to prevent timing analysis

func CreateAPIAuthMiddleware

func CreateAPIAuthMiddleware(oauthService common.OAuthServiceInterface, logger *zap.Logger) apptheory.Middleware

CreateAPIAuthMiddleware creates standard API authentication middleware

func CreateAPIAuthMiddlewareFromAuthService

func CreateAPIAuthMiddlewareFromAuthService(authService *AuthService, logger *zap.Logger) apptheory.Middleware

CreateAPIAuthMiddlewareFromAuthService creates API auth middleware from AuthService

func CreateFederationAuthMiddleware

func CreateFederationAuthMiddleware(oauthService common.OAuthServiceInterface, logger *zap.Logger) apptheory.Middleware

CreateFederationAuthMiddleware creates federation-specific authentication middleware

func CreateFederationAuthMiddlewareFromAuthService

func CreateFederationAuthMiddlewareFromAuthService(authService *AuthService, logger *zap.Logger) apptheory.Middleware

CreateFederationAuthMiddlewareFromAuthService creates federation auth middleware from AuthService

func CreateGraphQLAuthMiddleware

func CreateGraphQLAuthMiddleware(oauthService common.OAuthServiceInterface, logger *zap.Logger) apptheory.Middleware

CreateGraphQLAuthMiddleware creates standard GraphQL authentication middleware

func CreateGraphQLAuthMiddlewareFromAuthService

func CreateGraphQLAuthMiddlewareFromAuthService(authService *AuthService, logger *zap.Logger) apptheory.Middleware

CreateGraphQLAuthMiddlewareFromAuthService creates GraphQL auth middleware from AuthService

func DefaultScopes

func DefaultScopes() []string

DefaultScopes returns the default scopes for a user

func ExtractBearerToken

func ExtractBearerToken(authHeader string) (string, error)

ExtractBearerToken extracts the token from the Authorization header

func FollowAuth

func FollowAuth(config MiddlewareConfig) apptheory.Middleware

FollowAuth creates middleware specifically for follow operations

func GenerateCSRFTokenHandler

func GenerateCSRFTokenHandler(manager *CSRFManager) http.HandlerFunc

GenerateCSRFTokenHandler creates an endpoint to get CSRF tokens

func GeneratePasswordHint

func GeneratePasswordHint(password string) []string

GeneratePasswordHint provides helpful hints for password improvement

func GetAuthenticatedUsername

func GetAuthenticatedUsername(ctx *apptheory.Context) string

GetAuthenticatedUsername retrieves the authenticated username or empty string

func GetJWTClaims

func GetJWTClaims(ctx *apptheory.Context) common.Claims

GetJWTClaims retrieves the JWT claims from context

func GetLegacyAuthContext

func GetLegacyAuthContext(ctx *apptheory.Context) *common.AuthContext

GetLegacyAuthContext retrieves the authentication context from the request context.

func GetUsernameFromContext

func GetUsernameFromContext(ctx *apptheory.Context, oauthService OAuthServiceInterface) (string, error)

GetUsernameFromContext extracts just the username from the context This consolidates the pattern: username, err := h.authenticateRequestWithScope(ctx, "read")

func GetUsernameFromStandardContext

func GetUsernameFromStandardContext(ctx context.Context) (string, error)

GetUsernameFromStandardContext extracts username from standard context

func HashOAuthClientSecret

func HashOAuthClientSecret(secret string) (string, error)

HashOAuthClientSecret hashes an OAuth client secret for storage.

func HashPassword

func HashPassword(password string) (string, error)

HashPassword hashes a password using bcrypt

func IsAuthenticated

func IsAuthenticated(ctx *apptheory.Context) bool

IsAuthenticated returns true if the request is authenticated

func IsCommonPassword

func IsCommonPassword(password string) bool

IsCommonPassword checks if a password is in the common passwords list

func IsTestMode

func IsTestMode(_ *apptheory.Context) bool

IsTestMode determines if the current request is in test mode

func OptionalAuth

func OptionalAuth(config MiddlewareConfig) apptheory.Middleware

OptionalAuth creates middleware that provides optional authentication

func ParseAgentPublicKey

func ParseAgentPublicKey(keyType string, publicKey string) (crypto.PublicKey, error)

ParseAgentPublicKey parses an agent-provided public key for supported key types ("ed25519", "rsa").

func PasswordStrength

func PasswordStrength(password string) int

PasswordStrength calculates password strength score (0-5).

The score is based on how many character classes are present (lower/upper/number/special), plus a long-password bonus (default: length >= 16 and all classes), with penalties for sequential or repeated-character patterns.

func PasswordStrengthLabel

func PasswordStrengthLabel(strength int) string

PasswordStrengthLabel returns a human-readable strength label

func PasswordStrengthWithConfig

func PasswordStrengthWithConfig(password string, cfg PasswordStrengthConfig) int

PasswordStrengthWithConfig calculates password strength score (0-5) using the provided config.

func ReadAuth

func ReadAuth(config MiddlewareConfig) apptheory.Middleware

ReadAuth creates middleware specifically for read operations

func RequireAuth

func RequireAuth(ctx *apptheory.Context, oauthService OAuthServiceInterface) error

RequireAuth ensures the request is authenticated This consolidates the pattern of checking if username is empty after auth

func RequireAuthFromStandardContext

func RequireAuthFromStandardContext(ctx context.Context) error

RequireAuthFromStandardContext ensures standard context contains authenticated account

func RequireReadAccess

func RequireReadAccess(ctx *apptheory.Context) error

RequireReadAccess validates that the current request has read access

func RequireWriteAccess

func RequireWriteAccess(ctx *apptheory.Context) error

RequireWriteAccess validates that the current request has write access

func RequiredAuth

func RequiredAuth(config MiddlewareConfig) apptheory.Middleware

RequiredAuth creates middleware that requires authentication with a specific scope

func RequiredAuthWithMultipleScopes

func RequiredAuthWithMultipleScopes(config MiddlewareConfig) apptheory.Middleware

RequiredAuthWithMultipleScopes creates middleware that requires one of multiple scopes

func SetAccountInStandardContext

func SetAccountInStandardContext(ctx context.Context, account *AuthenticatedAccount) context.Context

SetAccountInStandardContext stores authenticated account in standard context

func SetAuthContext

func SetAuthContext(ctx *apptheory.Context, authCtx *Context)

SetAuthContext stores authentication context in an AppTheory context.

func TimingSafeStringSliceContains

func TimingSafeStringSliceContains(slice []string, target string) bool

TimingSafeStringSliceContains checks if a string is in a slice with timing protection

func TimingSafeTokenValidation

func TimingSafeTokenValidation(providedToken, storedToken string) bool

TimingSafeTokenValidation validates tokens with timing attack protection

func ToWebAuthnCredential

func ToWebAuthnCredential(c *storage.WebAuthnCredential) *webauthn.Credential

ToWebAuthnCredential converts to the webauthn library credential type

func ValidateAPIKey

func ValidateAPIKey(provided string, getStoredKey func() (string, error)) error

ValidateAPIKey validates an API key with timing attack protection

func ValidateAccountOwnership

func ValidateAccountOwnership(account *AuthenticatedAccount, targetUsername string) error

ValidateAccountOwnership checks if the authenticated user owns the specified account This consolidates the pattern: if username != targetUsername { return forbidden }

func ValidateAccountOwnershipOrAdmin

func ValidateAccountOwnershipOrAdmin(account *AuthenticatedAccount, targetUsername string) error

ValidateAccountOwnershipOrAdmin checks if the user owns the account or is admin

func ValidatePassword

func ValidatePassword(password string, username string) error

ValidatePassword checks if a password meets security requirements

func ValidateScopes

func ValidateScopes(scopes []string) error

ValidateScopes checks if the requested scopes are valid globally

func ValidateSessionToken

func ValidateSessionToken(token string, validateFunc func(string) (bool, error)) error

ValidateSessionToken validates a session token with timing protection

func VerifyAgentChallengeSignature

func VerifyAgentChallengeSignature(keyType string, publicKey string, message string, signatureBase64 string) error

VerifyAgentChallengeSignature verifies a base64 signature over the server-provided challenge message.

func VerifyOAuthClientSecret

func VerifyOAuthClientSecret(providedSecret, storedValue string) (bool, bool, error)

VerifyOAuthClientSecret verifies a provided OAuth client secret against a stored value.

func VerifyPassword

func VerifyPassword(password, hash string) error

VerifyPassword checks if a password matches the hash

func WithClaims

func WithClaims(ctx context.Context, claims *Claims) context.Context

WithClaims adds claims to the context

func WriteAuth

func WriteAuth(config MiddlewareConfig) apptheory.Middleware

WriteAuth creates middleware specifically for write operations

Types

type AWSSecretsManager

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

AWSSecretsManager implements SecretsManager using AWS Secrets Manager

func NewAWSSecretsManager

func NewAWSSecretsManager(cfg SecretsManagerConfig, logger *zap.Logger) (*AWSSecretsManager, error)

NewAWSSecretsManager creates a new AWS Secrets Manager client

func (*AWSSecretsManager) CleanupCache

func (sm *AWSSecretsManager) CleanupCache()

CleanupCache removes expired entries from cache

func (*AWSSecretsManager) DeletePrivateKey

func (sm *AWSSecretsManager) DeletePrivateKey(ctx context.Context, keyID string) error

DeletePrivateKey deletes a private key from AWS Secrets Manager

func (*AWSSecretsManager) GenerateAndStoreKeyPair

func (sm *AWSSecretsManager) GenerateAndStoreKeyPair(ctx context.Context, keyID string) (publicKeyPEM, privateKeyPEM string, err error)

GenerateAndStoreKeyPair generates a new RSA key pair and stores it

func (*AWSSecretsManager) GetCacheStats

func (sm *AWSSecretsManager) GetCacheStats() map[string]interface{}

GetCacheStats returns cache statistics for monitoring

func (*AWSSecretsManager) RetrievePrivateKey

func (sm *AWSSecretsManager) RetrievePrivateKey(ctx context.Context, keyID string) (string, error)

RetrievePrivateKey retrieves a private key from AWS Secrets Manager

func (*AWSSecretsManager) RotateKey

func (sm *AWSSecretsManager) RotateKey(ctx context.Context, keyID string) (publicKeyPEM, privateKeyPEM string, err error)

RotateKey generates a new key pair and replaces the existing one

func (*AWSSecretsManager) StorePrivateKey

func (sm *AWSSecretsManager) StorePrivateKey(ctx context.Context, keyID, privateKeyPEM string) error

StorePrivateKey stores a private key in AWS Secrets Manager

type AdvancedSessionSecurityConfig

type AdvancedSessionSecurityConfig struct {
	EnableIPBinding            bool          // Bind sessions to IP addresses
	EnableDeviceFingerprinting bool          // Use device fingerprinting
	EnableGeoValidation        bool          // Validate geographic location
	MaxConcurrentSessions      int           // Max sessions per user
	SessionFixationPrevention  bool          // Prevent session fixation attacks
	CSRFProtection             bool          // Enable CSRF token validation
	SecureCookiesOnly          bool          // Only use secure cookies
	StrictSameSite             bool          // Use strict SameSite policy
	SessionTimeout             time.Duration // Auto-logout timeout
	GracePeriod                time.Duration // Token rotation grace period
}

AdvancedSessionSecurityConfig holds advanced security configuration

func DefaultAdvancedSessionSecurityConfig

func DefaultAdvancedSessionSecurityConfig() *AdvancedSessionSecurityConfig

DefaultAdvancedSessionSecurityConfig provides secure defaults

type AuditConfig

type AuditConfig struct {
	// Enable/disable audit logging
	Enabled bool

	// Storage configuration
	StoreToDB   bool
	StoreToFile bool
	StoreToSIEM bool // Security Information and Event Management

	// Log levels
	LogSuccessfulAuth bool
	LogFailedAuth     bool
	LogSecurityEvents bool
	LogAPIAccess      bool

	// Data retention
	RetentionDays int

	// Privacy settings
	HashIPAddresses    bool
	RedactSensitive    bool
	AnonymizeAfterDays int

	// Alert thresholds
	FailedLoginThreshold     int
	SuspiciousIPThreshold    int
	AlertOnAnomalousLocation bool
	AlertOnNewDevice         bool

	// SIEM integration
	SIEMEndpoint string
	SIEMAPIKey   string
}

AuditConfig defines audit logging configuration

func DefaultAuditConfig

func DefaultAuditConfig() *AuditConfig

DefaultAuditConfig returns default audit configuration

type AuditEvent

type AuditEvent struct {
	ID            string                 `json:"id"`
	Timestamp     time.Time              `json:"timestamp"`
	EventType     AuditEventType         `json:"event_type"`
	Severity      AuditSeverity          `json:"severity"`
	Username      string                 `json:"username,omitempty"`
	UserID        string                 `json:"user_id,omitempty"`
	IPAddress     string                 `json:"ip_address"`
	UserAgent     string                 `json:"user_agent,omitempty"`
	DeviceName    string                 `json:"device_name,omitempty"`
	SessionID     string                 `json:"session_id,omitempty"`
	RequestID     string                 `json:"request_id,omitempty"`
	Success       bool                   `json:"success"`
	FailureReason string                 `json:"failure_reason,omitempty"`
	Metadata      map[string]interface{} `json:"metadata,omitempty"`

	// Geographic information
	Country   string  `json:"country,omitempty"`
	City      string  `json:"city,omitempty"`
	Region    string  `json:"region,omitempty"`
	Latitude  float64 `json:"latitude,omitempty"`
	Longitude float64 `json:"longitude,omitempty"`

	// Risk assessment
	RiskScore float64  `json:"risk_score,omitempty"`
	RiskFlags []string `json:"risk_flags,omitempty"`

	// Compliance fields
	DataRetentionDays int      `json:"data_retention_days,omitempty"`
	ComplianceFlags   []string `json:"compliance_flags,omitempty"`
}

AuditEvent represents an authentication audit log entry

type AuditEventType

type AuditEventType string

AuditEventType represents the type of authentication event

const (
	// AuditLoginSuccess represents a successful login attempt
	AuditLoginSuccess AuditEventType = "auth.login.success"
	// AuditLoginFailed represents a failed login attempt
	AuditLoginFailed AuditEventType = "auth.login.failed"
	// AuditLoginRateLimited represents a login attempt blocked by rate limiting
	AuditLoginRateLimited AuditEventType = "auth.login.rate_limited"
	// AuditLoginSuspended represents a login attempt by a suspended user
	AuditLoginSuspended AuditEventType = "auth.login.suspended"
	// AuditLoginNotApproved represents a login attempt that was not approved
	AuditLoginNotApproved AuditEventType = "auth.login.not_approved"
	// AuditLoginTwoFactorRequired represents a login attempt requiring 2FA
	AuditLoginTwoFactorRequired AuditEventType = "auth.login.2fa_required"
	// AuditLoginTwoFactorFailed represents a failed 2FA login attempt
	AuditLoginTwoFactorFailed AuditEventType = "auth.login.2fa_failed"

	// AuditLogout represents a user logout event
	AuditLogout AuditEventType = "auth.logout"
	// AuditLogoutAllDevices represents a logout from all devices event
	AuditLogoutAllDevices AuditEventType = "auth.logout.all_devices"

	// AuditRegistrationStarted represents the start of user registration
	AuditRegistrationStarted AuditEventType = "auth.registration.started"
	// AuditRegistrationCompleted represents the completion of user registration
	AuditRegistrationCompleted AuditEventType = "auth.registration.completed"
	// AuditRegistrationFailed represents a failed user registration
	AuditRegistrationFailed AuditEventType = "auth.registration.failed"
	// AuditEmailVerification represents an email verification event
	AuditEmailVerification AuditEventType = "auth.registration.email_verified"

	// AuditPasswordResetRequested represents a password reset request
	AuditPasswordResetRequested AuditEventType = "auth.password.reset_requested"
	// AuditPasswordResetCompleted represents a completed password reset
	AuditPasswordResetCompleted AuditEventType = "auth.password.reset_completed"
	// AuditPasswordChanged represents a successful password change
	AuditPasswordChanged AuditEventType = "auth.password.changed"
	// AuditPasswordChangeFailed represents a failed password change attempt
	AuditPasswordChangeFailed AuditEventType = "auth.password.change_failed"

	// AuditOAuthAuthorizeStarted represents the start of OAuth authorization
	AuditOAuthAuthorizeStarted AuditEventType = "auth.oauth.authorize_started" // #nosec G101 -- audit event type, not a credential
	// AuditOAuthAuthorizeCompleted represents completed OAuth authorization
	AuditOAuthAuthorizeCompleted AuditEventType = "auth.oauth.authorize_completed" // #nosec G101 -- audit event type, not a credential
	// AuditOAuthAuthorizeFailed represents a failed OAuth authorization
	AuditOAuthAuthorizeFailed AuditEventType = "auth.oauth.authorize_failed" // #nosec G101 -- audit event type, not a credential
	// AuditOAuthTokenIssued represents an OAuth token being issued
	AuditOAuthTokenIssued AuditEventType = "auth.oauth.token_issued" // #nosec G101 -- audit event type, not a credential
	// AuditOAuthTokenRefreshed represents an OAuth token being refreshed
	AuditOAuthTokenRefreshed AuditEventType = "auth.oauth.token_refreshed" // #nosec G101 -- audit event type, not a credential
	// AuditOAuthTokenRevoked represents an OAuth token being revoked
	AuditOAuthTokenRevoked AuditEventType = "auth.oauth.token_revoked" // #nosec G101 -- audit event type, not a credential
	// AuditOAuthTokenFailed represents a failed OAuth token operation
	AuditOAuthTokenFailed AuditEventType = "auth.oauth.token_failed" // #nosec G101 -- audit event type, not a credential

	// AuditWebAuthnRegistrationStarted represents the start of WebAuthn credential registration
	AuditWebAuthnRegistrationStarted AuditEventType = "auth.webauthn.registration_started" // #nosec G101 -- audit event type, not a credential
	// AuditWebAuthnRegistrationCompleted represents the completion of WebAuthn credential registration
	AuditWebAuthnRegistrationCompleted AuditEventType = "auth.webauthn.registration_completed" // #nosec G101 -- audit event type, not a credential
	// AuditWebAuthnRegistrationFailed represents a failed WebAuthn credential registration
	AuditWebAuthnRegistrationFailed AuditEventType = "auth.webauthn.registration_failed" // #nosec G101 -- audit event type, not a credential
	// AuditWebAuthnLoginStarted represents the start of a WebAuthn login attempt
	AuditWebAuthnLoginStarted AuditEventType = "auth.webauthn.login_started" // #nosec G101 -- audit event type, not a credential
	// AuditWebAuthnLoginCompleted represents a successful WebAuthn login
	AuditWebAuthnLoginCompleted AuditEventType = "auth.webauthn.login_completed" // #nosec G101 -- audit event type, not a credential
	// AuditWebAuthnLoginFailed represents a failed WebAuthn login attempt
	AuditWebAuthnLoginFailed AuditEventType = "auth.webauthn.login_failed" // #nosec G101 -- audit event type, not a credential
	// AuditWebAuthnCredentialRemoved represents a WebAuthn credential being removed
	AuditWebAuthnCredentialRemoved AuditEventType = "auth.webauthn.credential_removed" // #nosec G101 -- audit event type, not a credential

	// AuditWalletConnected represents a successful wallet connection
	AuditWalletConnected AuditEventType = "auth.wallet.connected"
	// AuditWalletDisconnected represents a wallet being disconnected
	AuditWalletDisconnected AuditEventType = "auth.wallet.disconnected"
	// AuditWalletLoginStarted represents the start of a wallet-based login attempt
	AuditWalletLoginStarted AuditEventType = "auth.wallet.login_started"
	// AuditWalletLoginCompleted represents a successful wallet-based login
	AuditWalletLoginCompleted AuditEventType = "auth.wallet.login_completed"
	// AuditWalletLoginFailed represents a failed wallet-based login attempt
	AuditWalletLoginFailed AuditEventType = "auth.wallet.login_failed"

	// AuditSessionCreated represents a new session creation
	AuditSessionCreated AuditEventType = "auth.session.created"
	// AuditSessionRefreshed represents a session being refreshed
	AuditSessionRefreshed AuditEventType = "auth.session.refreshed"
	// AuditSessionRevoked represents a session being manually revoked
	AuditSessionRevoked AuditEventType = "auth.session.revoked"
	// AuditSessionExpired represents a session expiring naturally
	AuditSessionExpired AuditEventType = "auth.session.expired"
	// AuditSessionInvalidated represents a session being invalidated
	AuditSessionInvalidated AuditEventType = "auth.session.invalidated"

	// AuditSuspiciousActivity represents detected suspicious authentication activity
	AuditSuspiciousActivity AuditEventType = "auth.security.suspicious_activity"
	// AuditAccountLocked represents an account being locked due to security concerns
	AuditAccountLocked AuditEventType = "auth.security.account_locked"
	// AuditAccountUnlocked represents an account being unlocked
	AuditAccountUnlocked AuditEventType = "auth.security.account_unlocked"
	// AuditIPBlocked represents an IP address being blocked
	AuditIPBlocked AuditEventType = "auth.security.ip_blocked"
	// AuditIPUnblocked represents an IP address being unblocked
	AuditIPUnblocked AuditEventType = "auth.security.ip_unblocked"
	// AuditBruteForceDetected represents detection of a brute force attack
	AuditBruteForceDetected AuditEventType = "auth.security.brute_force_detected"
	// AuditAnomalousLocation represents a login from an unusual location
	AuditAnomalousLocation AuditEventType = "auth.security.anomalous_location"
	// AuditDeviceNotRecognized represents a login from an unrecognized device
	AuditDeviceNotRecognized AuditEventType = "auth.security.device_not_recognized"

	// AuditAPIKeyCreated represents API key creation event
	AuditAPIKeyCreated AuditEventType = "auth.api_key.created" // #nosec G101 -- audit event type, not a credential
	// AuditAPIKeyRevoked represents an API key being revoked
	AuditAPIKeyRevoked AuditEventType = "auth.api_key.revoked" // #nosec G101 -- audit event type, not a credential
	// AuditAPIKeyUsed represents an API key being used for authentication
	AuditAPIKeyUsed AuditEventType = "auth.api_key.used" // #nosec G101 -- audit event type, not a credential
	// AuditAPIKeyFailed represents a failed API key authentication attempt
	AuditAPIKeyFailed AuditEventType = "auth.api_key.failed" // #nosec G101 -- audit event type, not a credential

	// AuditTwoFactorEnabled represents two-factor authentication being enabled
	AuditTwoFactorEnabled AuditEventType = "auth.2fa.enabled"
	// AuditTwoFactorDisabled represents two-factor authentication being disabled
	AuditTwoFactorDisabled AuditEventType = "auth.2fa.disabled"
	// AuditTwoFactorVerified represents successful two-factor authentication verification
	AuditTwoFactorVerified AuditEventType = "auth.2fa.verified"
	// AuditTwoFactorFailed represents a failed two-factor authentication attempt
	AuditTwoFactorFailed AuditEventType = "auth.2fa.failed"
	// AuditRecoveryCodeUsed represents a 2FA recovery code being used
	AuditRecoveryCodeUsed AuditEventType = "auth.2fa.recovery_code_used"
)

type AuditLogger

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

AuditLogger handles authentication audit logging

func NewAuditLogger

func NewAuditLogger(repos StorageProvider, logger *zap.Logger, config *AuditConfig) *AuditLogger

NewAuditLogger creates a new audit logger

func (*AuditLogger) GetIPAuditLogs

func (al *AuditLogger) GetIPAuditLogs(ctx context.Context, ipAddress string, limit int) ([]*AuditEvent, error)

GetIPAuditLogs retrieves audit logs for a specific IP address

func (*AuditLogger) GetSecurityEvents

func (al *AuditLogger) GetSecurityEvents(ctx context.Context, startTime, endTime time.Time, severityFilter []AuditSeverity) ([]*AuditEvent, error)

GetSecurityEvents retrieves security events within a time range

func (*AuditLogger) GetSessionAuditLogs

func (al *AuditLogger) GetSessionAuditLogs(ctx context.Context, sessionID string) ([]*AuditEvent, error)

GetSessionAuditLogs retrieves audit logs for a specific session

func (*AuditLogger) GetUserAuditLogs

func (al *AuditLogger) GetUserAuditLogs(ctx context.Context, username string, limit int) ([]*AuditEvent, error)

GetUserAuditLogs retrieves audit logs for a specific user

func (*AuditLogger) LogEvent

func (al *AuditLogger) LogEvent(ctx context.Context, event *AuditEvent) error

LogEvent logs an authentication event

func (*AuditLogger) LogLogin

func (al *AuditLogger) LogLogin(ctx context.Context, username, ipAddress, userAgent, deviceName string, success bool, failureReason string)

LogLogin logs a login attempt

func (*AuditLogger) LogOAuthToken

func (al *AuditLogger) LogOAuthToken(ctx context.Context, clientID, username, ipAddress string, eventType AuditEventType, scopes []string, success bool, err error)

LogOAuthToken logs OAuth token operations

func (*AuditLogger) LogSecurityEvent

func (al *AuditLogger) LogSecurityEvent(ctx context.Context, eventType AuditEventType, username, ipAddress string, metadata map[string]interface{})

LogSecurityEvent logs security-related events

func (*AuditLogger) LogSession

func (al *AuditLogger) LogSession(ctx context.Context, username, sessionID, ipAddress string, eventType AuditEventType)

LogSession logs session operations

func (*AuditLogger) LogWebAuthn

func (al *AuditLogger) LogWebAuthn(ctx context.Context, username, ipAddress, userAgent string, eventType AuditEventType, credentialID string, success bool, err error)

LogWebAuthn logs WebAuthn operations

type AuditSeverity

type AuditSeverity string

AuditSeverity represents the severity level of an audit event

const (
	// SeverityInfo represents informational audit events
	SeverityInfo AuditSeverity = "info"
	// SeverityWarning represents warning-level audit events
	SeverityWarning AuditSeverity = "warning"
	// SeverityError represents an error-level audit event
	SeverityError AuditSeverity = "error"
	// SeverityCritical represents a critical-level audit event
	SeverityCritical AuditSeverity = "critical"
)

type AuthResponse

type AuthResponse struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int    `json:"expires_in"`
	RefreshToken string `json:"refresh_token"`
	Scope        string `json:"scope"`
	CreatedAt    int64  `json:"created_at"`
	Me           string `json:"me,omitempty"`            // Username for Mastodon compatibility
	CredentialID string `json:"credential_id,omitempty"` // WebAuthn credential ID (if applicable)
}

AuthResponse represents an authentication response

type AuthService

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

AuthService provides comprehensive authentication functionality

func NewAuthService

func NewAuthService(cfg *config.Config, repos StorageProvider) (*AuthService, error)

NewAuthService creates a comprehensive auth service

func (*AuthService) AuthenticateWithPassword

func (as *AuthService) AuthenticateWithPassword(_ context.Context, _, _, _, _, _ string) (*AuthResponse, error)

AuthenticateWithPassword authenticates a user with username and password

func (*AuthService) BeginWebAuthnLogin

func (as *AuthService) BeginWebAuthnLogin(ctx context.Context, username string) (any, string, error)

BeginWebAuthnLogin starts the WebAuthn login process

func (*AuthService) BeginWebAuthnRegistration

func (as *AuthService) BeginWebAuthnRegistration(ctx context.Context, username string) (any, string, error)

BeginWebAuthnRegistration starts the WebAuthn registration process

func (*AuthService) ChangePassword

func (as *AuthService) ChangePassword(_ context.Context, _, _, _ string) error

ChangePassword changes a user's password

func (*AuthService) ClearAccountLockout

func (as *AuthService) ClearAccountLockout(ctx context.Context, username string) error

ClearAccountLockout clears rate limiting for a specific account (admin action)

func (*AuthService) CreateWalletChallenge

func (as *AuthService) CreateWalletChallenge(ctx context.Context, address string, chainID int, username string) (*storage.WalletChallenge, error)

CreateWalletChallenge creates a new authentication challenge for wallet signing

func (*AuthService) DeleteWebAuthnCredential

func (as *AuthService) DeleteWebAuthnCredential(ctx context.Context, username string, credentialID string) error

DeleteWebAuthnCredential removes a WebAuthn credential

func (*AuthService) FinishWebAuthnLogin

func (as *AuthService) FinishWebAuthnLogin(ctx context.Context, username string, challenge string, response []byte, deviceName, userAgent, ipAddress string) (*AuthResponse, error)

FinishWebAuthnLogin completes the WebAuthn login process and creates a session

func (*AuthService) FinishWebAuthnRegistration

func (as *AuthService) FinishWebAuthnRegistration(ctx context.Context, username string, challenge string, response []byte, credentialName string) error

FinishWebAuthnRegistration completes the WebAuthn registration process

func (*AuthService) GenerateAuthorizationCode

func (as *AuthService) GenerateAuthorizationCode() (string, error)

GenerateAuthorizationCode generates OAuth authorization code

func (*AuthService) GenerateRecoveryToken

func (as *AuthService) GenerateRecoveryToken(ctx context.Context, username string, recoveryMethod string) (string, error)

GenerateRecoveryToken generates a recovery token for WebAuthn/federation-based recovery

func (*AuthService) GetAccountStatus

func (as *AuthService) GetAccountStatus(ctx context.Context, username string) (*RateLimitStatus, error)

GetAccountStatus returns the rate limit status for an account

func (*AuthService) GetConfig

func (as *AuthService) GetConfig() *ServiceConfig

GetConfig returns configuration (for handlers that need environment info)

func (*AuthService) GetStore

func (as *AuthService) GetStore() StorageProvider

GetStore returns the repository storage instance (for handlers that need direct access)

func (*AuthService) GetUserDevices

func (as *AuthService) GetUserDevices(ctx context.Context, username string) ([]*Device, error)

GetUserDevices returns all devices for a user

func (*AuthService) GetUserWallets

func (as *AuthService) GetUserWallets(ctx context.Context, username string) ([]*storage.WalletCredential, error)

GetUserWallets returns all wallets linked to a user

func (*AuthService) GetWalletByAddress

func (as *AuthService) GetWalletByAddress(ctx context.Context, address string) (*storage.WalletCredential, error)

GetWalletByAddress retrieves a wallet by address

func (*AuthService) GetWalletChallenge

func (as *AuthService) GetWalletChallenge(ctx context.Context, challengeID string) (*storage.WalletChallenge, error)

GetWalletChallenge retrieves a wallet challenge by ID

func (*AuthService) GetWebAuthnCredentials

func (as *AuthService) GetWebAuthnCredentials(ctx context.Context, username string) ([]*storage.WebAuthnCredential, error)

GetWebAuthnCredentials returns all WebAuthn credentials for a user

func (*AuthService) LinkWallet

func (as *AuthService) LinkWallet(ctx context.Context, username, address string, chainID int, walletType string) error

LinkWallet links a wallet to an existing user account

func (*AuthService) LoginWithWallet

func (as *AuthService) LoginWithWallet(ctx context.Context, req *WalletVerifyRequest, deviceName, userAgent, ipAddress string) (*AuthResponse, error)

LoginWithWallet logs in a user with a wallet (wallet must already be linked)

func (*AuthService) LoginWithWalletAfterLinking

func (as *AuthService) LoginWithWalletAfterLinking(ctx context.Context, username, deviceName, userAgent, ipAddress string) (*AuthResponse, error)

LoginWithWalletAfterLinking creates a session and access token for a wallet-linked user without re-verifying signature Used after wallet linking during registration when signature was already verified

func (*AuthService) Logout

func (as *AuthService) Logout(ctx context.Context, sessionID string) error

Logout revokes a session

func (*AuthService) LogoutAllDevices

func (as *AuthService) LogoutAllDevices(ctx context.Context, username string) error

LogoutAllDevices revokes all sessions for a user

func (*AuthService) MarkWalletChallengeSpent

func (as *AuthService) MarkWalletChallengeSpent(ctx context.Context, challengeID string) error

MarkWalletChallengeSpent marks a wallet challenge as spent (second verification)

func (*AuthService) RefreshAccessToken

func (as *AuthService) RefreshAccessToken(ctx context.Context, refreshToken, ipAddress string) (*AuthResponse, error)

RefreshAccessToken exchanges a refresh token for a new access token

func (*AuthService) TrustDevice

func (as *AuthService) TrustDevice(ctx context.Context, username, deviceID string) error

TrustDevice marks a device as trusted

func (*AuthService) UnlinkWallet

func (as *AuthService) UnlinkWallet(ctx context.Context, username, address string) error

UnlinkWallet removes a wallet link from a user account

func (*AuthService) UpdateWebAuthnCredentialName

func (as *AuthService) UpdateWebAuthnCredentialName(ctx context.Context, username string, credentialID string, newName string) error

UpdateWebAuthnCredentialName updates the display name of a credential

func (*AuthService) ValidateAccessToken

func (as *AuthService) ValidateAccessToken(tokenString string) (*EnhancedClaims, error)

ValidateAccessToken validates and parses an enhanced JWT access token

func (*AuthService) ValidateClient

func (as *AuthService) ValidateClient(ctx context.Context, clientID, clientSecret string) error

ValidateClient validates OAuth client credentials

func (*AuthService) ValidateRedirectURI

func (as *AuthService) ValidateRedirectURI(ctx context.Context, clientID, redirectURI string) error

ValidateRedirectURI validates OAuth redirect URI

func (*AuthService) VerifySignatureOnly

func (as *AuthService) VerifySignatureOnly(ctx context.Context, challenge *storage.WalletChallenge, signature string) error

VerifySignatureOnly verifies a signature against a challenge without creating a session This is used for the second verification in the wallet link flow

func (*AuthService) VerifyWalletSignature

func (as *AuthService) VerifyWalletSignature(ctx context.Context, req *WalletVerifyRequest) error

VerifyWalletSignature verifies a wallet signature (for registration) This only verifies the signature - it does NOT create a session

type AuthenticatedAccount

type AuthenticatedAccount struct {
	Username string
	Claims   *Claims
}

AuthenticatedAccount represents an authenticated user account

func ExtractOptionalAuth

func ExtractOptionalAuth(ctx *apptheory.Context, oauthService OAuthServiceInterface) (*AuthenticatedAccount, error)

ExtractOptionalAuth extracts authentication if present, but doesn't require it This consolidates the pattern used in public endpoints that benefit from auth context

func GetAccountFromContext

func GetAccountFromContext(ctx *apptheory.Context, oauthService OAuthServiceInterface) (*AuthenticatedAccount, error)

GetAccountFromContext extracts the authenticated account from an AppTheory context. This consolidates the common pattern: claims, err := h.oauthService.ValidateAccessToken(token)

func GetAccountFromStandardContext

func GetAccountFromStandardContext(ctx context.Context) (*AuthenticatedAccount, error)

GetAccountFromStandardContext extracts authenticated account from standard context

func GetAuthenticatedAccountFromContext

func GetAuthenticatedAccountFromContext(ctx *apptheory.Context) (*AuthenticatedAccount, bool)

GetAuthenticatedAccountFromContext retrieves the account set by OptionalAuthMiddleware.

func RequireAdminScope

func RequireAdminScope(ctx *apptheory.Context, oauthService OAuthServiceInterface) (*AuthenticatedAccount, error)

RequireAdminScope is a convenience function for requiring admin access

func RequireAuthWithMultipleScopes

func RequireAuthWithMultipleScopes(ctx *apptheory.Context, oauthService OAuthServiceInterface, scopes []string) (*AuthenticatedAccount, error)

RequireAuthWithMultipleScopes allows any of the specified scopes This consolidates the pattern where either read OR write scope is acceptable

func RequireAuthWithScope

func RequireAuthWithScope(ctx *apptheory.Context, oauthService OAuthServiceInterface, scope string) (*AuthenticatedAccount, error)

RequireAuthWithScope ensures the request is authenticated with a specific scope This consolidates the most common auth pattern across all handlers

func RequireReadOrWriteScope

func RequireReadOrWriteScope(ctx *apptheory.Context, oauthService OAuthServiceInterface) (*AuthenticatedAccount, error)

RequireReadOrWriteScope allows either read or write scope

func RequireReadScope

func RequireReadScope(ctx *apptheory.Context, oauthService OAuthServiceInterface) (*AuthenticatedAccount, error)

RequireReadScope is a convenience function for requiring read access

func RequireWriteScope

func RequireWriteScope(ctx *apptheory.Context, oauthService OAuthServiceInterface) (*AuthenticatedAccount, error)

RequireWriteScope is a convenience function for requiring write access

type AuthenticationMiddleware

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

AuthenticationMiddleware provides a Lift middleware for authentication

func NewAuthenticationMiddleware

func NewAuthenticationMiddleware(oauthService OAuthServiceInterface) *AuthenticationMiddleware

NewAuthenticationMiddleware creates a new authentication middleware

func (*AuthenticationMiddleware) OptionalAuthMiddleware

func (am *AuthenticationMiddleware) OptionalAuthMiddleware() apptheory.Middleware

OptionalAuthMiddleware extracts optional auth and stores it in context for downstream handlers.

func (*AuthenticationMiddleware) RequireAuthMiddleware

func (am *AuthenticationMiddleware) RequireAuthMiddleware() apptheory.Middleware

RequireAuthMiddleware returns middleware that requires authentication.

func (*AuthenticationMiddleware) RequireScopeMiddleware

func (am *AuthenticationMiddleware) RequireScopeMiddleware(scope string) apptheory.Middleware

RequireScopeMiddleware returns middleware that requires a specific scope.

type CSRFManager

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

CSRFManager handles CSRF token operations

func NewCSRFManager

func NewCSRFManager(store CSRFStore) *CSRFManager

NewCSRFManager creates a new CSRF manager

func NewCSRFManagerWithDynamORM

func NewCSRFManagerWithDynamORM(db core.DB, tableName string, logger *zap.Logger) *CSRFManager

NewCSRFManagerWithDynamORM creates a CSRF manager with DynamORM store

func (*CSRFManager) GenerateToken

func (m *CSRFManager) GenerateToken(userID string) (string, error)

GenerateToken creates a new CSRF token for a user

func (*CSRFManager) ValidateToken

func (m *CSRFManager) ValidateToken(token string, userID string) error

ValidateToken checks if a CSRF token is valid for a user

type CSRFStore

type CSRFStore interface {
	Store(token string, csrf CSRFToken) error
	Get(token string) (*CSRFToken, error)
	Delete(token string) error
	CleanExpired() error
}

CSRFStore interface for token storage

type CSRFToken

type CSRFToken struct {
	Token     string
	ExpiresAt time.Time
	UserID    string
}

CSRFToken represents a CSRF token with metadata

type Claims

type Claims struct {
	jwt.RegisteredClaims
	Username string   `json:"username"`
	Scopes   []string `json:"scopes"`
	ClientID string   `json:"client_id"`
	// ClientClass categorizes the client that minted the token (e.g., "cli" for device-flow CLI tokens).
	ClientClass string `json:"client_class,omitempty"`
	// Enhanced security fields
	SessionID    string `json:"sid,omitempty"` // Session ID for validation
	DeviceID     string `json:"did,omitempty"` // Device fingerprint
	TokenVersion int    `json:"tv,omitempty"`  // Token version for invalidation
	IPAddress    string `json:"ip,omitempty"`  // IP binding (optional)
	UserAgent    string `json:"ua,omitempty"`  // User agent binding (optional)

	// Agent context (LLM agents)
	IsAgent        bool   `json:"is_agent,omitempty"`
	AgentType      string `json:"agent_type,omitempty"`
	DelegatedBy    string `json:"delegated_by,omitempty"`
	AgentSessionID string `json:"agent_session_id,omitempty"`
}

Claims represents the JWT claims for access tokens with enhanced security

func GetClaims

func GetClaims(ctx context.Context) (*Claims, bool)

GetClaims retrieves claims from the context

func (*Claims) GetUsername

func (c *Claims) GetUsername() string

GetUsername returns the username from the claims

func (*Claims) HasScope

func (c *Claims) HasScope(scope string) bool

HasScope checks if the claims contain a specific scope

type Context

type Context struct {
	UserID        string    `json:"user_id"`
	Username      string    `json:"username"`
	Scopes        []string  `json:"scopes"`
	TokenType     string    `json:"token_type"`
	IssuedAt      time.Time `json:"issued_at"`
	ExpiresAt     time.Time `json:"expires_at"`
	ClientID      string    `json:"client_id"`
	Authenticated bool      `json:"authenticated"`
}

Context represents the authenticated user context

func CreateAuthContext

func CreateAuthContext(username, clientID, tokenType string, scopes []string, issuedAt, expiresAt time.Time) *Context

CreateAuthContext creates a new authentication context from OAuth claims

func CreateUnauthenticatedContext

func CreateUnauthenticatedContext() *Context

CreateUnauthenticatedContext creates an unauthenticated context

func GetAuthContext

func GetAuthContext(ctx *apptheory.Context) *Context

GetAuthContext retrieves authentication context from an AppTheory context.

func (*Context) HasScope

func (ac *Context) HasScope(scope string) bool

HasScope checks if the user has a specific scope

func (*Context) IsAdmin

func (ac *Context) IsAdmin() bool

IsAdmin checks if the user has admin privileges

func (*Context) IsExpired

func (ac *Context) IsExpired() bool

IsExpired checks if the authentication token has expired

func (*Context) RequireAuth

func (ac *Context) RequireAuth() error

RequireAuth returns error if not authenticated

func (*Context) RequireAuthWithResponse

func (ac *Context) RequireAuthWithResponse(ctx *apptheory.Context) (*apptheory.Response, error)

RequireAuthWithResponse returns an unauthorized response if not authenticated.

func (*Context) RequireScope

func (ac *Context) RequireScope(scope string) error

RequireScope returns error if scope missing

func (*Context) RequireScopeWithResponse

func (ac *Context) RequireScopeWithResponse(ctx *apptheory.Context, scope string) (*apptheory.Response, error)

RequireScopeWithResponse returns an insufficient-scope response if scope missing.

func (*Context) TimeUntilExpiry

func (ac *Context) TimeUntilExpiry() time.Duration

TimeUntilExpiry returns the duration until the token expires

func (*Context) ToMap

func (ac *Context) ToMap() map[string]interface{}

ToMap converts the auth context to a map for logging or debugging

type Device

type Device = storage.Device

Device is a type alias for storage.Device

type DeviceFingerprint

type DeviceFingerprint struct {
	UserAgent   string `json:"user_agent"`
	IPAddress   string `json:"ip_address"`
	AcceptLang  string `json:"accept_language,omitempty"`
	Timezone    string `json:"timezone,omitempty"`
	ScreenRes   string `json:"screen_resolution,omitempty"`
	ColorDepth  string `json:"color_depth,omitempty"`
	Platform    string `json:"platform,omitempty"`
	Fingerprint string `json:"fingerprint"` // SHA256 hash of combined factors
}

DeviceFingerprint represents a device fingerprint

type DeviceFingerprintConfig

type DeviceFingerprintConfig struct {
	EnableFingerprinting  bool          // Enable device fingerprinting
	StrictFingerprinting  bool          // Strict fingerprint matching
	FingerprintTTL        time.Duration // How long to keep fingerprints
	TrustNewDevices       bool          // Automatically trust new devices
	RequireDeviceApproval bool          // Require manual device approval
	MaxDevicesPerUser     int           // Maximum devices per user
	DeviceTrustThreshold  time.Duration // Time before device becomes trusted
}

DeviceFingerprintConfig holds device fingerprinting configuration

func DefaultDeviceFingerprintConfig

func DefaultDeviceFingerprintConfig() *DeviceFingerprintConfig

DefaultDeviceFingerprintConfig provides secure defaults

type DeviceFingerprintManager

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

DeviceFingerprintManager handles device identification and tracking

func NewDeviceFingerprintManager

func NewDeviceFingerprintManager(repo deviceFingerprintRepository, logger *zap.Logger, config *DeviceFingerprintConfig) *DeviceFingerprintManager

NewDeviceFingerprintManager creates a new device fingerprint manager

func (*DeviceFingerprintManager) GenerateEnhancedFingerprint

func (dfm *DeviceFingerprintManager) GenerateEnhancedFingerprint(userAgent, ipAddress, acceptLang, acceptEncoding string, additionalData map[string]string) *EnhancedDeviceFingerprint

GenerateEnhancedFingerprint creates a comprehensive device fingerprint

func (*DeviceFingerprintManager) RegisterNewDevice

func (dfm *DeviceFingerprintManager) RegisterNewDevice(ctx context.Context, username string, fingerprint *EnhancedDeviceFingerprint, deviceName string) (*DeviceInfo, error)

RegisterNewDevice registers a new device for a user

func (*DeviceFingerprintManager) UpdateDeviceFingerprint

func (dfm *DeviceFingerprintManager) UpdateDeviceFingerprint(ctx context.Context, deviceID string, fingerprint *EnhancedDeviceFingerprint) error

UpdateDeviceFingerprint updates a device's fingerprint after validation

func (*DeviceFingerprintManager) ValidateDevice

func (dfm *DeviceFingerprintManager) ValidateDevice(ctx context.Context, username string, fingerprint *EnhancedDeviceFingerprint) (*DeviceValidationResult, error)

ValidateDevice validates a device fingerprint against known devices

type DeviceInfo

type DeviceInfo struct {
	DeviceID         string                     `json:"device_id"`
	Username         string                     `json:"username"`
	DeviceName       string                     `json:"device_name"`
	DeviceType       string                     `json:"device_type"`
	Fingerprint      *EnhancedDeviceFingerprint `json:"fingerprint"`
	TrustLevel       string                     `json:"trust_level"`
	CreatedAt        time.Time                  `json:"created_at"`
	LastSeenAt       time.Time                  `json:"last_seen_at"`
	LastIPAddress    string                     `json:"last_ip_address"`
	SessionCount     int                        `json:"session_count"`
	IsApproved       bool                       `json:"is_approved"`
	RequiresApproval bool                       `json:"requires_approval"`
}

DeviceInfo represents information about a user's device

type DeviceValidationResult

type DeviceValidationResult struct {
	IsKnownDevice     bool     `json:"is_known_device"`
	DeviceID          string   `json:"device_id"`
	TrustLevel        string   `json:"trust_level"`
	MatchConfidence   float64  `json:"match_confidence"`
	RequiresChallenge bool     `json:"requires_challenge"`
	RequiresApproval  bool     `json:"requires_approval"`
	ChangedAttributes []string `json:"changed_attributes"`
	RiskScore         float64  `json:"risk_score"`
}

DeviceValidationResult represents device validation results

type DynamORMCSRFStore

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

DynamORMCSRFStore implements CSRFStore using DynamORM patterns

func NewDynamORMCSRFStore

func NewDynamORMCSRFStore(db core.DB, tableName string, logger *zap.Logger) *DynamORMCSRFStore

NewDynamORMCSRFStore creates a new DynamORM-backed CSRF store

func (*DynamORMCSRFStore) CleanExpired

func (s *DynamORMCSRFStore) CleanExpired() error

CleanExpired removes expired tokens (DynamoDB TTL handles this automatically)

func (*DynamORMCSRFStore) CleanupUserTokens

func (s *DynamORMCSRFStore) CleanupUserTokens(userID string) error

CleanupUserTokens removes old/used tokens for a user This is called automatically when a user hits the token limit

func (*DynamORMCSRFStore) Delete

func (s *DynamORMCSRFStore) Delete(token string) error

Delete removes a CSRF token

func (*DynamORMCSRFStore) Get

func (s *DynamORMCSRFStore) Get(token string) (*CSRFToken, error)

Get retrieves a CSRF token

func (*DynamORMCSRFStore) GetUserActiveTokenCount

func (s *DynamORMCSRFStore) GetUserActiveTokenCount(userID string) (int, error)

GetUserActiveTokenCount returns the number of active tokens for a user This is used for rate limiting to prevent DoS attacks

func (*DynamORMCSRFStore) Store

func (s *DynamORMCSRFStore) Store(token string, csrf CSRFToken) error

Store saves a CSRF token with expiration

func (*DynamORMCSRFStore) ValidateAndConsume

func (s *DynamORMCSRFStore) ValidateAndConsume(token string, userID string) error

ValidateAndConsume validates a token and marks it as used atomically This method provides the atomic operation that the legacy DynamoDB store had

type EnhancedClaims

type EnhancedClaims = Claims

EnhancedClaims is now an alias for the improved Claims struct

type EnhancedDeviceFingerprint

type EnhancedDeviceFingerprint struct {
	// Basic identifiers
	UserAgent      string `json:"user_agent"`
	IPAddress      string `json:"ip_address"`
	AcceptLang     string `json:"accept_language,omitempty"`
	AcceptEncoding string `json:"accept_encoding,omitempty"`

	// Browser fingerprinting
	Timezone      string `json:"timezone,omitempty"`
	ScreenRes     string `json:"screen_resolution,omitempty"`
	ColorDepth    string `json:"color_depth,omitempty"`
	Platform      string `json:"platform,omitempty"`
	CookieEnabled string `json:"cookie_enabled,omitempty"`

	// Network fingerprinting
	IPVersion string `json:"ip_version"`    // IPv4 or IPv6
	ASN       string `json:"asn,omitempty"` // Autonomous System Number
	ISP       string `json:"isp,omitempty"` // Internet Service Provider
	Country   string `json:"country,omitempty"`
	Region    string `json:"region,omitempty"`

	// Behavioral fingerprinting
	RequestTiming time.Duration `json:"request_timing,omitempty"`
	RequestOrder  []string      `json:"request_order,omitempty"`

	// Computed values
	BasicFingerprint    string  `json:"basic_fingerprint"`    // Hash of basic attributes
	ExtendedFingerprint string  `json:"extended_fingerprint"` // Hash of all attributes
	FingerprintEntropy  float64 `json:"fingerprint_entropy"`  // Uniqueness score
}

EnhancedDeviceFingerprint represents a comprehensive device fingerprint

type FederationDeliveryService

type FederationDeliveryService interface {
	DeliverActivity(ctx context.Context, activity *activitypub.Activity, targetInbox string, signingActor *activitypub.Actor) error
}

FederationDeliveryService represents the interface needed for federation delivery

type MemoryCSRFStore

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

MemoryCSRFStore is an in-memory implementation (use DynamoDB in production)

func NewMemoryCSRFStore

func NewMemoryCSRFStore() *MemoryCSRFStore

NewMemoryCSRFStore creates a new in-memory CSRF store

func (*MemoryCSRFStore) CleanExpired

func (s *MemoryCSRFStore) CleanExpired() error

CleanExpired removes expired tokens

func (*MemoryCSRFStore) Delete

func (s *MemoryCSRFStore) Delete(token string) error

Delete removes a CSRF token

func (*MemoryCSRFStore) Get

func (s *MemoryCSRFStore) Get(token string) (*CSRFToken, error)

Get retrieves a CSRF token

func (*MemoryCSRFStore) Store

func (s *MemoryCSRFStore) Store(token string, csrf CSRFToken) error

Store saves a CSRF token

type Middleware

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

Middleware provides authentication middleware functionality

func GetMiddleware

func GetMiddleware() (*Middleware, error)

GetMiddleware returns a singleton middleware instance

func NewMiddleware

func NewMiddleware() *Middleware

NewMiddleware creates a new auth middleware (deprecated - use GetMiddleware)

func (*Middleware) RequireAuth

func (m *Middleware) RequireAuth(_ context.Context, request events.APIGatewayV2HTTPRequest) (*Claims, error)

RequireAuth validates the Bearer token from the request and returns the claims

func (*Middleware) RequireScope

func (m *Middleware) RequireScope(claims *Claims, scope string) error

RequireScope checks if the claims have the required scope

func (*Middleware) RequireUser

func (m *Middleware) RequireUser(claims *Claims, username string) error

RequireUser checks if the claims match the specified username

func (*Middleware) ValidateToken

func (m *Middleware) ValidateToken(authHeader string) (*Claims, error)

ValidateToken validates a token and returns the claims

type MiddlewareConfig

type MiddlewareConfig struct {
	OAuthService  common.OAuthServiceInterface
	Logger        *zap.Logger
	ServiceName   string
	Required      bool     // Whether authentication is required or optional
	RequiredScope string   // Required scope for access
	AllowedScopes []string // Multiple allowed scopes (alternative to RequiredScope)
}

MiddlewareConfig holds configuration for unified authentication middleware

type OAuthService

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

OAuthService handles OAuth 2.0 operations

func NewOAuthService

func NewOAuthService(jwtSecret string, cfg *config.Config, repos StorageProvider, auditLogger *AuditLogger) *OAuthService

NewOAuthService creates a new OAuth service

func (*OAuthService) GenerateAuthorizationCode

func (s *OAuthService) GenerateAuthorizationCode() (string, error)

GenerateAuthorizationCode generates a new authorization code

func (*OAuthService) GenerateTokens

func (s *OAuthService) GenerateTokens(ctx context.Context, username, clientID, ipAddress string, scopes []string) (accessToken, refreshToken string, err error)

GenerateTokens generates both access and refresh tokens

func (*OAuthService) GenerateTokensWithAccessTokenTTL

func (s *OAuthService) GenerateTokensWithAccessTokenTTL(ctx context.Context, username, clientID, ipAddress string, scopes []string, accessTokenTTL time.Duration) (accessToken, refreshToken string, err error)

GenerateTokensWithAccessTokenTTL generates both access and refresh tokens with a custom access token TTL.

func (*OAuthService) GenerateTokensWithAccessTokenTTLAndClientContext added in v1.1.2

func (s *OAuthService) GenerateTokensWithAccessTokenTTLAndClientContext(ctx context.Context, username, clientID, ipAddress string, scopes []string, accessTokenTTL time.Duration, clientClass, sessionID string) (accessToken, refreshToken string, err error)

GenerateTokensWithAccessTokenTTLAndClientContext generates tokens with an explicit client class and session ID.

This enables downstream middleware to enforce server-side policies (e.g., automation safety rails) based on non-spoofable classification derived at token issuance time. For agent accounts, if a sessionID is not provided, a new session ID is generated.

func (*OAuthService) GenerateTokensWithContext

func (s *OAuthService) GenerateTokensWithContext(username, clientID, sessionID, deviceID, ipAddress, userAgent string, scopes []string, tokenVersion int) (accessToken, refreshToken string, err error)

GenerateTokensWithContext generates enhanced OAuth tokens with context information including device tracking and refresh token families

func (*OAuthService) ValidateAccessToken

func (s *OAuthService) ValidateAccessToken(tokenString string) (*Claims, error)

ValidateAccessToken validates and parses a JWT access token with enhanced security checks

func (*OAuthService) ValidateAccessTokenWithContext

func (s *OAuthService) ValidateAccessTokenWithContext(tokenString, expectedSessionID, expectedIP string, expectedTokenVersion int) (*Claims, error)

ValidateAccessTokenWithContext validates a JWT token with additional security context

func (*OAuthService) ValidateClient

func (s *OAuthService) ValidateClient(ctx context.Context, clientID, clientSecret string) error

ValidateClient validates client credentials according to Mastodon OAuth rules

func (*OAuthService) ValidateRedirectURI

func (s *OAuthService) ValidateRedirectURI(ctx context.Context, clientID, redirectURI string) error

ValidateRedirectURI validates redirect URI according to Mastodon OAuth rules Mastodon requires EXACT matching of redirect URIs with no exceptions

func (*OAuthService) ValidateScopes

func (s *OAuthService) ValidateScopes(ctx context.Context, clientID string, requestedScopes []string) error

ValidateScopes validates scopes against client's registered scopes per Mastodon rules

func (*OAuthService) VerifyCodeChallenge

func (s *OAuthService) VerifyCodeChallenge(codeChallenge, codeVerifier, challengeMethod string) error

VerifyCodeChallenge verifies the PKCE code challenge per Mastodon 4.3.0+ requirements Mastodon only supports S256 method for PKCE

type OAuthServiceAdapter

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

OAuthServiceAdapter adapts AuthService to implement common.OAuthServiceInterface

func NewOAuthServiceAdapter

func NewOAuthServiceAdapter(authService *AuthService) *OAuthServiceAdapter

NewOAuthServiceAdapter creates a new adapter for AuthService

func (*OAuthServiceAdapter) ValidateAccessToken

func (a *OAuthServiceAdapter) ValidateAccessToken(token string) (common.Claims, error)

ValidateAccessToken validates an access token and returns Claims interface

type OAuthServiceInterface

type OAuthServiceInterface interface {
	ValidateAccessToken(token string) (*Claims, error)
}

OAuthServiceInterface defines the OAuth service interface to avoid import cycles This matches the interface expected by the common auth helpers

type PasswordPolicy

type PasswordPolicy struct {
	MinLength              int
	RequireUppercase       bool
	RequireLowercase       bool
	RequireNumbers         bool
	RequireSpecialChars    bool
	PreventCommonPasswords bool
}

PasswordPolicy defines password requirements

type PasswordStrengthConfig

type PasswordStrengthConfig struct {
	// MinLength is the minimum length to score above 0.
	MinLength int

	// LongLength is the length threshold for the long password bonus.
	LongLength int
	// LongBonus is the bonus applied when the long password condition is met.
	LongBonus int
	// RequireAllCharacterTypesForLongBonus requires upper/lower/number/special for the long bonus.
	RequireAllCharacterTypesForLongBonus bool

	// SequentialPenalty is subtracted when sequential patterns are detected.
	SequentialPenalty int
	// SequentialPatternMinRun is the minimum length of an ascending/descending run
	// (for letters or digits) before it is considered sequential.
	SequentialPatternMinRun int
	// RepeatedPenalty is subtracted when repeated characters are detected.
	RepeatedPenalty int
}

PasswordStrengthConfig controls how PasswordStrength scores passwords.

type RateLimitStatus

type RateLimitStatus struct {
	IsLocked          bool          `json:"is_locked"`
	UnlockTime        time.Time     `json:"unlock_time,omitempty"`
	RecentAttempts    int           `json:"recent_attempts"`
	MaxAttempts       int           `json:"max_attempts"`
	TimeWindow        time.Duration `json:"time_window"`
	RemainingAttempts int           `json:"remaining_attempts"`
}

RateLimitStatus represents the current rate limit status

type RateLimiter

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

RateLimiter handles authentication rate limiting

func NewRateLimiter

func NewRateLimiter(repos StorageProvider) *RateLimiter

NewRateLimiter creates a new rate limiter

func (*RateLimiter) CheckRateLimit

func (rl *RateLimiter) CheckRateLimit(ctx context.Context, username, ipAddress string) error

CheckRateLimit checks if an authentication attempt should be allowed

func (*RateLimiter) ClearAccountLockout

func (rl *RateLimiter) ClearAccountLockout(ctx context.Context, username string) error

ClearAccountLockout clears rate limiting for a specific account (admin action)

func (*RateLimiter) GetAccountStatus

func (rl *RateLimiter) GetAccountStatus(ctx context.Context, username string) (*RateLimitStatus, error)

GetAccountStatus returns the current rate limit status for an account

func (*RateLimiter) GetFailedAttempts

func (rl *RateLimiter) GetFailedAttempts(ctx context.Context, username string) (int, error)

GetFailedAttempts returns the number of failed login attempts for a user

func (*RateLimiter) RecordAttempt

func (rl *RateLimiter) RecordAttempt(ctx context.Context, username, ipAddress string, success bool) error

RecordAttempt records a login attempt and enforces rate limits

type RecoveryActivity

type RecoveryActivity struct {
	activitypub.Activity
	RecoveryType string         `json:"lesser:recoveryType,omitempty"`
	RecoveryData map[string]any `json:"lesser:recoveryData,omitempty"`
}

RecoveryActivity represents a custom ActivityPub activity for recovery

func (*RecoveryActivity) MarshalJSON

func (r *RecoveryActivity) MarshalJSON() ([]byte, error)

MarshalJSON implements custom JSON marshaling

type RecoveryCodeService

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

RecoveryCodeService handles backup recovery codes

func NewRecoveryCodeService

func NewRecoveryCodeService(repos StorageProvider, logger *zap.Logger) *RecoveryCodeService

NewRecoveryCodeService creates a new recovery code service

func (*RecoveryCodeService) ClearRecoveryCodes

func (s *RecoveryCodeService) ClearRecoveryCodes(ctx context.Context, username string) error

ClearRecoveryCodes removes all recovery codes for a user

func (*RecoveryCodeService) GenerateRecoveryCodes

func (s *RecoveryCodeService) GenerateRecoveryCodes(ctx context.Context, username string, count int) ([]string, error)

GenerateRecoveryCodes generates new recovery codes for a user

func (*RecoveryCodeService) GetRecoveryCodeCount

func (s *RecoveryCodeService) GetRecoveryCodeCount(ctx context.Context, username string) (int, error)

GetRecoveryCodeCount returns the number of unused recovery codes

func (*RecoveryCodeService) ValidateRecoveryCode

func (s *RecoveryCodeService) ValidateRecoveryCode(ctx context.Context, username, code string) (bool, error)

ValidateRecoveryCode validates and consumes a recovery code

type RecoveryFederationService

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

RecoveryFederationService handles ActivityPub notifications for recovery

func NewRecoveryFederationService

func NewRecoveryFederationService(cfg *config.Config, repos StorageProvider, fedService FederationDeliveryService, domain string, logger *zap.Logger) *RecoveryFederationService

NewRecoveryFederationService creates a new recovery federation service

func (*RecoveryFederationService) GetSystemActorPrivateKey

func (s *RecoveryFederationService) GetSystemActorPrivateKey(ctx context.Context) (string, error)

GetSystemActorPrivateKey retrieves the system actor's private key from Secrets Manager

func (*RecoveryFederationService) HandleTrusteeConfirmation

func (s *RecoveryFederationService) HandleTrusteeConfirmation(ctx context.Context, activity *activitypub.Activity) error

HandleTrusteeConfirmation processes incoming trustee confirmations

func (*RecoveryFederationService) RotateSystemActorKey

func (s *RecoveryFederationService) RotateSystemActorKey(ctx context.Context) error

RotateSystemActorKey rotates the system actor's key pair

func (*RecoveryFederationService) SendRecoveryApprovalNotification

func (s *RecoveryFederationService) SendRecoveryApprovalNotification(ctx context.Context, username string, recoveryToken string) error

SendRecoveryApprovalNotification notifies the user their recovery was approved

func (*RecoveryFederationService) SendRecoveryRequest

func (s *RecoveryFederationService) SendRecoveryRequest(ctx context.Context, request *storage.SocialRecoveryRequest, trusteeActorID string) error

SendRecoveryRequest sends a recovery request to a trustee

func (*RecoveryFederationService) SendTrusteeInvitation

func (s *RecoveryFederationService) SendTrusteeInvitation(ctx context.Context, fromUser string, trusteeActorID string) error

SendTrusteeInvitation sends an ActivityPub notification to a trustee

type RefreshToken

type RefreshToken = models.AuthRefreshToken

RefreshToken represents a refresh token with rotation support This is an alias to the models.AuthRefreshToken for backward compatibility

type RefreshTokenStore

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

RefreshTokenStore manages refresh tokens using DynamORM

func NewRefreshTokenStore

func NewRefreshTokenStore(db core.DB) *RefreshTokenStore

NewRefreshTokenStore creates a new refresh token store

func NewRefreshTokenStoreFromRepo

func NewRefreshTokenStoreFromRepo(repo *repositories.AuthRefreshTokenRepository) *RefreshTokenStore

NewRefreshTokenStoreFromRepo creates a new refresh token store from repository

func (*RefreshTokenStore) CreateRefreshToken

func (s *RefreshTokenStore) CreateRefreshToken(ctx context.Context, userID string, deviceName string, ipAddress string) (*RefreshToken, error)

CreateRefreshToken generates a new refresh token

func (*RefreshTokenStore) GetRefreshToken

func (s *RefreshTokenStore) GetRefreshToken(ctx context.Context, token string) (*RefreshToken, error)

GetRefreshToken retrieves a refresh token

func (*RefreshTokenStore) GetTokensByFamily

func (s *RefreshTokenStore) GetTokensByFamily(ctx context.Context, family string) ([]RefreshToken, error)

GetTokensByFamily retrieves all tokens in a family

func (*RefreshTokenStore) GetTokensByUser

func (s *RefreshTokenStore) GetTokensByUser(ctx context.Context, userID string) ([]RefreshToken, error)

GetTokensByUser retrieves all active tokens for a user

func (*RefreshTokenStore) RevokeTokenFamily

func (s *RefreshTokenStore) RevokeTokenFamily(ctx context.Context, family string, reason string) error

RevokeTokenFamily revokes all tokens in a family (security breach response)

func (*RefreshTokenStore) RevokeUserTokens

func (s *RefreshTokenStore) RevokeUserTokens(ctx context.Context, userID string, reason string) error

RevokeUserTokens revokes all tokens for a user (logout all devices)

func (*RefreshTokenStore) RotateRefreshToken

func (s *RefreshTokenStore) RotateRefreshToken(ctx context.Context, oldToken string, ipAddress string) (*RefreshToken, error)

RotateRefreshToken implements secure rotation with reuse detection

type SecretValue

type SecretValue struct {
	PrivateKeyPEM string    `json:"private_key_pem"`
	CreatedAt     time.Time `json:"created_at"`
	KeyType       string    `json:"key_type"`
	Version       string    `json:"version"`
}

SecretValue represents the structure stored in AWS Secrets Manager

type SecretsManager

type SecretsManager interface {
	StorePrivateKey(ctx context.Context, keyID, privateKeyPEM string) error
	RetrievePrivateKey(ctx context.Context, keyID string) (string, error)
	DeletePrivateKey(ctx context.Context, keyID string) error
	GenerateAndStoreKeyPair(ctx context.Context, keyID string) (publicKeyPEM, privateKeyPEM string, err error)
	RotateKey(ctx context.Context, keyID string) (publicKeyPEM, privateKeyPEM string, err error)
}

SecretsManager interface for AWS Secrets Manager operations

type SecretsManagerConfig

type SecretsManagerConfig struct {
	Region      string
	KeyPrefix   string
	CacheTTL    time.Duration
	Description string
}

SecretsManagerConfig holds configuration for the secrets manager

type SecurityValidationResult

type SecurityValidationResult struct {
	Valid             bool     `json:"valid"`
	TrustScore        float64  `json:"trust_score"` // 0.0 - 1.0
	RiskFactors       []string `json:"risk_factors"`
	RequiresChallenge bool     `json:"requires_challenge"`
	RecommendedAction string   `json:"recommended_action"`
}

SecurityValidationResult represents the result of security validation

type ServiceConfig

type ServiceConfig struct {
	Environment string
}

ServiceConfig represents auth service configuration

type Session

type Session = storage.Session

Session is a type alias for storage.Session

type SessionAnomalyFlags

type SessionAnomalyFlags struct {
	IPChanged          bool `json:"ip_changed"`
	DeviceChanged      bool `json:"device_changed"`
	LocationChanged    bool `json:"location_changed"`
	UnusualTiming      bool `json:"unusual_timing"`
	ConcurrentSessions bool `json:"concurrent_sessions"`
	SuspiciousActivity bool `json:"suspicious_activity"`
}

SessionAnomalyFlags represents detected anomalies

type SessionExtension

type SessionExtension struct {
	SessionID      string        `json:"session_id"`
	ExtendedBy     time.Duration `json:"extended_by"`
	ExtendedAt     time.Time     `json:"extended_at"`
	Reason         string        `json:"reason"`
	ExtensionCount int           `json:"extension_count"`
}

SessionExtension represents a session extension event

type SessionHealth

type SessionHealth struct {
	SessionID        string        `json:"session_id"`
	Username         string        `json:"username"`
	CreatedAt        time.Time     `json:"created_at"`
	LastActivity     time.Time     `json:"last_activity"`
	ExpiresAt        time.Time     `json:"expires_at"`
	IsActive         bool          `json:"is_active"`
	TimeUntilExpiry  time.Duration `json:"time_until_expiry"`
	InactivityTime   time.Duration `json:"inactivity_time"`
	CanBeExtended    bool          `json:"can_be_extended"`
	ShouldBeExtended bool          `json:"should_be_extended"`
	ExtensionCount   int           `json:"extension_count"`
}

SessionHealth represents the health status of a session

type SessionLifecycleConfig

type SessionLifecycleConfig struct {
	// Session durations
	SessionDuration      time.Duration // Default session lifetime
	MaxSessionDuration   time.Duration // Maximum session lifetime (hard limit)
	InactivityTimeout    time.Duration // Auto-logout after inactivity
	RefreshTokenDuration time.Duration // Refresh token lifetime

	// Cleanup settings
	CleanupInterval           time.Duration // How often to run cleanup
	ExpiredSessionGracePeriod time.Duration // Grace period for expired sessions
	MaxInactiveSessions       int           // Max inactive sessions per user

	// Security settings
	RequireRefreshRotation    bool // Rotate refresh tokens on use
	SessionFixationPrevention bool // Regenerate session IDs on login
	ConcurrentSessionLimit    int  // Max concurrent sessions per user

	// Extension policies
	AllowSessionExtension bool          // Allow extending session lifetime
	ExtensionThreshold    time.Duration // When to extend sessions automatically
	MaxSessionExtensions  int           // Max extensions per session
}

SessionLifecycleConfig holds lifecycle management configuration

func DefaultSessionLifecycleConfig

func DefaultSessionLifecycleConfig() *SessionLifecycleConfig

DefaultSessionLifecycleConfig provides secure defaults

type SessionLifecycleManager

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

SessionLifecycleManager handles session creation, refresh, and cleanup

func NewSessionLifecycleManager

func NewSessionLifecycleManager(sessionManager *SessionManager, securityManager *SessionSecurityManager, repos StorageProvider, logger *zap.Logger, config *SessionLifecycleConfig) *SessionLifecycleManager

NewSessionLifecycleManager creates a new session lifecycle manager

func (*SessionLifecycleManager) CleanupExpiredSessions

func (slm *SessionLifecycleManager) CleanupExpiredSessions(_ context.Context) error

CleanupExpiredSessions removes expired and inactive sessions

func (*SessionLifecycleManager) CreateSessionWithLifecycle

func (slm *SessionLifecycleManager) CreateSessionWithLifecycle(ctx context.Context, username, deviceName, userAgent, ipAddress, authMethod string) (*Session, error)

CreateSessionWithLifecycle creates a new session with full lifecycle management

func (*SessionLifecycleManager) GetSessionHealth

func (slm *SessionLifecycleManager) GetSessionHealth(ctx context.Context, sessionID string) (*SessionHealth, error)

GetSessionHealth returns health information about a session

func (*SessionLifecycleManager) RefreshSessionWithRotation

func (slm *SessionLifecycleManager) RefreshSessionWithRotation(ctx context.Context, refreshToken string, ipAddress, userAgent string) (*Session, string, error)

RefreshSessionWithRotation refreshes a session with optional token rotation

func (*SessionLifecycleManager) RevokeAllUserSessionsWithReason

func (slm *SessionLifecycleManager) RevokeAllUserSessionsWithReason(ctx context.Context, username, reason string) error

RevokeAllUserSessionsWithReason revokes all sessions for a user with a specific reason

func (*SessionLifecycleManager) ScheduleCleanup

func (slm *SessionLifecycleManager) ScheduleCleanup(ctx context.Context)

ScheduleCleanup schedules periodic session cleanup

type SessionManager

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

SessionManager handles session operations with enhanced security

func NewSessionManager

func NewSessionManager(repos StorageProvider) *SessionManager

NewSessionManager creates a new session manager with enhanced security

func (*SessionManager) CleanupInactiveSessions

func (sm *SessionManager) CleanupInactiveSessions(_ context.Context) error

CleanupInactiveSessions removes sessions that have been inactive too long

func (*SessionManager) CreateSession

func (sm *SessionManager) CreateSession(ctx context.Context, username, deviceName, userAgent, ipAddress, authMethod string) (*Session, error)

CreateSession creates a new session for a user with enhanced security

func (*SessionManager) DetectAnomalousSession

func (sm *SessionManager) DetectAnomalousSession(_ context.Context, session *Session, currentIP string) (bool, string)

DetectAnomalousSession checks for suspicious session activity

func (*SessionManager) GetTokenVersion

func (sm *SessionManager) GetTokenVersion(username string) int

GetTokenVersion returns the current token version for a user

func (*SessionManager) GetUserDevices

func (sm *SessionManager) GetUserDevices(ctx context.Context, username string) ([]*Device, error)

GetUserDevices returns all devices for a user

func (*SessionManager) InvalidateAllUserTokens

func (sm *SessionManager) InvalidateAllUserTokens(username string)

InvalidateAllUserTokens increments token version to invalidate all tokens

func (*SessionManager) RevokeAllUserSessions

func (sm *SessionManager) RevokeAllUserSessions(ctx context.Context, username string) error

RevokeAllUserSessions revokes all sessions for a user

func (*SessionManager) RevokeSession

func (sm *SessionManager) RevokeSession(ctx context.Context, sessionID string) error

RevokeSession revokes a specific session

func (*SessionManager) RotateRefreshToken

func (sm *SessionManager) RotateRefreshToken(ctx context.Context, session *Session) (string, error)

RotateRefreshToken rotates a refresh token for enhanced security

func (*SessionManager) TrustDevice

func (sm *SessionManager) TrustDevice(ctx context.Context, deviceID string) error

TrustDevice marks a device as trusted

func (*SessionManager) UpdateSessionActivity

func (sm *SessionManager) UpdateSessionActivity(ctx context.Context, sessionID, ipAddress string) error

UpdateSessionActivity updates the last activity timestamp

func (*SessionManager) ValidateRefreshToken

func (sm *SessionManager) ValidateRefreshToken(ctx context.Context, refreshToken string) (*Session, error)

ValidateRefreshToken validates a refresh token and returns the session

type SessionSecurityConfig

type SessionSecurityConfig struct {
	EnableIPBinding       bool
	EnableDeviceBinding   bool
	EnableGeoValidation   bool
	Require2FA            bool
	MaxConcurrentSessions int
}

SessionSecurityConfig holds security configuration for sessions

type SessionSecurityManager

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

SessionSecurityManager handles advanced session security measures

func NewSessionSecurityManager

func NewSessionSecurityManager(logger *zap.Logger, config *AdvancedSessionSecurityConfig) *SessionSecurityManager

NewSessionSecurityManager creates a new session security manager

func (*SessionSecurityManager) CalculateSessionRisk

func (ssm *SessionSecurityManager) CalculateSessionRisk(_ *Session, anomalies *SessionAnomalyFlags, validationResult *SecurityValidationResult) float64

CalculateSessionRisk calculates an overall risk score for a session

func (*SessionSecurityManager) DetectSessionAnomalies

func (ssm *SessionSecurityManager) DetectSessionAnomalies(session *Session, currentFingerprint *DeviceFingerprint) *SessionAnomalyFlags

DetectSessionAnomalies detects various session anomalies

func (*SessionSecurityManager) GenerateCSRFToken

func (ssm *SessionSecurityManager) GenerateCSRFToken() (string, error)

GenerateCSRFToken generates a cryptographically secure CSRF token

func (*SessionSecurityManager) GenerateDeviceFingerprint

func (ssm *SessionSecurityManager) GenerateDeviceFingerprint(userAgent, ipAddress, acceptLang string) *DeviceFingerprint

GenerateDeviceFingerprint creates a device fingerprint from request metadata

func (*SessionSecurityManager) GenerateSecureSessionCookie

func (ssm *SessionSecurityManager) GenerateSecureSessionCookie(sessionID, username string) (string, error)

GenerateSecureSessionCookie generates a secure session cookie value

func (*SessionSecurityManager) IsHighRiskUserAgent

func (ssm *SessionSecurityManager) IsHighRiskUserAgent(userAgent string) bool

IsHighRiskUserAgent checks if a user agent is potentially malicious

func (*SessionSecurityManager) LogSecurityEvent

func (ssm *SessionSecurityManager) LogSecurityEvent(eventType, sessionID, username, description string, metadata map[string]interface{})

LogSecurityEvent logs a security-related event

func (*SessionSecurityManager) PreventSessionFixation

func (ssm *SessionSecurityManager) PreventSessionFixation(oldSessionID string) (string, error)

PreventSessionFixation implements session fixation prevention

func (*SessionSecurityManager) RotateSessionSecrets

func (ssm *SessionSecurityManager) RotateSessionSecrets(session *Session) error

RotateSessionSecrets rotates session secrets for enhanced security

func (*SessionSecurityManager) ShouldRequire2FA

func (ssm *SessionSecurityManager) ShouldRequire2FA(riskScore float64, session *Session) bool

ShouldRequire2FA determines if 2FA should be required based on risk

func (*SessionSecurityManager) ValidateCSRFToken

func (ssm *SessionSecurityManager) ValidateCSRFToken(provided, expected string) bool

ValidateCSRFToken validates a CSRF token against the expected value

func (*SessionSecurityManager) ValidateSecurityHeaders

func (ssm *SessionSecurityManager) ValidateSecurityHeaders(headers map[string]string) []string

ValidateSecurityHeaders validates important security headers

func (*SessionSecurityManager) ValidateSessionSecurity

func (ssm *SessionSecurityManager) ValidateSessionSecurity(_ context.Context, session *Session, currentFingerprint *DeviceFingerprint) (*SecurityValidationResult, error)

ValidateSessionSecurity performs comprehensive session security validation

type SessionValidationConfig

type SessionValidationConfig struct {
	// Validation levels
	RequireDeviceValidation bool // Validate device fingerprints
	RequireIPValidation     bool // Validate IP addresses
	RequireCSRFValidation   bool // Validate CSRF tokens
	RequireSecurityHeaders  bool // Validate security headers

	// Validation thresholds
	MaxSessionAge        time.Duration // Maximum session age
	MaxInactivityPeriod  time.Duration // Maximum inactivity period
	MinTrustScore        float64       // Minimum required trust score
	DeviceMatchThreshold float64       // Device fingerprint match threshold

	// Security policies
	StrictValidation  bool // Enable strict validation mode
	AllowGracePeriod  bool // Allow grace period for token rotation
	RequireReauth     bool // Require reauthentication for sensitive operations
	LogAllValidations bool // Log all validation attempts
}

SessionValidationConfig holds validation configuration

func DefaultSessionValidationConfig

func DefaultSessionValidationConfig() *SessionValidationConfig

DefaultSessionValidationConfig provides secure defaults

type SessionValidationRequest

type SessionValidationRequest struct {
	// Session identification
	SessionID    string `json:"session_id,omitempty"`
	RefreshToken string `json:"refresh_token,omitempty"`
	CSRFToken    string `json:"csrf_token,omitempty"`

	// Request context
	IPAddress     string            `json:"ip_address"`
	UserAgent     string            `json:"user_agent"`
	Headers       map[string]string `json:"headers,omitempty"`
	RequestPath   string            `json:"request_path,omitempty"`
	RequestMethod string            `json:"request_method,omitempty"`

	// Additional context
	DeviceFingerprint   map[string]string `json:"device_fingerprint,omitempty"`
	Timestamp           time.Time         `json:"timestamp"`
	RequireHighSecurity bool              `json:"require_high_security,omitempty"`
}

SessionValidationRequest represents a session validation request

type SessionValidationResponse

type SessionValidationResponse struct {
	// Validation result
	Valid           bool    `json:"valid"`
	TrustScore      float64 `json:"trust_score"`
	RiskScore       float64 `json:"risk_score"`
	ValidationLevel string  `json:"validation_level"` // basic, standard, strict

	// Session information
	SessionID    string    `json:"session_id"`
	Username     string    `json:"username"`
	ExpiresAt    time.Time `json:"expires_at"`
	LastActivity time.Time `json:"last_activity"`
	DeviceID     string    `json:"device_id,omitempty"`

	// Validation details
	ValidatedChecks []string `json:"validated_checks"`
	FailedChecks    []string `json:"failed_checks"`
	Warnings        []string `json:"warnings"`
	RequiredActions []string `json:"required_actions"`

	// Security recommendations
	RequiresChallenge      bool   `json:"requires_challenge"`
	RequiresReauth         bool   `json:"requires_reauth"`
	RequiresDeviceApproval bool   `json:"requires_device_approval"`
	SuggestedAction        string `json:"suggested_action"`

	// Extended session if applicable
	ExtendedSession bool      `json:"extended_session,omitempty"`
	NewExpiresAt    time.Time `json:"new_expires_at,omitempty"`
	NewRefreshToken string    `json:"new_refresh_token,omitempty"`
}

SessionValidationResponse represents the validation result

type SessionValidator

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

SessionValidator provides comprehensive session validation

func NewSessionValidator

func NewSessionValidator(
	sessionManager *SessionManager,
	securityManager *SessionSecurityManager,
	lifecycleManager *SessionLifecycleManager,
	fingerprintManager *DeviceFingerprintManager,
	logger *zap.Logger,
	config *SessionValidationConfig,
) *SessionValidator

NewSessionValidator creates a new comprehensive session validator

func (*SessionValidator) QuickValidateSession

func (sv *SessionValidator) QuickValidateSession(ctx context.Context, sessionID, ipAddress, userAgent string) (bool, error)

QuickValidateSession provides a simplified validation for common cases

func (*SessionValidator) ValidateRefreshTokenRequest

func (sv *SessionValidator) ValidateRefreshTokenRequest(ctx context.Context, refreshToken, ipAddress, userAgent string) (*SessionValidationResponse, error)

ValidateRefreshTokenRequest validates a refresh token request specifically

func (*SessionValidator) ValidateSession

ValidateSession performs comprehensive session validation

type SocialRecoveryService

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

SocialRecoveryService handles account recovery through trusted contacts

func NewSocialRecoveryService

func NewSocialRecoveryService(repos StorageProvider, logger *zap.Logger) *SocialRecoveryService

NewSocialRecoveryService creates a new social recovery service

func (*SocialRecoveryService) AddTrustee

func (s *SocialRecoveryService) AddTrustee(ctx context.Context, username, trusteeActorID string) error

AddTrustee adds a trusted contact for social recovery

func (*SocialRecoveryService) ConfirmRecovery

func (s *SocialRecoveryService) ConfirmRecovery(ctx context.Context, requestID, trusteeActorID string) error

ConfirmRecovery processes a trustee's confirmation

func (*SocialRecoveryService) GetTrustees

func (s *SocialRecoveryService) GetTrustees(ctx context.Context, username string) ([]*storage.TrusteeConfig, error)

GetTrustees returns all trustees for a user

func (*SocialRecoveryService) InitiateRecovery

func (s *SocialRecoveryService) InitiateRecovery(ctx context.Context, username string) (*storage.SocialRecoveryRequest, error)

InitiateRecovery starts the social recovery process

func (*SocialRecoveryService) RemoveTrustee

func (s *SocialRecoveryService) RemoveTrustee(ctx context.Context, username, trusteeActorID string) error

RemoveTrustee removes a trusted contact

func (*SocialRecoveryService) SetFederationService

func (s *SocialRecoveryService) SetFederationService(fedService socialRecoveryFederationService)

SetFederationService sets the federation service for sending notifications

type StorageProvider

type StorageProvider interface {
	Account() *repositories.AccountRepository
	Actor() interfaces.ActorRepository
	Activity() interfaces.ActivityRepository
	Notification() interfaces.NotificationRepository
	Recovery() *repositories.RecoveryRepository
	Audit() *repositories.AuditRepository
}

StorageProvider is the common interface for all auth services to access storage repositories This avoids importing pkg/storage/core which causes import cycles

type TokenBlacklist

type TokenBlacklist interface {
	RevokeToken(jti string, expiry time.Time) error
	IsTokenRevoked(jti string) (bool, error)
	CleanExpiredTokens() error
}

TokenBlacklist interface for managing revoked tokens

type UnifiedAuthMiddleware

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

UnifiedAuthMiddleware provides centralized authentication middleware for all services

func NewUnifiedAuthMiddleware

func NewUnifiedAuthMiddleware(config MiddlewareConfig) *UnifiedAuthMiddleware

NewUnifiedAuthMiddleware creates a new unified authentication middleware

type WalletChallenge

type WalletChallenge struct {
	ID        string    `json:"id"`
	Username  string    `json:"username,omitempty"`
	Address   string    `json:"address"`
	ChainID   int       `json:"chainId"`
	Nonce     string    `json:"nonce"`
	Message   string    `json:"message"`
	IssuedAt  time.Time `json:"issuedAt"`
	ExpiresAt time.Time `json:"expiresAt"`
}

WalletChallenge represents a challenge for wallet authentication

type WalletCredential

type WalletCredential struct {
	Username string    `json:"username"`
	Address  string    `json:"address"`
	ChainID  int       `json:"chainId"`
	Type     string    `json:"type"` // ethereum, solana, etc.
	ENS      string    `json:"ens,omitempty"`
	LinkedAt time.Time `json:"linkedAt"`
	LastUsed time.Time `json:"lastUsed"`
}

WalletCredential represents a linked wallet

type WalletService

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

WalletService handles wallet authentication

func NewWalletService

func NewWalletService(repos StorageProvider) *WalletService

NewWalletService creates a new wallet service

func (*WalletService) CreateChallenge

func (s *WalletService) CreateChallenge(ctx context.Context, address string, chainID int, username string) (*storage.WalletChallenge, error)

CreateChallenge creates a new authentication challenge for a wallet

func (*WalletService) GetUserWallets

func (s *WalletService) GetUserWallets(ctx context.Context, username string) ([]*storage.WalletCredential, error)

GetUserWallets returns all wallets linked to a user

func (*WalletService) LinkWallet

func (s *WalletService) LinkWallet(ctx context.Context, username, address string, chainID int, walletType string) error

LinkWallet links a wallet to an existing user account

func (*WalletService) UnlinkWallet

func (s *WalletService) UnlinkWallet(ctx context.Context, username, address string) error

UnlinkWallet removes a wallet link from a user account

func (*WalletService) VerifySignature

func (s *WalletService) VerifySignature(ctx context.Context, req *WalletVerifyRequest) (string, error)

VerifySignature verifies a wallet signature and returns user info

type WalletVerifyRequest

type WalletVerifyRequest struct {
	ChallengeID string `json:"challengeId"`
	Address     string `json:"address"`
	Signature   string `json:"signature"`
	Message     string `json:"message"`
}

WalletVerifyRequest represents a wallet signature verification request

type WebAuthnService

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

WebAuthnService handles WebAuthn operations

func NewWebAuthnService

func NewWebAuthnService(repos StorageProvider, domain string, displayName string) (*WebAuthnService, error)

NewWebAuthnService creates a new WebAuthn service

func (*WebAuthnService) BeginLogin

func (s *WebAuthnService) BeginLogin(ctx context.Context, username string) (any, string, error)

BeginLogin starts the WebAuthn login process

func (*WebAuthnService) BeginRegistration

func (s *WebAuthnService) BeginRegistration(ctx context.Context, username string) (any, string, error)

BeginRegistration starts the WebAuthn registration process

func (*WebAuthnService) DeleteCredential

func (s *WebAuthnService) DeleteCredential(ctx context.Context, username string, credentialID string) error

DeleteCredential removes a WebAuthn credential

func (*WebAuthnService) FinishLogin

func (s *WebAuthnService) FinishLogin(ctx context.Context, username string, challenge string, response []byte) (*storage.WebAuthnCredential, error)

FinishLogin completes the WebAuthn login process

func (*WebAuthnService) FinishRegistration

func (s *WebAuthnService) FinishRegistration(ctx context.Context, username string, challenge string, response []byte, credentialName string) error

FinishRegistration completes the WebAuthn registration process

func (*WebAuthnService) GetUserCredentials

func (s *WebAuthnService) GetUserCredentials(ctx context.Context, username string) ([]*storage.WebAuthnCredential, error)

GetUserCredentials returns all WebAuthn credentials for a user

func (*WebAuthnService) UpdateCredentialName

func (s *WebAuthnService) UpdateCredentialName(ctx context.Context, username string, credentialID string, newName string) error

UpdateCredentialName updates the display name of a credential

Directories

Path Synopsis
Package providers defines OAuth provider interfaces and user information structures for social authentication.
Package providers defines OAuth provider interfaces and user information structures for social authentication.

Jump to

Keyboard shortcuts

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