session

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Jun 20, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package session provides a session storage interface with controls.

Session storage extends key-value storage with session-specific operations:

  • User-based session lookups and deletion
  • Automatic TTL management
  • Size limits and validation
  • Touch/heartbeat operations

Available Backends

  • memory: In-memory storage (for development/testing)
  • kvs: Adapts any kvs.ListableStore (Redis, SQLite, etc.)

Index

Constants

View Source
const (
	// ErrCodeInvalidSession indicates the session is malformed or missing required fields.
	ErrCodeInvalidSession = "SESSION_INVALID"

	// ErrCodeSizeLimitExceeded indicates the session data exceeds the configured limit.
	ErrCodeSizeLimitExceeded = "SESSION_SIZE_EXCEEDED"

	// ErrCodeNotSerializable indicates session data cannot be serialized to JSON.
	ErrCodeNotSerializable = "SESSION_NOT_SERIALIZABLE"

	// ErrCodeNotFound indicates the session does not exist.
	ErrCodeNotFound = "SESSION_NOT_FOUND"

	// ErrCodeExpired indicates the session has expired.
	ErrCodeExpired = "SESSION_EXPIRED"

	// ErrCodeStoreClosed indicates the store has been closed.
	ErrCodeStoreClosed = "STORE_CLOSED"

	// ErrCodeSessionLimitExceeded indicates the user has too many concurrent sessions.
	ErrCodeSessionLimitExceeded = "SESSION_LIMIT_EXCEEDED"

	// ErrCodeSiteMismatch indicates the session belongs to a different site.
	ErrCodeSiteMismatch = "SESSION_SITE_MISMATCH"
)

Error codes for session operations. These can be used by HTTP handlers to return appropriate status codes.

View Source
const SessionIDLength = 32

SessionIDLength is the length of generated session IDs in bytes.

Variables

View Source
var (
	ErrNotFound             = errors.New("session not found")
	ErrExpired              = errors.New("session expired")
	ErrInvalidSession       = errors.New("invalid session")
	ErrSizeLimitExceeded    = errors.New("session size limit exceeded")
	ErrSessionLimitExceeded = errors.New("session limit exceeded")
	ErrSiteMismatch         = errors.New("session belongs to different site")
	ErrClosed               = errors.New("store is closed")
)

Common errors.

Functions

func ErrorCode

func ErrorCode(err error) string

ErrorCode extracts the error code from an error, if it's a SessionError. Returns empty string for non-SessionError errors.

func ErrorDetails

func ErrorDetails(err error) map[string]any

ErrorDetails extracts details from an error, if it's a SessionError.

func GenerateSessionID

func GenerateSessionID() (string, error)

GenerateSessionID generates a cryptographically secure session ID.

Types

type Config

type Config struct {
	// SiteID identifies which site/service this store handles.
	// Used for multi-site isolation (e.g., "academyos", "agentos", "dashforge").
	// When set, all sessions are tagged with this SiteID and Get operations
	// validate the session belongs to this site.
	// Required for ControlledStore when running multiple sites.
	SiteID string

	// MaxSessionSize is the maximum serialized session size in bytes.
	// Set to 0 for no limit.
	MaxSessionSize int

	// MaxSessionsPerUser limits concurrent sessions per user.
	// When exceeded, oldest sessions are deleted to make room.
	// Set to 0 for no limit.
	MaxSessionsPerUser int

	// DefaultTTL is the default session TTL if not specified.
	DefaultTTL time.Duration

	// CleanupInterval is how often to run automatic cleanup.
	// Set to 0 to disable automatic cleanup.
	CleanupInterval time.Duration

	// KeyPrefix is the prefix for session keys (for KVS backends).
	KeyPrefix string
}

Config contains configuration for session stores.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns sensible default configuration.

type ControlOption

type ControlOption func(*ControlledStore)

ControlOption configures a ControlledStore.

func WithLogger

func WithLogger(logger *slog.Logger) ControlOption

WithLogger sets the logger for the controlled store.

func WithViolationHandler

func WithViolationHandler(handler ViolationHandler) ControlOption

WithViolationHandler sets a callback for policy violations. Use this to emit metrics (e.g., OTel counters) or alerts.

type ControlledStore

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

ControlledStore wraps a Store with size limits, validation, and observability.

func WithControls

func WithControls(store Store, cfg Config, opts ...ControlOption) *ControlledStore

WithControls wraps a Store with size limits and validation controls.

func (*ControlledStore) Close

func (s *ControlledStore) Close() error

Close closes the store.

func (*ControlledStore) Create

func (s *ControlledStore) Create(ctx context.Context, session *Session) error

Create stores a new session with validation.

func (*ControlledStore) Delete

func (s *ControlledStore) Delete(ctx context.Context, id string) error

Delete removes a session by ID.

func (*ControlledStore) DeleteByUserID

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

DeleteByUserID removes all sessions for a user.

func (*ControlledStore) Get

func (s *ControlledStore) Get(ctx context.Context, id string) (*Session, error)

Get retrieves a session by ID. If SiteID is configured, validates the session belongs to this site.

func (*ControlledStore) ListByUserID

func (s *ControlledStore) ListByUserID(ctx context.Context, userID string) ([]*Session, error)

ListByUserID returns all sessions for a user if the underlying store supports it. If SiteID is configured, only returns sessions for this site. This implements SessionLister for transparent pass-through.

func (*ControlledStore) Touch

func (s *ControlledStore) Touch(ctx context.Context, id string) error

Touch updates the LastAccessedAt timestamp.

func (*ControlledStore) Unwrap

func (s *ControlledStore) Unwrap() Store

Unwrap returns the underlying store.

func (*ControlledStore) Update

func (s *ControlledStore) Update(ctx context.Context, session *Session) error

Update updates an existing session with validation.

type Session

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

	// UserID is the authenticated user's ID.
	UserID uuid.UUID `json:"user_id"`

	// SiteID identifies which site/service this session belongs to.
	// Used for multi-site isolation (e.g., "academyos", "agentos", "dashforge").
	// Set automatically by ControlledStore based on Config.SiteID.
	SiteID string `json:"site_id,omitempty"`

	// OrganizationID is the current organization context (optional).
	OrganizationID *uuid.UUID `json:"organization_id,omitempty"`

	// Data contains arbitrary session data.
	// This can include tokens, preferences, etc.
	Data map[string]any `json:"data,omitempty"`

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

	// UpdatedAt is when the session was last updated.
	UpdatedAt time.Time `json:"updated_at"`

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

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

	// IPAddress is the IP address that created the session.
	IPAddress string `json:"ip_address,omitempty"`

	// UserAgent is the user agent that created the session.
	UserAgent string `json:"user_agent,omitempty"`
}

Session represents a server-side session.

func NewSession

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

NewSession creates a new session with the given parameters.

func (*Session) IsExpired

func (s *Session) IsExpired() bool

IsExpired returns true if the session has expired.

func (*Session) TTL

func (s *Session) TTL() time.Duration

TTL returns the remaining time until expiration.

type SessionError

type SessionError struct {
	// Code is a machine-readable error code.
	Code string

	// Message is a human-readable error message.
	Message string

	// Details contains additional error context.
	Details map[string]any

	// Cause is the underlying error, if any.
	Cause error
}

SessionError is a structured error with a code for programmatic handling.

func NewSessionError

func NewSessionError(code, message string, details map[string]any, cause error) *SessionError

NewSessionError creates a new SessionError.

func (*SessionError) Error

func (e *SessionError) Error() string

func (*SessionError) Is

func (e *SessionError) Is(target error) bool

Is implements errors.Is for SessionError.

func (*SessionError) Unwrap

func (e *SessionError) Unwrap() error

type SessionLister

type SessionLister interface {
	// ListByUserID returns all sessions for a user, sorted by CreatedAt ascending (oldest first).
	ListByUserID(ctx context.Context, userID string) ([]*Session, error)
}

SessionLister is an optional interface for stores that support listing sessions. Stores implementing this interface can enforce MaxSessionsPerUser.

type Store

type Store interface {
	// Create stores a new session.
	Create(ctx context.Context, session *Session) error

	// Get retrieves a session by ID.
	// Returns ErrNotFound if the session doesn't exist.
	// Returns ErrExpired if the session has expired.
	Get(ctx context.Context, id string) (*Session, error)

	// Update updates an existing session.
	// Returns ErrNotFound if the session doesn't exist.
	Update(ctx context.Context, session *Session) error

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

	// DeleteByUserID removes all sessions for a user.
	// Returns the number of sessions deleted.
	DeleteByUserID(ctx context.Context, userID string) (int, error)

	// Touch updates the LastAccessedAt timestamp.
	// This is used to track session activity without modifying other fields.
	Touch(ctx context.Context, id string) error

	// Close closes the store and releases any resources.
	Close() error
}

Store defines the interface for session storage. Implementations must be safe for concurrent use.

type ViolationEvent

type ViolationEvent struct {
	Type      ViolationType
	SessionID string
	UserID    uuid.UUID
	SiteID    string // Site identifier for multi-site isolation
	Size      int    // Current size in bytes
	Limit     int    // Configured limit
	Message   string
}

ViolationEvent contains information about a policy violation.

type ViolationHandler

type ViolationHandler func(ctx context.Context, event ViolationEvent)

ViolationHandler is called when a session policy is violated. Use this to emit metrics, alerts, or audit logs.

type ViolationType

type ViolationType string

ViolationType identifies the type of policy violation.

const (
	ViolationSizeExceeded         ViolationType = "size_exceeded"
	ViolationNotSerializable      ViolationType = "not_serializable"
	ViolationInvalidSession       ViolationType = "invalid_session"
	ViolationSessionLimitExceeded ViolationType = "session_limit_exceeded"
	ViolationSiteMismatch         ViolationType = "site_mismatch"
)

Directories

Path Synopsis
backend
kvs
Package kvs provides a session storage backend using kvs.ListableStore.
Package kvs provides a session storage backend using kvs.ListableStore.
memory
Package memory provides an in-memory session storage backend.
Package memory provides an in-memory session storage backend.

Jump to

Keyboard shortcuts

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