// Package session defines the authenticated session-cache contract used by the // gateway hot path. package session import ( "context" "errors" ) var ( // ErrNotFound reports that SessionCache does not currently contain the // requested device session identifier. ErrNotFound = errors.New("session cache record not found") ) // Cache resolves authenticated device-session state from the gateway // hot path. The canonical implementation is *MemoryCache: a // process-local LRU + TTL store that falls back to backend's // `/api/v1/internal/sessions/{id}` on miss and listens for // `session_invalidation` push events from backend so revoked sessions // are reflected immediately without a fresh backend lookup. // // The Mark* methods are called by the push dispatcher. They flip // cached entries to revoked status; subsequent Lookups serve the // revoked record directly so authenticated traffic on those sessions // is rejected at the edge before reaching backend. type Cache interface { // Lookup returns the cached record for deviceSessionID. Implementations must // wrap ErrNotFound when the cache does not contain the requested record. Lookup(ctx context.Context, deviceSessionID string) (Record, error) // MarkRevoked flips the cached record for deviceSessionID to a // revoked status. Calling on a missing entry is a no-op. MarkRevoked(deviceSessionID string) // MarkAllRevokedForUser flips every cached record belonging to // userID to a revoked status. Calling on a user with no cached // sessions is a no-op. MarkAllRevokedForUser(userID string) } // Status identifies the cached lifecycle state of a device session. type Status string const ( // StatusActive reports that the cached device session may continue through // later authenticated gateway checks. StatusActive Status = "active" // StatusRevoked reports that the cached device session has been revoked and // must be rejected before later auth steps run. StatusRevoked Status = "revoked" ) // Record is the minimum authenticated session state required by the gateway // before signature verification begins. type Record struct { // DeviceSessionID is the stable device-session identifier resolved from the // hot-path cache. DeviceSessionID string // UserID is the authenticated user identity bound to DeviceSessionID. UserID string // ClientPublicKey is the standard base64-encoded raw Ed25519 public key // material used for request-signature verification. ClientPublicKey string // Status reports whether the cached session is active or revoked. Status Status // RevokedAtMS optionally records when the device session was revoked. RevokedAtMS *int64 } // IsKnown reports whether s is one of the session states supported by the // gateway. func (s Status) IsKnown() bool { switch s { case StatusActive, StatusRevoked: return true default: return false } }