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
- Variables
- func ErrorCode(err error) string
- func ErrorDetails(err error) map[string]any
- func GenerateSessionID() (string, error)
- type Config
- type ControlOption
- type ControlledStore
- func (s *ControlledStore) Close() error
- func (s *ControlledStore) Create(ctx context.Context, session *Session) error
- func (s *ControlledStore) Delete(ctx context.Context, id string) error
- func (s *ControlledStore) DeleteByUserID(ctx context.Context, userID string) (int, error)
- func (s *ControlledStore) Get(ctx context.Context, id string) (*Session, error)
- func (s *ControlledStore) ListByUserID(ctx context.Context, userID string) ([]*Session, error)
- func (s *ControlledStore) Touch(ctx context.Context, id string) error
- func (s *ControlledStore) Unwrap() Store
- func (s *ControlledStore) Update(ctx context.Context, session *Session) error
- type Session
- type SessionError
- type SessionLister
- type Store
- type ViolationEvent
- type ViolationHandler
- type ViolationType
Constants ¶
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.
const SessionIDLength = 32
SessionIDLength is the length of generated session IDs in bytes.
Variables ¶
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 ¶
ErrorCode extracts the error code from an error, if it's a SessionError. Returns empty string for non-SessionError errors.
func ErrorDetails ¶
ErrorDetails extracts details from an error, if it's a SessionError.
func GenerateSessionID ¶
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) 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 ¶
DeleteByUserID removes all sessions for a user.
func (*ControlledStore) Get ¶
Get retrieves a session by ID. If SiteID is configured, validates the session belongs to this site.
func (*ControlledStore) ListByUserID ¶
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.
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 ¶
NewSession creates a new session with the given parameters.
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. |