Documentation
¶
Overview ¶
Package controlplane is the neutral seam between sandboxd and an optional managed control plane. It declares small capability interfaces — caller-token validation, usage-sample reporting, and standing-driven fleet enforcement — and ships a no-op implementation that is the default in the open-source build.
The open-source daemon links only against this package. A managed build wires a concrete Provider (backed by a private client) at startup; nothing about that client's behavior lives here. With the no-op Provider, sandboxd behaves byte-for-byte as it did before this seam existed: user tokens are rejected (leaving only the operator PAT path), usage reporting is discarded, and the enforcement loop does nothing.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrAdmissionDenied = errors.New("controlplane: admission denied")
ErrAdmissionDenied is returned by Admitter.Admit when the caller's account is not permitted to create a sandbox right now (e.g. its access has been suspended or terminated by the control plane). It is a definite "no": the API edge maps it to 403. Distinct from ErrAdmissionUnavailable, which is a retryable "ask again later".
ErrAdmissionUnavailable is returned by Admitter.Admit when the control plane cannot vouch for the caller right now (standing data is not yet known and the contract's grace window has elapsed). It is retryable; the API edge maps it to 503 with a Retry-After hint.
var ErrTokenRejected = errors.New("controlplane: token rejected")
ErrTokenRejected is returned by Validator.Validate for any token the control plane declines (or for every token under the no-op Provider). The API edge maps it to 401.
Functions ¶
Types ¶
type Access ¶
Access is the authenticated caller context attached by the API auth middleware and read by the service layer to enforce owner scoping. Operator is true for the PAT path (operator/admin: bypasses scoping, sees the whole fleet); for a validated user token Operator is false and Identity.OwnerRef is the tenant the request is scoped to.
Background loops and internal calls run with no Access in context. The service layer treats "no Access present" as unscoped (fleet-wide) so those paths are never accidentally constrained — only an explicit non-operator Access narrows visibility.
func AccessFromContext ¶
AccessFromContext returns the Access attached to ctx, if any. ok is false for background loops and internal calls that never went through the auth edge — callers must treat that as unscoped (operator-equivalent) access.
type Admitter ¶
Admitter is the create-admission gate. The daemon consults it before reserving capacity for a new sandbox: a non-nil error refuses the create (e.g. the owner's account is suspended, or fleet standing is unknown beyond the contract grace). The no-op Admitter admits everything, so the open-source build never gates creates.
type Enforcement ¶
Enforcement is the background standing loop. Start is called once at daemon boot by the managed build; the no-op Start returns immediately.
type FleetController ¶
type FleetController interface {
StopByOwner(ctx context.Context, ownerRef string) error
RestoreByOwner(ctx context.Context, ownerRef string) error
DeleteByOwner(ctx context.Context, ownerRef string) error
FireWebhook(ctx context.Context, ownerRef, level string) error
}
FleetController is implemented by the service layer so the managed build can converge the fleet to a standing directive without the control-plane client knowing any orchestration internals. Every method must be idempotent.
type Identity ¶
Identity is the account a caller token resolves to. OwnerRef is the stable account key stamped onto sandboxes and usage samples; ExternalID is informational only.
type Provider ¶
type Provider struct {
Validator Validator
Reporter Reporter
Admitter Admitter
EnforcementFor func(FleetController) Enforcement
}
Provider bundles the capabilities a build supplies to the daemon. The open-source build uses Noop(); a managed build constructs one backed by the private client. Passed explicitly into the API server and background wiring — there is no global registry, so the dependency stays visible and testable.
EnforcementFor is a factory rather than a ready Enforcement because the FleetController it drives is the service layer, which only exists partway through daemon boot. The daemon calls EnforcementFor(svc).Start(ctx) once the service is constructed. A nil factory (or one returning the no-op) means no enforcement loop runs.
func Noop ¶
func Noop() Provider
Noop returns a Provider whose capabilities do nothing: every token is rejected, every report is dropped, every create is admitted, and enforcement never runs. This is the open-source default and the safe fallback whenever the feature is disabled.
func (Provider) WithDefaults ¶
WithDefaults fills any nil capability on p with its no-op equivalent, so a managed build can supply only the pieces it has wired without risking a nil dereference on the others.
type Reporter ¶
Reporter ships usage samples toward the managed ingest. Implementations must be non-blocking enough to sit on the daemon's background loops without stalling them.
type Sample ¶
type Sample struct {
EventID string
OwnerRef string
SandboxID string
Kind string
Value float64
Unit string
WindowStart time.Time
WindowEnd time.Time
}
Sample is one neutral usage record. It carries units, never money — the managed side is solely responsible for any interpretation of these values.