Documentation
¶
Index ¶
- Variables
- func GenerateSessionID() (string, error)
- func GenerateState() (string, error)
- type SessionData
- type SessionStore
- func (s *SessionStore) Create(ctx context.Context, data SessionData) (string, error)
- func (s *SessionStore) CreateUserSession(ctx context.Context, data UserSession, ttl time.Duration) (string, error)
- func (s *SessionStore) Delete(ctx context.Context, sessionID string) error
- func (s *SessionStore) DeleteUserSession(ctx context.Context, sessionID string) error
- func (s *SessionStore) Get(ctx context.Context, sessionID string) (*SessionData, error)
- func (s *SessionStore) GetUserSession(ctx context.Context, sessionID string) (*UserSession, error)
- func (s *SessionStore) UpdateUserSession(ctx context.Context, sessionID string, data UserSession, ttl time.Duration) error
- type UserSession
Constants ¶
This section is empty.
Variables ¶
var ( ErrSessionNotFound = errors.New("session not found") ErrSessionExpired = errors.New("session expired") )
Standard errors for session operations
Functions ¶
func GenerateSessionID ¶
GenerateSessionID generates a cryptographically secure session ID. Returns a base64 URL-safe encoded string (43 characters from 32 bytes).
func GenerateState ¶
GenerateState generates a CSRF protection state token. Returns a base64 URL-safe encoded string (43 characters from 32 bytes).
Types ¶
type SessionData ¶
type SessionData struct {
// State is the CSRF protection token (base64-encoded random 32 bytes)
State string `json:"state"`
// Verifier is the PKCE code verifier (oauth2.GenerateVerifier() output)
Verifier string `json:"verifier"`
// Provider identifies which provider initiated the flow (google, github, etc.)
Provider string `json:"provider"`
// ExpiresAt is the session expiry timestamp (10 minutes from creation)
ExpiresAt time.Time `json:"expires_at"`
}
SessionData holds OIDC state parameters and PKCE verifier for OAuth flow. Server-side storage prevents XSS attacks on client-side state storage.
type SessionStore ¶
type SessionStore struct {
// contains filtered or unexported fields
}
SessionStore provides server-side storage for OIDC sessions using NATS KV. Sessions auto-expire after 10 minutes (matching OAuth2 auth code lifetime).
func NewSessionStore ¶
func NewSessionStore(kv jetstream.KeyValue) *SessionStore
NewSessionStore creates a SessionStore backed by NATS JetStream KeyValue.
func (*SessionStore) Create ¶
func (s *SessionStore) Create(ctx context.Context, data SessionData) (string, error)
Create generates a new session ID, stores the session data with 10-minute TTL, and returns the session ID.
func (*SessionStore) CreateUserSession ¶
func (s *SessionStore) CreateUserSession(ctx context.Context, data UserSession, ttl time.Duration) (string, error)
CreateUserSession creates a new authenticated user session with the specified TTL. Returns the generated session ID.
NOTE: ttl parameter ignored - relies on NATS bucket MaxAge=30d. Sessions with RememberMe=false will be manually validated in middleware based on LastActive timestamp.
func (*SessionStore) Delete ¶
func (s *SessionStore) Delete(ctx context.Context, sessionID string) error
Delete removes a session by session ID.
func (*SessionStore) DeleteUserSession ¶
func (s *SessionStore) DeleteUserSession(ctx context.Context, sessionID string) error
DeleteUserSession removes a user session by session ID. This is idempotent - deleting a non-existent session is not an error.
func (*SessionStore) Get ¶
func (s *SessionStore) Get(ctx context.Context, sessionID string) (*SessionData, error)
Get retrieves session data by session ID. Returns ErrSessionNotFound if session doesn't exist. Returns ErrSessionExpired if session has expired.
func (*SessionStore) GetUserSession ¶
func (s *SessionStore) GetUserSession(ctx context.Context, sessionID string) (*UserSession, error)
GetUserSession retrieves an authenticated user session by session ID. Returns ErrSessionNotFound if session doesn't exist.
func (*SessionStore) UpdateUserSession ¶
func (s *SessionStore) UpdateUserSession(ctx context.Context, sessionID string, data UserSession, ttl time.Duration) error
UpdateUserSession updates an existing user session, refreshing the NATS KV TTL. This implements the sliding window expiration pattern - each update extends the session lifetime.
NOTE: ttl parameter ignored - relies on NATS bucket MaxAge=30d. The Put operation creates a new message revision with a fresh TTL, implementing sliding window behavior.
type UserSession ¶
type UserSession struct {
// UserID is the OIDC "sub" claim (unique identifier from identity provider)
UserID string `json:"user_id"`
// Email is the user's verified email address from OIDC claims
Email string `json:"email"`
// Role is the user's authorization level ("admin" or "readonly")
// Derived from config role mapping based on email/groups
Role string `json:"role"`
// RememberMe determines session duration: false=7 days, true=30 days
// Middleware validates against LastActive for 7-day sessions
RememberMe bool `json:"remember_me"`
// CreatedAt is the session creation timestamp (set once, never updated)
CreatedAt time.Time `json:"created_at"`
// LastActive is updated on each authenticated request for sliding window
// expiration and security audit trail
LastActive time.Time `json:"last_active"`
// IPAddress is the client's IP address at session creation time
// Used for security audit logs and suspicious activity detection
IPAddress string `json:"ip_address"`
// UserAgent is the browser's User-Agent header at session creation time
// Used for session fingerprinting and audit logs
UserAgent string `json:"user_agent"`
}
UserSession represents an authenticated browser session after successful OIDC login. Unlike SessionData (short-lived OIDC state for OAuth flow), UserSession persists for 7-30 days and is used for cookie-based authentication on each request.
Lifecycle: - Created: After OIDC callback successfully validates and creates JWT - Updated: On each authenticated request to refresh LastActive (sliding window) - Deleted: On user logout or automatic expiry via NATS KV TTL
Storage: NATS KV with bucket-level TTL (30-day maximum), middleware validates 7-day expiry for RememberMe=false sessions by checking LastActive timestamp.