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
- Variables
- func ClearCookie(w http.ResponseWriter)
- func ConstantTimeEqual(a, b string) bool
- type Backend
- type Config
- type Identity
- type Record
- type Session
- type Store
- func (s *Store) Issue(ctx context.Context, identity Identity) (string, Session, error)
- func (s *Store) IssueHTTP(ctx context.Context, w http.ResponseWriter, identity Identity) (Session, error)
- func (s *Store) IssueTransient(ctx context.Context, identity Identity, ttl time.Duration) (string, Session, error)
- func (s *Store) Resolve(ctx context.Context, value string) (Session, error)
- func (s *Store) ResolveRequest(r *http.Request) (Session, error)
- func (s *Store) Revoke(ctx context.Context, value string) error
- func (s *Store) RevokeRequest(w http.ResponseWriter, r *http.Request)
- func (s *Store) TTL() time.Duration
Constants ¶
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 ¶
Functions ¶
func ClearCookie ¶
func ClearCookie(w http.ResponseWriter)
ClearCookie writes an expired shared cookie without touching server state.
func ConstantTimeEqual ¶
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 ¶
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 ¶
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 ¶
New creates a browser-session store. Without Config.Backend it keeps records in bounded process-local memory.
func (*Store) Issue ¶
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) ResolveRequest ¶
ResolveRequest resolves the shared cookie from an HTTP request.
func (*Store) Revoke ¶
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.