sharedstore

package
v0.2.39 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package sharedstore is the hub's cross-replica key/value store for short-lived login state: browser sessions and published-app authorization codes.

Both are minted by whichever replica served the request and redeemed by whichever replica the load balancer picks next, so process-local maps break as soon as the hub runs more than one pod. Entries live as Secrets in root:railgrid:system:controllers — a hub-internal workspace no tenant, provider, or user identity can reach — which keeps the hub's only hard dependency kcp.

Values are opaque to this package. Keys are hashed into the object name, so neither a session handle nor an authorization code is recoverable from resource names in logs, audit records, or metrics.

Index

Constants

View Source
const ActionProofUseKind = "railgrid-action-proof-use"
View Source
const AppCodeKind = "railgrid-appcode"

AppCodeKind is the shared-store collection holding published-app authorization codes.

View Source
const (
	// LabelKind marks every Secret this package owns and names the logical
	// collection, so the sweeper can list one kind without touching the other.
	LabelKind = "railgrid.ai/shared-store"
)
View Source
const PreviewAppCodeKind = "railgrid-preview-appcode-v2"

PreviewAppCodeKind is a versioned, isolated collection for scoped preview handoff and app-authorization codes. Older replicas must not be able to consume scoped codes as ordinary app codes while ignoring their scope and purpose fields.

View Source
const PreviewSessionKind = "railgrid-preview-session-v2"

PreviewSessionKind is deliberately separate from SessionKind. Older hub replicas decode session JSON without scoped fields and would otherwise treat a preview handle as an ordinary portal session if it were presented under the portal cookie name.

View Source
const SessionKind = "railgrid-session"

SessionKind is the shared-store collection holding browser sessions.

Variables

View Source
var ErrNotFound = errors.New("sharedstore: entry not found")

ErrNotFound is returned when a key is absent, expired, or already redeemed.

Functions

func RunGC

func RunGC(ctx context.Context, interval time.Duration, stores ...*Store)

RunGC sweeps expired entries on interval until ctx is done. Intended to run only on the leader; a second sweeper would merely duplicate deletes.

Types

type ActionProofUseStore added in v0.2.21

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

ActionProofUseStore adapts a Store collection to actionproof.UseStore.

func NewActionProofUseStore added in v0.2.21

func NewActionProofUseStore(store *Store) *ActionProofUseStore

NewActionProofUseStore adapts the supplied collection for durable cross-replica action-proof use tracking.

func (*ActionProofUseStore) Consume added in v0.2.21

func (s *ActionProofUseStore) Consume(ctx context.Context, nonce, capability, method, path string, expiresAt time.Time) (bool, error)

type AppCodeStore

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

AppCodeStore adapts Store to appauth.CodeStore, so a code minted on the replica that served the browser's authorize hop can be redeemed on whichever replica the access proxy reaches for the exchange.

Single-use is enforced by Store.Take's resource-version-guarded delete: two concurrent exchanges of one code produce exactly one success, no matter which replicas run them.

func NewAppCodeStore

func NewAppCodeStore(config *rest.Config, namespace string) (*AppCodeStore, error)

NewAppCodeStore builds the shared authorization-code store. config must target the workspace holding the entries.

func NewPreviewAppCodeStore added in v0.2.16

func NewPreviewAppCodeStore(config *rest.Config, namespace string) (*AppCodeStore, error)

NewPreviewAppCodeStore builds the isolated shared collection for scoped preview codes. Ordinary app authorization codes remain in AppCodeKind for mixed-version compatibility.

func (*AppCodeStore) Peek added in v0.2.21

func (s *AppCodeStore) Peek(ctx context.Context, code string) (appauth.CodeRecord, bool, error)

Peek reads an app authorization code without consuming it. The separate error result lets identity exchange distinguish a missing/expired code from a shared-store outage and return a retryable response for the latter.

func (*AppCodeStore) Put

func (s *AppCodeStore) Put(ctx context.Context, code string, record appauth.CodeRecord) error

func (*AppCodeStore) Store

func (s *AppCodeStore) Store() *Store

Store exposes the underlying collection so the leader can sweep it.

func (*AppCodeStore) Take

func (s *AppCodeStore) Take(ctx context.Context, code string) (appauth.CodeRecord, bool)

type SessionBackend

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

SessionBackend adapts Store to browsersession.Backend so every hub replica resolves and revokes the same cookies.

Revocation is a delete, not a tombstone: a handle is 32 bytes of crypto/rand, so the collision the in-memory backend's tombstones guard against cannot occur, and a delete propagates to every replica immediately instead of depending on a per-process marker.

func NewPreviewSessionBackend added in v0.2.16

func NewPreviewSessionBackend(config *rest.Config, namespace string) (*SessionBackend, error)

NewPreviewSessionBackend builds the isolated collection for short-lived, one-app preview sessions. It must not share SessionKind with portal logins: older hub replicas ignore the scoped identity fields when decoding a shared session record.

func NewSessionBackend

func NewSessionBackend(config *rest.Config, namespace string) (*SessionBackend, error)

NewSessionBackend builds the shared browser-session backend. config must target the workspace holding the entries.

func (*SessionBackend) Get

func (*SessionBackend) Put

func (b *SessionBackend) Put(ctx context.Context, key string, record browsersession.Record) error

func (*SessionBackend) Revoke

func (b *SessionBackend) Revoke(ctx context.Context, key string, _ time.Time) error

func (*SessionBackend) Store

func (b *SessionBackend) Store() *Store

Store exposes the underlying collection so the leader can sweep it.

type Store

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

Store is one logical collection of entries (all sharing a `kind`) inside a single kcp workspace namespace. It is safe for concurrent use — it holds no state beyond its client.

func New

func New(config *rest.Config, namespace, kind string) (*Store, error)

New builds a Store. config must already target the workspace holding the entries (its Host carries the /clusters/<path> segment). kind must be a valid label value and DNS-name prefix — it namespaces one collection from another inside the same Kubernetes namespace.

func (*Store) CreateIfAbsent added in v0.2.21

func (s *Store) CreateIfAbsent(ctx context.Context, key string, value []byte, expiresAt time.Time) (bool, error)

CreateIfAbsent atomically creates value under key. The Kubernetes API's Create operation is the cross-replica compare-and-set: exactly one caller can claim a key, while all others observe AlreadyExists.

func (*Store) Delete

func (s *Store) Delete(ctx context.Context, key string) error

Delete removes an entry. It is idempotent, which makes logout safe to retry.

func (*Store) GC

func (s *Store) GC(ctx context.Context) (int, error)

GC deletes every expired entry of this kind and returns how many it removed. Readers already refuse expired entries, so this only reclaims space — run it on the elected replica.

func (*Store) Get

func (s *Store) Get(ctx context.Context, key string) ([]byte, error)

Get returns the value stored under key. An expired entry reports ErrNotFound and is deleted opportunistically, so a stale record cannot outlive its expiry even if the sweeper is not running.

func (*Store) Put

func (s *Store) Put(ctx context.Context, key string, value []byte, expiresAt time.Time) error

Put writes value under key, replacing any existing entry, and stamps the expiry the reader enforces.

func (*Store) Take

func (s *Store) Take(ctx context.Context, key string) ([]byte, error)

Take returns the value stored under key and removes it in the same breath. The delete is guarded by the resource version observed on read, so exactly one caller across every replica can redeem a given key — the guarantee a single-use authorization code depends on.

Jump to

Keyboard shortcuts

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