Documentation
¶
Overview ¶
Package bootstrap loads configuration and assembles the application: it resolves secret placeholders, opens the database provider, converts config entities to the core entity model, and wires the registry, authorizer, cost gate, engine, and tools. It is the only place that imports gopkg.in/yaml.v3 and x/providers.
Index ¶
- Variables
- func CapabilityWarnings(cfg *config.Config, capabilities EntityCapabilities) []string
- func CheckHotReload(old, next *config.Config) error
- func CheckOffline(cfg *config.Config) error
- func CheckPublishable(current, target revision.Revision, restartRequired bool) error
- func Load(path string) (*config.Config, error)
- func LoadBytes(data []byte) (*config.Config, error)
- func LoadRevision(rev revision.Revision) (*config.Config, error)
- func LoadRevisionSpec(rev revision.Revision) (*config.Spec, *config.Config, error)
- func OfflineAuthorizer(cfg *config.Config) (rbac.Authorizer, error)
- func RedactDSN(driver, dsn string) string
- func RestartChanges(old, next *config.Config) []string
- func UserPrincipal(user string) string
- func ValidateFile(path string, resolver SecretResolver) error
- func ValidateStorePayload(cfg *config.Config) error
- type App
- func Assemble(cfg *config.Config) (*App, error)
- func AssembleWithConnections(cfg *config.Config, connections Connections) (*App, error)
- func AssembleWithProvider(cfg *config.Config, prov Provider) (*App, error)
- func AssembleWithProviders(cfg *config.Config, providers map[string]Provider) (*App, error)
- func AssembleWithResolver(cfg *config.Config, r SecretResolver) (*App, error)
- func (a *App) Bus() *bus.Bus
- func (a *App) Capabilities() EntityCapabilities
- func (a *App) Close() error
- func (a *App) CloseContext(ctx context.Context) error
- func (a *App) Config() *config.Config
- func (a *App) OpenScan(ctx context.Context, database config.DatabaseConfig) (p Provider, ok bool, err error)
- func (a *App) Ping(ctx context.Context) error
- func (a *App) Services() *tool.Services
- func (a *App) ToolContext(role string) tool.Context
- func (a *App) ToolContextForSubject(role string, subject map[string]any) tool.Context
- func (a *App) UserByName(name string) (UserIdentity, bool)
- func (a *App) UserByTokenHash(hash string) (UserIdentity, bool)
- func (a *App) WaitCapabilities(ctx context.Context) (EntityCapabilities, error)
- type Capability
- type Connections
- type EntityCapabilities
- type EnvFileResolver
- type Provider
- type Runtime
- func (r *Runtime) Acquire() (*App, func(), error)
- func (r *Runtime) AppliedRevision() int64
- func (r *Runtime) Close() error
- func (r *Runtime) CloseContext(ctx context.Context) error
- func (r *Runtime) Current() *App
- func (r *Runtime) DatabasesReady(ctx context.Context) error
- func (r *Runtime) OnPublish(fn func(*App))
- func (r *Runtime) OnRevokedPrincipals(fn func([]string) []string)
- func (r *Runtime) Reload(path string) error
- func (r *Runtime) ReloadWith(build func() (*App, error)) error
- func (r *Runtime) RollbackSession(session string)
- func (r *Runtime) SnapshotReady(context.Context) error
- func (r *Runtime) Stale() (StaleState, bool)
- func (r *Runtime) UserByName(name string) (UserIdentity, bool)
- func (r *Runtime) UserByTokenHash(hash string) (UserIdentity, bool)
- func (r *Runtime) Watch(ctx context.Context, path string, interval time.Duration, onError func(error)) error
- func (r *Runtime) WatchStore(ctx context.Context, store revision.Store, current int64, ...) error
- type SecretResolver
- type Shared
- type StaleState
- type UserIdentity
Constants ¶
This section is empty.
Variables ¶
var ErrPlaintextSecret = errors.New("store payload must not contain plaintext secrets")
ErrPlaintextSecret rejects store payloads that would persist credentials.
var ErrReloadBacklog = errors.New("bootstrap: earlier configurations are still draining; try again")
ErrReloadBacklog is returned by a reload while maxRetiring replaced snapshots still serve requests: each holds its own engine and prepared statements, so reloads wait for them to drain rather than pile them up.
var ErrRestartRequired = errors.New("config change requires restart")
ErrRestartRequired marks a configuration change that cannot be applied by hot reload or publish without restarting the server.
var ErrRuntimeClosed = errors.New("bootstrap: runtime closed")
ErrRuntimeClosed is returned when a closed runtime is used.
var ErrUnsupportedDriver = providerregistry.ErrUnsupportedDriver
ErrUnsupportedDriver is returned for a driver with no provider yet.
Functions ¶
func CapabilityWarnings ¶ added in v0.1.11
func CapabilityWarnings(cfg *config.Config, capabilities EntityCapabilities) []string
CapabilityWarnings lists actions cfg grants that the routed connection cannot run, in a stable order.
func CheckHotReload ¶ added in v0.1.11
CheckHotReload reports whether next can replace old without a restart. File reload, store reload and store publish share this rule: the transport, the address, and serving TLS or not need a restart; the rest, authentication and the listed tools included, follows a reload.
func CheckOffline ¶ added in v0.1.13
CheckOffline reports whether cfg passes the steps of assembling it that need no database (entities, grants, the masker), so a configuration the runtime would refuse to load is refused before it is stored or published even where validation misses a rule of those steps. What the databases hold (tables, columns, default schemas) is checked only when assembling.
func CheckPublishable ¶ added in v0.1.11
CheckPublishable verifies that target loads under the store rules and passes the offline assembly checks (CheckOffline) and, when current is published (ID != 0), that switching to target needs no restart unless restartRequired is set. A current revision that no longer loads can only be replaced with restartRequired.
func LoadBytes ¶ added in v0.1.11
LoadBytes decodes, defaults and validates YAML configuration bytes and checks that every driver is registered, like Load does for a file.
func LoadRevision ¶ added in v0.1.11
LoadRevision verifies a revision's content hash and decodes its payload under the store-mode secret rule.
func LoadRevisionSpec ¶ added in v0.1.13
LoadRevisionSpec is LoadRevision keeping what the payload says too.
func OfflineAuthorizer ¶ added in v0.1.11
func OfflineAuthorizer(cfg *config.Config) (rbac.Authorizer, error)
OfflineAuthorizer compiles cfg's entities, roles and users into an authorizer without connecting to any database, for policy simulation.
func RedactDSN ¶
RedactDSN returns dsn with every password the driver would read replaced by ***, for logging and display.
func RestartChanges ¶ added in v0.1.11
RestartChanges lists the changes from old to next that need a restart.
func UserPrincipal ¶ added in v0.1.11
UserPrincipal returns the principal key of a configured user.
func ValidateFile ¶
func ValidateFile(path string, resolver SecretResolver) error
ValidateFile parses, defaults, validates, runs the offline assembly checks (CheckOffline) and resolves secrets without opening database connections.
func ValidateStorePayload ¶ added in v0.1.11
ValidateStorePayload enforces the store-mode secret rule: every non-empty DSN password must come from a ${...} placeholder and server.auth.token must be empty (configured users keep only token hashes).
Types ¶
type App ¶
type App struct {
// Provider is the read connection of the default datasource (the one a
// request names none of).
Provider Provider
// Providers holds each datasource's read connection, which also serves
// introspection and EXPLAIN; Connections holds every connection.
Providers map[string]Provider
Connections Connections
Prepared map[string]*store.PreparedDB
Sources map[string]tool.DataSource
Registry *entity.Registry
Authorizer rbac.Authorizer
Masker mask.Masker
Engine *engine.Engine
Tools *tool.Registry
ToolFlags config.ToolFlags
DefaultRole string
DefaultUser string
// Users maps an enabled user name to its identity; UserTokens maps a
// tokenHash to the user name. Both follow the snapshot on reload.
Users map[string]UserIdentity
UserTokens map[string]string
Limits tool.Limits
Auditor audit.Auditor
Hooks *hook.Hooks
Cache cache.Cache[[]map[string]any]
Feedback cost.FeedbackStore
Budget *budget.MemoryManager
Transactions *tool.TransactionManager
Writes *tool.WriteTracker
ResultMemory *tool.ResultMemory
TxBeginners map[string]store.TxBeginner
// WriteTargets are what a write through each entity invalidates.
WriteTargets *tool.WriteTargets
// contains filtered or unexported fields
}
App is the assembled application, ready to serve.
func Assemble ¶
Assemble opens the provider and wires the application from cfg, using the default EnvFileResolver for secret placeholders.
func AssembleWithConnections ¶ added in v0.1.11
func AssembleWithConnections(cfg *config.Config, connections Connections) (*App, error)
AssembleWithConnections wires opened connections. Ownership transfers to the returned App on success. On failure the connections stay with the caller and every resource acquired here is released: configuration is checked before any resource is acquired. Each datasource's read connection serves introspection and EXPLAIN.
func AssembleWithProvider ¶
AssembleWithProvider wires the application using an injected provider (for testing with fakes).
func AssembleWithProviders ¶
AssembleWithProviders wires one provider per datasource, serving every connection the datasource configures. It is intended for tests and embedders; ownership transfers to the returned App on success.
func AssembleWithResolver ¶
func AssembleWithResolver(cfg *config.Config, r SecretResolver) (*App, error)
AssembleWithResolver resolves secrets with the given resolver, opens the provider, and wires the application. Use a custom resolver to integrate secret managers (Vault, AWS Secrets Manager, etc.) without coupling core to any specific backend.
func (*App) Bus ¶ added in v0.1.13
Bus returns the execution bus the App runs on; nil for an App assembled without shared services, whose work then runs unbounded by a bus.
func (*App) Capabilities ¶ added in v0.1.11
func (a *App) Capabilities() EntityCapabilities
Capabilities returns what the routed connections may do per entity action, as the databases reported after the App was assembled; nil (unknown) while they are being assessed.
func (*App) Close ¶
Close preserves the original unbounded close contract. Callers that need a shutdown deadline should use CloseContext.
func (*App) CloseContext ¶
CloseContext stops engine admission and drains all execution before rolling back transactions and releasing audit/provider resources.
func (*App) OpenScan ¶ added in v0.1.12
func (a *App) OpenScan(ctx context.Context, database config.DatabaseConfig) (p Provider, ok bool, err error)
OpenScan opens a connection of its own to the read connection of database, as given, for a schema scan: it takes no serving connection and does not hold the snapshot, so neither requests nor reloads wait for the scan, and it reads the database the caller names even before this App is replaced by one configured so. The caller closes it; ctx bounds opening it. ok is false when the App was assembled from connections it was handed and cannot open more.
func (*App) Ping ¶ added in v0.1.6
Ping verifies every configured database is reachable. It backs the /readyz/db readiness probe and stays off the tool execution path: it uses the provider's native connection ping when exposed and falls back to a trivial query otherwise.
func (*App) ToolContext ¶
ToolContext builds a per-request tool.Context for the given role.
func (*App) ToolContextForSubject ¶
ToolContextForSubject builds a per-request tool.Context for a role plus subject attributes (referenced by row-level ${subject.x} policies).
func (*App) UserByName ¶ added in v0.1.11
func (a *App) UserByName(name string) (UserIdentity, bool)
UserByName returns an enabled user by name.
func (*App) UserByTokenHash ¶ added in v0.1.11
func (a *App) UserByTokenHash(hash string) (UserIdentity, bool)
UserByTokenHash returns the enabled user whose tokenHash matches.
func (*App) WaitCapabilities ¶ added in v0.1.12
func (a *App) WaitCapabilities(ctx context.Context) (EntityCapabilities, error)
WaitCapabilities waits for the assessment of capabilities, or for ctx.
type Capability ¶ added in v0.1.11
type Capability struct {
Privilege introspect.Privilege
Connection string
// Columns lists the columns granted at column level when the table-level
// privilege is not granted.
Columns []string
Reason string
}
Capability says whether the connection an entity action routes to may run it, as far as the database reports (I-3). It informs administrators; the database decides each statement.
type Connections ¶ added in v0.1.11
Connections are opened providers by datasource and connection name.
type EntityCapabilities ¶ added in v0.1.11
type EntityCapabilities map[string]map[entity.Action]Capability
EntityCapabilities are capabilities by entity and action.
type EnvFileResolver ¶
type EnvFileResolver struct {
AllowedRoots []string
}
EnvFileResolver resolves ${ENV} (environment variables) and ${file:/path} (file contents, e.g. Kubernetes Secret volume mounts).
type Provider ¶
type Provider = coreprovider.Provider
Provider aggregates the core interfaces a database adapter must satisfy.
type Runtime ¶
type Runtime struct {
// contains filtered or unexported fields
}
Runtime owns the atomically replaceable App snapshot used by serving handlers. A successful reload publishes the new App at once, so requests never wait for a reload, and drains and closes the old one in the background; a failed build leaves the current App untouched.
func NewRuntimeWithBuilder ¶
NewRuntimeWithBuilder creates a runtime with an injected reload builder. It is useful for embedders and tests that assemble providers themselves. Process state (transactions, budgets, write tracking) outlives a reload only when every App is assembled on one Shared; an App assembled without it owns that state, which goes as the App is retired (see docs/design/lifetimes.md).
func (*Runtime) Acquire ¶
Acquire leases the current snapshot until the returned release function is called. It retries when racing with retirement.
func (*Runtime) AppliedRevision ¶ added in v0.1.11
AppliedRevision returns the store revision the runtime serves as tracked by WatchStore, or 0 before WatchStore starts.
func (*Runtime) CloseContext ¶ added in v0.1.13
CloseContext stops new acquisitions at once, drains leases, and closes the current App and the ones reloads replaced. It does not wait for a reload being built: that reload closes what it built. Past ctx's deadline it returns ctx's error and leaves the rest to finish in the background (a stuck database call or audit sink must not hold up a process exit).
func (*Runtime) Current ¶
Current returns the currently published App, or nil after Close. Handlers that execute work must use Acquire so the App cannot close during the call.
func (*Runtime) DatabasesReady ¶ added in v0.1.6
DatabasesReady pings every database of the current snapshot. It backs the /readyz/db readiness probe.
func (*Runtime) OnPublish ¶ added in v0.1.12
OnPublish calls fn with the current App and then with every App a reload publishes, as it is published. Registering and the first call happen between reloads, so fn misses none. Transports use it to follow the configuration: the tools they list, how they authenticate.
func (*Runtime) OnRevokedPrincipals ¶ added in v0.1.11
OnRevokedPrincipals registers fn to receive the principal keys of users that a successful reload removed or disabled, as the new snapshot is published. Transports use it to drop those users' sessions and roll back their transactions; fn returns the sessions it dropped. Once requests on the old snapshot finish, transactions they opened in those sessions are rolled back too. Sessions are named by their IDs, never reused, so a user enabled again keeps the sessions it opens meanwhile.
func (*Runtime) Reload ¶
Reload performs parse/default/validate/secret-resolution/assembly before atomically publishing the new App. Build failure preserves the old snapshot.
func (*Runtime) ReloadWith ¶ added in v0.1.11
ReloadWith publishes the App returned by build, with the same budget, transaction and drain handling as Reload.
func (*Runtime) RollbackSession ¶
RollbackSession rolls back transactions associated with a disconnected MCP session when the transport exposes a stable non-empty session ID.
func (*Runtime) SnapshotReady ¶ added in v0.1.6
SnapshotReady reports whether a configuration snapshot is currently published and servable. It backs the /readyz/snapshot readiness probe.
func (*Runtime) Stale ¶ added in v0.1.11
func (r *Runtime) Stale() (StaleState, bool)
Stale returns the unapplied published revision, if any.
func (*Runtime) UserByName ¶ added in v0.1.11
func (r *Runtime) UserByName(name string) (UserIdentity, bool)
UserByName resolves an enabled user against the current snapshot; a held user is not found.
func (*Runtime) UserByTokenHash ¶ added in v0.1.11
func (r *Runtime) UserByTokenHash(hash string) (UserIdentity, bool)
UserByTokenHash resolves a tokenHash against the current snapshot; a held user is not found.
func (*Runtime) Watch ¶
func (r *Runtime) Watch(ctx context.Context, path string, interval time.Duration, onError func(error)) error
Watch polls path for content changes and reloads it. Reload errors are reported through onError and do not stop the watcher or replace the old App.
func (*Runtime) WatchStore ¶ added in v0.1.11
func (r *Runtime) WatchStore( ctx context.Context, store revision.Store, current int64, interval time.Duration, build func(revision.Revision) (*App, error), onError func(error), ) error
WatchStore polls store for a newly published revision and reloads it with build. current is the revision the runtime already serves. Failures keep the current snapshot (fail-static) and are recorded in Stale; a later successful reload clears it. The users a revision that loads but fails to apply changes are held meanwhile (see holdChanged).
type SecretResolver ¶
SecretResolver resolves ${...} placeholders in a string (e.g. a DSN). EnvFileResolver is the built-in implementation; custom implementations can back this by Vault, AWS Secrets Manager, GCP Secret Manager, etc., without coupling core to any specific backend.
type Shared ¶ added in v0.1.12
type Shared struct {
// contains filtered or unexported fields
}
Shared holds what the Apps of one process share across reloads, so the old and the new configuration, serving side by side while the old one drains, act as one process: the read cache, which a write through either invalidates; the execution bus and the IO quota on it, which bound both together; and the database connections, reused while their settings stay the same, each with its own health (circuit breaker and adaptive limit: one database failing or slowing down is held back on its own).
func NewShared ¶ added in v0.1.12
func NewShared() *Shared
NewShared returns empty shared services on an execution bus of their own.
func NewSharedOn ¶ added in v0.1.13
NewSharedOn returns empty shared services on b, the process's execution bus: the IO quota is b's IO semaphore, and publishing an App sets b's limits. The caller closes b after the Runtime.
func (*Shared) Assemble ¶ added in v0.1.12
Assemble opens (or reuses) the connections of cfg and wires an App on the shared services, resolving secrets like Assemble.
type StaleState ¶ added in v0.1.11
type StaleState struct {
RevisionID int64
Err string
// RestartRequired reports that the revision only applies after a restart.
RestartRequired bool
}
StaleState describes a published store revision the runtime has not applied, either because building it failed or because it needs a restart.