server

package
v0.1.0-alpha.11 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: Apache-2.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ProtocolVersion is the current realtime/RPC envelope version. Existing
	// versions are immutable; incompatible grammar requires a new version.
	ProtocolVersion = 1
)

Variables

View Source
var (
	ErrUnauthenticated = errors.New("meldbase server: unauthenticated")
	ErrForbidden       = errors.New("meldbase server: forbidden")
)
View Source
var ErrInvalidPolicyLease = errors.New("meldbase server: invalid query policy lease")

Functions

This section is empty.

Types

type Authenticator

type Authenticator interface {
	AuthenticateHTTP(*http.Request) (Principal, error)
}

type Authorizer

type Authorizer interface {
	AuthorizeQuery(context.Context, Principal, string, meldbase.QuerySpec) (QueryPolicy, error)
	AuthorizeInsert(context.Context, Principal, string, meldbase.Document) (InsertPolicy, error)
	AuthorizeUpdate(context.Context, Principal, string, meldbase.QuerySpec, meldbase.MutationSpec) (UpdatePolicy, error)
	AuthorizeDelete(context.Context, Principal, string, meldbase.QuerySpec) (DeletePolicy, error)
}

type Config

type Config struct {
	DB                             *meldbase.DB
	Authenticator                  Authenticator
	Authorizer                     Authorizer
	QueryPolicyResolver            QueryPolicyResolver
	PublicRealtimeURL              string
	OriginPatterns                 []string
	AllowedHTTPOrigins             []string
	TicketTTL                      time.Duration
	ResumeTokenKey                 []byte
	ResumeTokenTTL                 time.Duration
	MaxBodyBytes                   int
	MaxQueryResultBytes            int
	MaxRealtimeFrameBytes          int
	MaxRealtimeOutboundBytes       int
	MaxSubscriptionsPerConnection  int
	QueryLimits                    meldbase.QueryLimits
	ReplaySource                   meldbase.QueryReplaySource
	RPCMethods                     map[string]RPCMethod
	RPCTransactionalMethods        map[string]RPCTransactionalMethod
	RPCMethodResolver              RPCMethodResolver
	RPCTransactionalMethodResolver RPCTransactionalMethodResolver
	RPCAuthorizer                  RPCAuthorizer
	MaxConcurrentRPC               int
	MaxRPCPerConnection            int
	MaxRPCArguments                int
	MaxRPCResultBytes              int
	RPCIdempotencyStore            RPCIdempotencyStore
	RPCIdempotencyRetention        time.Duration
	RPCIdempotencyCommitTimeout    time.Duration
}

type DeletePolicy

type DeletePolicy struct {
	QueryPolicy
	MaxAffected int
}

type DurablePolicyGenerationStore

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

func NewDurablePolicyGenerationStore

func NewDurablePolicyGenerationStore(db *meldbase.DB) (*DurablePolicyGenerationStore, error)

func (*DurablePolicyGenerationStore) LoadPolicyGeneration

func (store *DurablePolicyGenerationStore) LoadPolicyGeneration(ctx context.Context, collection string) ([16]byte, bool, error)

type DurableRPCIdempotencyStore

type DurableRPCIdempotencyStore interface {
	RPCIdempotencyStore
	RPCIdempotencyMaintenance
}

func NewDurableRPCIdempotencyStore

func NewDurableRPCIdempotencyStore(db *meldbase.DB) (DurableRPCIdempotencyStore, error)

NewDurableRPCIdempotencyStore creates the built-in -backed store. Memory databases and V1 files are rejected rather than receiving a non-durable fallback.

type HS256JWTAuthenticator

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

HS256JWTAuthenticator verifies a bounded Bearer JWT and maps its subject and active workspace claim to the server Principal.

func NewHS256JWTAuthenticator

func NewHS256JWTAuthenticator(config HS256JWTAuthenticatorConfig) (*HS256JWTAuthenticator, error)

func (*HS256JWTAuthenticator) AuthenticateHTTP

func (a *HS256JWTAuthenticator) AuthenticateHTTP(request *http.Request) (Principal, error)

type HS256JWTAuthenticatorConfig

type HS256JWTAuthenticatorConfig struct {
	Secret         []byte
	Issuer         string
	Audience       string
	WorkspaceClaim string
	Clock          func() time.Time
}

HS256JWTAuthenticatorConfig configures a locally verified JWT issuer. It is useful when an identity service signs short-lived access tokens with a shared secret. OIDC/JWKS verification can use the same Principal contract later; callers never supply a tenant separately from the signed token.

type Handler

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

func New

func New(config Config) (*Handler, error)

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*Handler) Stats

func (h *Handler) Stats() ServerStats

type InsertPolicy

type InsertPolicy struct {
	AllowAllInputFields  bool
	AllowedInputFields   map[string]struct{}
	SetFields            meldbase.Document
	AllowAllResultFields bool
	AllowedResultFields  map[string]struct{}
}

type PolicyGenerationStore

type PolicyGenerationStore interface {
	LoadPolicyGeneration(context.Context, string) ([16]byte, bool, error)
}

type Principal

type Principal struct {
	Subject string
	Tenant  string
}

type QueryPolicy

type QueryPolicy struct {
	PolicyVersion        string
	Lease                *QueryPolicyLease
	Constraint           *meldbase.QuerySpec
	MaxResults           int
	AllowAllQueryPaths   bool
	AllowedQueryPaths    map[string]struct{}
	AllowAllResultFields bool
	AllowedResultFields  map[string]struct{}
	// contains filtered or unexported fields
}

type QueryPolicyLease

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

QueryPolicyLease linearizes policy revocation against authorized output. Revoke first prevents new acquisitions and closes Done, then waits for every acquisition already encoding or enqueueing a response to finish. Frames already placed in the transport queue are considered authorized in flight. One lease may be shared by many subscriptions governed by the same version.

func NewQueryPolicyLease

func NewQueryPolicyLease(version string) (*QueryPolicyLease, error)

func (*QueryPolicyLease) Done

func (lease *QueryPolicyLease) Done() <-chan struct{}

func (*QueryPolicyLease) Revoke

func (lease *QueryPolicyLease) Revoke(ctx context.Context) error

Revoke is idempotent. A canceled context stops waiting but does not undo the revocation; a later call may wait for the same lease to drain.

func (*QueryPolicyLease) Valid

func (lease *QueryPolicyLease) Valid() bool

func (*QueryPolicyLease) Version

func (lease *QueryPolicyLease) Version() string

type QueryPolicyResolver

type QueryPolicyResolver interface {
	ResolveQueryPolicy(context.Context, Principal, string, meldbase.QuerySpec) (QueryPolicy, bool, error)
}

QueryPolicyResolver adds a dynamic, data-only visibility policy after the application's Authorizer has allowed a query. When configured, a missing resolution fails closed. Implementations may never return documents; they only narrow row membership, query paths, result fields and result count.

type RPCAuthorizer

type RPCAuthorizer interface {
	AuthorizeRPC(context.Context, Principal, string) error
}

RPCAuthorizer is evaluated for every call before arguments are decoded or application code runs. Registration alone never grants call permission.

type RPCError

type RPCError struct {
	Code string
}

RPCError exposes one stable, non-sensitive application error code. Arbitrary handler errors are returned as "internal" and their text never crosses the transport boundary.

func (*RPCError) Error

func (err *RPCError) Error() string

type RPCIdempotencyClaim

type RPCIdempotencyClaim struct {
	ScopeHash   [32]byte
	KeyHash     [32]byte
	Fingerprint [32]byte
	SessionID   [16]byte
	ClaimID     [16]byte
	ExpiresAt   time.Time
}

RPCIdempotencyClaim is persisted before application code starts. ScopeHash and KeyHash prevent the durable keyspace from retaining raw identities or caller keys. SessionID and ClaimID are compare-and-set ownership tokens.

type RPCIdempotencyCompletion

type RPCIdempotencyCompletion struct {
	Claim       RPCIdempotencyClaim
	Result      []byte
	ErrorCode   string
	ErrorStatus int
}

type RPCIdempotencyDecision

type RPCIdempotencyDecision struct {
	Kind        RPCIdempotencyDecisionKind
	Result      []byte
	ErrorCode   string
	ErrorStatus int
}

type RPCIdempotencyDecisionKind

type RPCIdempotencyDecisionKind uint8
const (
	RPCIdempotencyExecute RPCIdempotencyDecisionKind = iota + 1
	RPCIdempotencyReplayResult
	RPCIdempotencyReplayError
	RPCIdempotencyInProgress
	RPCIdempotencyOutcomeUnknown
	RPCIdempotencyConflict
)

type RPCIdempotencyMaintenance

type RPCIdempotencyMaintenance interface {
	// PruneExpired removes at most limit completed/error/unknown records after
	// their retention window. Pending records are never removed by time alone.
	PruneExpired(context.Context, int) (int, error)
}

type RPCIdempotencyStore

RPCIdempotencyStore must be linearizable and durable. Claim must publish a new pending record before returning Execute. Complete and MarkUnknown are CAS transitions matching SessionID and ClaimID. Implementations must never turn a pending record owned by another session back into Execute.

type RPCMethod

type RPCMethod func(context.Context, Principal, []meldbase.Value) (meldbase.Value, error)

RPCMethod is a bounded, authenticated data-only request handler. Arguments and results use Meldbase's closed Value model, preserving Int64, Date, Binary and object semantics across Go and JavaScript.

type RPCMethodResolver

type RPCMethodResolver interface {
	ResolveRPCMethod(string) (RPCMethod, bool)
}

RPCMethodResolver resolves dynamic trusted-worker methods. It is consulted only after the immutable local registry misses.

type RPCTransactionalMethod

type RPCTransactionalMethod func(context.Context, Principal, []meldbase.Value, *meldbase.WriteTransaction) (meldbase.Value, error)

RPCTransactionalMethod stages point writes against a short immutable snapshot. A successful result and all staged writes share one durable publication with the RPC idempotency terminal record after optimistic commit validation.

type RPCTransactionalMethodResolver

type RPCTransactionalMethodResolver interface {
	ResolveRPCTransactionalMethod(string) (RPCTransactionalMethod, bool)
}

RPCTransactionalMethodResolver is the equivalent dynamic boundary for transaction-aware methods.

type RS256JWKSAuthenticator

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

func (*RS256JWKSAuthenticator) AuthenticateHTTP

func (a *RS256JWKSAuthenticator) AuthenticateHTTP(request *http.Request) (Principal, error)

type RS256JWKSAuthenticatorConfig

type RS256JWKSAuthenticatorConfig struct {
	JWKSURL        string
	Issuer         string
	Audience       string
	WorkspaceClaim string
	HTTPClient     *http.Client
	Clock          func() time.Time
	CacheTTL       time.Duration
}

RS256JWKSAuthenticatorConfig configures verification against an OIDC-style JSON Web Key Set. Issuer and audience are required so a token minted for a different API cannot become a Meldbase credential.

type ServerStats

type ServerStats struct {
	CapturedAt                time.Time      `json:"capturedAt"`
	StartedAt                 time.Time      `json:"startedAt"`
	ActiveConnections         uint64         `json:"activeConnections"`
	ConnectionsAccepted       uint64         `json:"connectionsAccepted"`
	RealtimeOutboundOverflows uint64         `json:"realtimeOutboundOverflows"`
	RPCRequests               uint64         `json:"rpcRequests"`
	RPCActive                 uint64         `json:"rpcActive"`
	RPCSucceeded              uint64         `json:"rpcSucceeded"`
	RPCFailed                 uint64         `json:"rpcFailed"`
	RPCCanceled               uint64         `json:"rpcCanceled"`
	RPCRejected               uint64         `json:"rpcRejected"`
	RPCBusy                   uint64         `json:"rpcBusy"`
	RPCArguments              uint64         `json:"rpcArguments"`
	RPCRequestBytes           uint64         `json:"rpcRequestBytes"`
	RPCResultBytes            uint64         `json:"rpcResultBytes"`
	RPCTotalNanos             uint64         `json:"rpcTotalNanos"`
	RPCMaxLatency             time.Duration  `json:"rpcMaxLatencyNanos"`
	RPCIdempotencyClaims      uint64         `json:"rpcIdempotencyClaims"`
	RPCIdempotencyReplays     uint64         `json:"rpcIdempotencyReplays"`
	RPCIdempotencyConflicts   uint64         `json:"rpcIdempotencyConflicts"`
	RPCIdempotencyInProgress  uint64         `json:"rpcIdempotencyInProgress"`
	RPCIdempotencyUnknown     uint64         `json:"rpcIdempotencyUnknown"`
	RPCIdempotencyFailures    uint64         `json:"rpcIdempotencyFailures"`
	RPCAtomicCommits          uint64         `json:"rpcAtomicCommits"`
	RPCAtomicRollbacks        uint64         `json:"rpcAtomicRollbacks"`
	RPCAtomicNoopCompletions  uint64         `json:"rpcAtomicNoopCompletions"`
	Worker                    WorkerHubStats `json:"worker"`
}

ServerStats is a fixed-cardinality process-session snapshot. It deliberately contains no method, principal, tenant, argument, result or error text.

type UpdatePolicy

type UpdatePolicy struct {
	QueryPolicy
	AllowAllUpdatePaths bool
	AllowedUpdatePaths  map[string]struct{}
	DeniedUpdatePaths   map[string]struct{}
	MaxAffected         int
}

type WorkerAuthenticator

type WorkerAuthenticator interface {
	AuthenticateWorker(*http.Request) (WorkerPrincipal, error)
}

WorkerAuthenticator is a separate control-plane trust boundary. Client authenticators must never be reused implicitly for worker connections.

func NewWorkerTokenAuthenticator

func NewWorkerTokenAuthenticator(token string) (WorkerAuthenticator, error)

NewWorkerTokenAuthenticator creates a constant-time bearer authenticator. The raw token is not retained after construction.

type WorkerHub

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

WorkerHub routes dynamically registered, separately authenticated worker methods. Mount it on a private control listener and pass it as both resolver fields when transactional worker methods are desired.

func NewWorkerHub

func NewWorkerHub(config WorkerHubConfig) (*WorkerHub, error)

func (*WorkerHub) ResolveQueryPolicy

func (hub *WorkerHub) ResolveQueryPolicy(ctx context.Context, principal Principal, collection string, query meldbase.QuerySpec) (QueryPolicy, bool, error)

func (*WorkerHub) ResolveRPCMethod

func (hub *WorkerHub) ResolveRPCMethod(name string) (RPCMethod, bool)

func (*WorkerHub) ResolveRPCTransactionalMethod

func (hub *WorkerHub) ResolveRPCTransactionalMethod(name string) (RPCTransactionalMethod, bool)

func (*WorkerHub) ServeHTTP

func (hub *WorkerHub) ServeHTTP(writer http.ResponseWriter, request *http.Request)

func (*WorkerHub) Stats

func (hub *WorkerHub) Stats() WorkerHubStats

type WorkerHubConfig

type WorkerHubConfig struct {
	Authenticator            WorkerAuthenticator
	PublicationCollections   []string
	RegistrationTimeout      time.Duration
	MaxFrameBytes            int
	MaxMethodsPerWorker      int
	MaxPublicationsPerWorker int
	MaxPendingCalls          int
	MaxOperationsPerCall     int
	PolicyQueryLimits        meldbase.QueryLimits
	PolicyEvaluationTimeout  time.Duration
	PolicyGenerationStore    PolicyGenerationStore
}

type WorkerHubStats

type WorkerHubStats struct {
	ConnectedWorkers       uint64 `json:"connectedWorkers"`
	RegisteredMethods      uint64 `json:"registeredMethods"`
	RegisteredPublications uint64 `json:"registeredPublications"`
	CallsStarted           uint64 `json:"callsStarted"`
	CallsActive            uint64 `json:"callsActive"`
	CallsSucceeded         uint64 `json:"callsSucceeded"`
	CallsFailed            uint64 `json:"callsFailed"`
	CallsCanceled          uint64 `json:"callsCanceled"`
	CallsBusy              uint64 `json:"callsBusy"`
	ProtocolFailures       uint64 `json:"protocolFailures"`
	BytesReceived          uint64 `json:"bytesReceived"`
	BytesSent              uint64 `json:"bytesSent"`
	TransactionOps         uint64 `json:"transactionOps"`
	PolicyEvaluations      uint64 `json:"policyEvaluations"`
	PolicyActive           uint64 `json:"policyActive"`
	PolicySucceeded        uint64 `json:"policySucceeded"`
	PolicyDenied           uint64 `json:"policyDenied"`
	PolicyFailed           uint64 `json:"policyFailed"`
	PolicyCanceled         uint64 `json:"policyCanceled"`
	PolicyBusy             uint64 `json:"policyBusy"`
	PolicyInvalidations    uint64 `json:"policyInvalidations"`
}

type WorkerPrincipal

type WorkerPrincipal struct{ Subject string }

type WorkspaceAuthorizer

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

WorkspaceAuthorizer is a data-only Authorizer for ordinary application collections. It is intentionally not a user or membership store; an external identity provider supplies Principal.Tenant from the active workspace claim.

func NewWorkspaceAuthorizer

func NewWorkspaceAuthorizer(config WorkspaceAuthorizerConfig) (*WorkspaceAuthorizer, error)

func (*WorkspaceAuthorizer) AuthorizeDelete

func (a *WorkspaceAuthorizer) AuthorizeDelete(ctx context.Context, principal Principal, collection string, query meldbase.QuerySpec) (DeletePolicy, error)

func (*WorkspaceAuthorizer) AuthorizeInsert

func (a *WorkspaceAuthorizer) AuthorizeInsert(_ context.Context, principal Principal, collection string, _ meldbase.Document) (InsertPolicy, error)

func (*WorkspaceAuthorizer) AuthorizeQuery

func (a *WorkspaceAuthorizer) AuthorizeQuery(_ context.Context, principal Principal, collection string, _ meldbase.QuerySpec) (QueryPolicy, error)

func (*WorkspaceAuthorizer) AuthorizeRPC

AuthorizeRPC fails closed until an application supplies an explicit method-level authorizer. Workspace collection membership alone must not grant access to trusted server methods.

func (*WorkspaceAuthorizer) AuthorizeUpdate

func (a *WorkspaceAuthorizer) AuthorizeUpdate(ctx context.Context, principal Principal, collection string, query meldbase.QuerySpec, _ meldbase.MutationSpec) (UpdatePolicy, error)

type WorkspaceAuthorizerConfig

type WorkspaceAuthorizerConfig struct {
	Collections    []string
	WorkspaceField string
	MaxResults     int
	MaxAffected    int
}

WorkspaceAuthorizerConfig declares which collections are scoped to the authenticated principal's current workspace. The workspace field is owned by the server: inserts set it and updates may never modify it.

Jump to

Keyboard shortcuts

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