browsersession

package
v0.2.9 Latest Latest
Warning

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

Go to latest
Published: Oct 7, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package browsersession owns the hub's shared browser login session.

A browser receives only a random, host-only cookie. The value is never a user identity or a platform credential: the store keeps a SHA-256 lookup key and the identity server-side. This package deliberately has no OIDC, Kubernetes, or hub dependencies so every HTTP boundary can share the same session contract without creating an import cycle.

Where the server-side records live is a Backend decision. The default is process-local memory, which is correct for a single hub replica. A hub scaled to several replicas must supply a shared Backend (see pkg/hub/sharedstore): a cookie is issued by whichever replica handled the login, and every other replica has to resolve and revoke it.

Index

Constants

View Source
const (
	// CookieName is the one shared portal/browser session cookie.  The __Host-
	// prefix requires Secure, Path=/, and no Domain attribute, which makes the
	// cookie host-only even when an app is served from a sibling subdomain.
	CookieName = "__Host-railgrid-session"
	// SessionCookieName is retained as a descriptive alias for callers that
	// already use the access-proxy naming convention.
	SessionCookieName = CookieName
)

Variables

View Source
var (
	ErrInvalid  = errors.New("invalid browser session")
	ErrNotFound = errors.New("browser session not found")
	ErrExpired  = errors.New("browser session expired")
	ErrRevoked  = errors.New("browser session revoked")
)

Functions

func ClearCookie

func ClearCookie(w http.ResponseWriter)

ClearCookie writes an expired shared cookie without touching server state.

func ConstantTimeEqual

func ConstantTimeEqual(a, b string) bool

ConstantTimeEqual is a small helper for callers comparing a cookie value against a request-bound value without introducing a second implementation.

Types

type Backend

type Backend interface {
	Put(ctx context.Context, key string, record Record) error
	Get(ctx context.Context, key string) (Record, error)
	// Revoke invalidates key.  It is idempotent, which makes logout safe to
	// retry.  expiresAt is the horizon past which the implementation may drop
	// any tombstone it keeps.
	Revoke(ctx context.Context, key string, expiresAt time.Time) error
}

Backend is the authoritative store for session records. Implementations are keyed by an opaque, already-hashed lookup key and must be safe for concurrent use.

Get reports ErrNotFound, ErrExpired, or ErrRevoked; any other error is treated as a store failure and fails the request closed.

type Config

type Config struct {
	TTL        time.Duration
	MaxEntries int
	Now        func() time.Time
	Random     io.Reader
	// Backend, when set, replaces the process-local memory backend.  Required
	// for a hub running more than one replica.
	Backend Backend
}

Config configures a Store. Now and Random are test seams; production uses time.Now and crypto/rand.Reader. MaxEntries bounds the default in-memory backend so an unbounded stream of logins cannot grow it indefinitely; it is ignored when Backend is supplied.

type Identity

type Identity struct {
	UserID string
	Email  string
	Name   string
	// RBACIdentity is the kcp username this account authenticates as inside
	// tenant workspaces (User.Spec.RBACIdentity, e.g. "railgrid:<email>"). All
	// workspace RBAC — admin ClusterRoleBindings and app-access grants — is
	// written against this string, so authorization checks (SAR) must use it,
	// never the User CR name. Not a credential.
	RBACIdentity string
	Issuer       string
	Subject      string
	AuthType     string
}

Identity is the minimum server-side identity needed by hub and provider authorization. Credentials, ID tokens, refresh tokens, and kubeconfigs are intentionally not representable here.

type Record

type Record struct {
	Identity  Identity
	IssuedAt  time.Time
	ExpiresAt time.Time
}

Record is what a Backend persists for one session. The raw opaque handle is returned transiently to the caller that needs to set a cookie; a Backend only ever sees the hash-derived key, never the handle itself.

type Session

type Session struct {
	ID        string
	Identity  Identity
	IssuedAt  time.Time
	ExpiresAt time.Time
}

Session is the server-side representation associated with the opaque browser cookie. ID is returned to trusted hub callers for diagnostics; it is never serialized into the cookie itself.

type Store

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

Store is the concurrency-safe front end for browser sessions: it owns handle generation, the cookie contract, and TTL policy, and delegates record storage to a Backend.

func New

func New(config Config) *Store

New creates a browser-session store. Without Config.Backend it keeps records in bounded process-local memory.

func (*Store) Issue

func (s *Store) Issue(ctx context.Context, identity Identity) (string, Session, error)

Issue stores identity and returns the opaque cookie value plus its server-side view. It rejects empty stable identities so callers cannot accidentally mint an anonymous session.

func (*Store) IssueHTTP

func (s *Store) IssueHTTP(ctx context.Context, w http.ResponseWriter, identity Identity) (Session, error)

IssueHTTP creates a session and writes its secure cookie.

func (*Store) IssueTransient

func (s *Store) IssueTransient(ctx context.Context, identity Identity, ttl time.Duration) (string, Session, error)

IssueTransient creates an opaque session handle with a caller-selected, shorter lifetime. It is used for one-time browser handoffs: the handle is redeemed immediately for a normal session cookie and must expire quickly if delivery never completes.

func (*Store) Resolve

func (s *Store) Resolve(ctx context.Context, value string) (Session, error)

Resolve returns a live session for an opaque cookie value.

func (*Store) ResolveRequest

func (s *Store) ResolveRequest(r *http.Request) (Session, error)

ResolveRequest resolves the shared cookie from an HTTP request.

func (*Store) Revoke

func (s *Store) Revoke(ctx context.Context, value string) error

Revoke invalidates a session immediately. Repeated revocation is idempotent, which makes logout safe to retry.

func (*Store) RevokeRequest

func (s *Store) RevokeRequest(w http.ResponseWriter, r *http.Request)

RevokeRequest revokes the shared cookie, if one is present, and emits an expired cookie. It is safe for anonymous requests.

func (*Store) TTL

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

TTL returns the configured lifetime for newly issued sessions.

Jump to

Keyboard shortcuts

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