Documentation
¶
Overview ¶
Package model contains Boxy's core domain data models.
Documentation pillars for this package: 1) What the thing is (definition) 2) Why it exists (the problem it solves) 3) When to use it (where it belongs in the system) 4) How to use it correctly (invariants and intended mutation points)
Design intent:
- Keep these types "data-first": plain structs and small enums.
- Prefer explicit domain types (PoolName, SandboxID, ResourceType) over raw strings when it prevents mixing up identifiers.
- Keep behavior and side effects out of the model layer. Orchestrators, pool controllers, providers, agents, and storage adapters should depend on this package, not the other way around.
---
Provider ¶
What:
- A provider instance is an external system Boxy can provision resources on. Examples: a specific Docker engine, or a specific Hyper-V host.
Why:
- Boxy must be able to route lifecycle operations (create/inspect/destroy) to the correct external system over time.
When to use: - Use ProviderRef on domain objects that need routing ("which provider owns this?"). - Use the runtime config layer (providersdk.Instance) for provider connection/config.
How to use correctly:
- ProviderRef.Name must match a configured provider instance name.
- Avoid using the word "provider" to mean both the code and the external system. In this repo:
- provider instance = external configured target (providersdk.Instance)
- ProviderRef = reference from core domain objects
- driver/adapter = code that talks to a provider type
---
Pool ¶
What: - Pool is a user-facing container of Resources.
Why:
- Pools give Boxy a place to keep "ready-to-allocate" inventory, which is the foundation of preheating (min_ready) and fast sandbox allocation.
When to use:
- Use Pool when you want the primary CLI/config noun to be something humans can name ("dev-docker", "win11-vms") and reason about as a bucket.
- Use Pool inventory when you need to allocate a Resource into a Sandbox or decide whether to provision more inventory.
How to use correctly:
- Pools should be homogeneous: all Resources in a Pool inventory should share the same ResourceType. (See ResourceCollection.)
- Resources are single-use: once a Resource leaves a Pool for a Sandbox, it is not returned to any Pool.
- The model layer does not replenish pools. A controller/reconciler should enforce preheat policy and perform lifecycle transitions.
---
Resource ¶
What: - Resource is a tracked, provisioned instance (VM/container/share/etc).
Why:
- Boxy needs a stable, backend-agnostic representation of "a thing that exists" so it can allocate it, track its lifecycle, and eventually clean it up.
When to use:
- Use Resource for anything that can be allocated to a Sandbox and has a lifecycle state.
How to use correctly:
- Resource.Type is intrinsic: a resource "is a VM" regardless of which pool or sandbox currently references it.
- If you want homogeneous containers, enforce that at the container boundary (ResourceCollection.Add / Validate) rather than trying to infer a resource's kind from the container it happens to be in.
---
Sandbox ¶
What: - Sandbox is a user-facing environment over 1..N resources, treated as "one thing".
Why:
- Users want one handle they can name and destroy even when the environment contains multiple resources (VM + DB + share).
- A sandbox can be as small as a single resource ("container sandbox") or as large as a full lab ("3 VM lab sandbox").
When to use: - Use Sandbox as the primary lifecycle object in the system.
How to use correctly:
- Sandboxes should reference concrete allocated items; avoid hiding "what was allocated from where" since that is required for cleanup and troubleshooting.
Index ¶
- Constants
- type APIKey
- type APIKeyID
- type APIKeyKind
- type APIKeyRole
- type AgentIdentity
- type AgentIdentityID
- type AgentRegistrationToken
- type AgentTokenID
- type Execution
- type ExecutionChunk
- type ExecutionID
- type ExecutionInputKind
- type ExecutionStatus
- type LocalAdminAccount
- type Pool
- type PoolConfigurationState
- type PoolDebugPolicy
- type PoolDrainState
- type PoolName
- type PoolPolicies
- type PreheatPolicy
- type Profile
- type ProfileRegistry
- type ProviderRef
- type RecyclePolicy
- type Resource
- type ResourceCollection
- type ResourceID
- type ResourceProfile
- type ResourceRequest
- type ResourceState
- type ResourceTemplate
- type ResourceType
- type RevokedAgentIdentity
- type Sandbox
- type SandboxID
- type SandboxPolicies
- type SandboxStatus
- type Session
- type SessionID
- type SessionKind
Constants ¶
const LocalAdminUsername = "admin"
LocalAdminUsername is the fixed username of the single bootstrapped local administrator account (see LocalAdminAccount). Not configurable in v1 — there is exactly one local-admin account per daemon.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIKey ¶ added in v0.1.34
type APIKey struct {
ID APIKeyID `json:"id" yaml:"id"`
Hash string `json:"hash" yaml:"hash"`
Role APIKeyRole `json:"role" yaml:"role"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
ExpiresAt *time.Time `json:"expires_at,omitempty" yaml:"expires_at,omitempty"`
RevokedAt *time.Time `json:"revoked_at,omitempty" yaml:"revoked_at,omitempty"`
// Kind distinguishes an admin-issued service key from a self-service
// personal key. Empty on every key created before this field existed
// and on every key the existing admin-only POST /api/v1/api-keys
// endpoint creates -- see EffectiveKind.
Kind APIKeyKind `json:"kind,omitempty" yaml:"kind,omitempty"`
// Subject identifies the human a personal key was minted for (an
// "oidc:<sub>" identity, see auth.SessionPrincipal). Empty for
// service keys, which have no such identity to record.
Subject string `json:"subject,omitempty" yaml:"subject,omitempty"`
}
APIKey is the persisted metadata for an operator credential. The raw key is deliberately never part of this model; Hash is the only credential material stored by the daemon.
func (APIKey) EffectiveKind ¶ added in v0.1.53
func (k APIKey) EffectiveKind() APIKeyKind
EffectiveKind returns k.Kind, defaulting to APIKeyKindService for a pre-existing record that predates this field.
type APIKeyID ¶ added in v0.1.34
type APIKeyID string
APIKeyID identifies an operator API key record.
type APIKeyKind ¶ added in v0.1.53
type APIKeyKind string
APIKeyKind distinguishes an admin-issued, long-lived service credential from a self-service, short-lived personal one minted via OIDC login. An empty Kind on an existing persisted record means "service" -- see APIKey.EffectiveKind.
const ( APIKeyKindService APIKeyKind = "service" APIKeyKindPersonal APIKeyKind = "personal" )
type APIKeyRole ¶ added in v0.1.34
type APIKeyRole string
APIKeyRole controls the operations available to an authenticated API key.
const ( APIKeyRoleUser APIKeyRole = "user" APIKeyRoleAuditor APIKeyRole = "auditor" APIKeyRoleAdmin APIKeyRole = "admin" )
func (APIKeyRole) Valid ¶ added in v0.1.34
func (r APIKeyRole) Valid() bool
Valid reports whether the role is one of Boxy's supported API-key roles.
type AgentIdentity ¶
type AgentIdentity struct {
AgentID string `json:"agent_id" yaml:"agent_id"`
CertSerial string `json:"cert_serial" yaml:"cert_serial"`
IssuedAt time.Time `json:"issued_at" yaml:"issued_at"`
}
AgentIdentity records which client certificate serial is currently associated with a registered agent, so an operator can revoke an agent by ID (`boxy agent revoke <id>`) even while it's disconnected — without this, the server would only learn an agent's cert serial while it has a live connection open.
type AgentIdentityID ¶
type AgentIdentityID string
AgentIdentityID identifies a revoked-agent-identity record.
type AgentRegistrationToken ¶
type AgentRegistrationToken struct {
ID AgentTokenID `json:"id" yaml:"id"`
TokenHash string `json:"token_hash" yaml:"token_hash"`
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
ExpiresAt time.Time `json:"expires_at" yaml:"expires_at"`
UsedAt *time.Time `json:"used_at,omitempty" yaml:"used_at,omitempty"`
Label string `json:"label,omitempty" yaml:"label,omitempty"`
}
AgentRegistrationToken is a single-use, short-lived bootstrap credential minted by an operator (`boxy agent token create`) and consumed exactly once by `boxy agent serve --token ...` during initial registration. The raw token is never persisted — only its hash, so a store dump does not itself let someone impersonate an agent.
func (AgentRegistrationToken) Expired ¶
func (t AgentRegistrationToken) Expired(now time.Time) bool
Expired reports whether this token's expiry has passed as of now.
func (AgentRegistrationToken) Used ¶
func (t AgentRegistrationToken) Used() bool
Used reports whether this token has already been redeemed.
type Execution ¶ added in v0.1.60
type Execution struct {
ID ExecutionID `json:"id"`
SandboxID SandboxID `json:"sandbox_id"`
ResourceID ResourceID `json:"resource_id"`
ActorID string `json:"actor_id,omitempty"`
Status ExecutionStatus `json:"status"`
InputKind ExecutionInputKind `json:"input_kind"`
RequestFingerprint string `json:"request_fingerprint"`
CreatedAt time.Time `json:"created_at"`
StartedAt *time.Time `json:"started_at,omitempty"`
FinishedAt *time.Time `json:"finished_at,omitempty"`
DeadlineAt time.Time `json:"deadline_at"`
ExitCode *int `json:"exit_code,omitempty"`
Error string `json:"error,omitempty"`
Truncated bool `json:"truncated,omitempty"`
Chunks []ExecutionChunk `json:"chunks,omitempty"`
}
Execution is the durable, safe representation of a sandbox command. Deliberately absent are command arguments, script content, environment values, and credentials. The in-process worker retains those only until the provider call finishes.
type ExecutionChunk ¶ added in v0.1.60
type ExecutionChunk struct {
Cursor uint64 `json:"cursor"`
Stream string `json:"stream"`
Data []byte `json:"data"`
Dropped bool `json:"dropped,omitempty"`
}
ExecutionChunk is one immutable, cursor-addressable output chunk. Cursor values are assigned by the execution service and are not byte offsets; this guarantees reconnects only resume at chunk boundaries.
type ExecutionID ¶ added in v0.1.60
type ExecutionID string
ExecutionID identifies one accepted sandbox execution.
type ExecutionInputKind ¶ added in v0.1.60
type ExecutionInputKind string
ExecutionInputKind describes the source of an execution request without storing the request's sensitive or potentially large content.
const ( ExecutionInputCommand ExecutionInputKind = "command" ExecutionInputCommandText ExecutionInputKind = "command_text" ExecutionInputScript ExecutionInputKind = "script" ExecutionInputStdin ExecutionInputKind = "stdin" )
type ExecutionStatus ¶ added in v0.1.60
type ExecutionStatus string
ExecutionStatus is the control-plane lifecycle of an execution.
const ( ExecutionStatusPending ExecutionStatus = "pending" ExecutionStatusRunning ExecutionStatus = "running" ExecutionStatusSucceeded ExecutionStatus = "succeeded" ExecutionStatusFailed ExecutionStatus = "failed" ExecutionStatusCancelled ExecutionStatus = "cancelled" ExecutionStatusInterrupted ExecutionStatus = "interrupted" )
func (ExecutionStatus) IsTerminal ¶ added in v0.1.60
func (s ExecutionStatus) IsTerminal() bool
IsTerminal reports whether an execution will receive no more output.
type LocalAdminAccount ¶ added in v0.1.53
type LocalAdminAccount struct {
Username string `json:"username" yaml:"username"`
PasswordHash string `json:"password_hash" yaml:"password_hash"`
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
}
LocalAdminAccount is the daemon's single bootstrapped local administrator account, used to log into the web UI (SessionKindLocalAdmin) when no OIDC provider is configured, or as a break-glass login even when one is. Only PasswordHash is persisted; the raw bootstrap password is generated once, written to a restricted-permission file for one-time CLI retrieval, and never stored here — the same "hash persisted, raw value shown once" discipline as APIKey/api-key bootstrap.
type Pool ¶
type Pool struct {
Name PoolName `json:"name" yaml:"name"`
// Template is the reusable desired resource shape used by this pool.
Template string `json:"template,omitempty" yaml:"template,omitempty"`
// Source and Packages are the resolved resource configuration carried by
// this pool. They are optional for legacy inline pools.
Source string `json:"source,omitempty" yaml:"source,omitempty"`
Packages []string `json:"packages,omitempty" yaml:"packages,omitempty"`
// Policies are pool-level behavioral controls (preheating, limits, etc).
Policies PoolPolicies `json:"policies,omitempty" yaml:"policies,omitempty"`
// Drain records desired drain state for unused pool inventory.
Drain PoolDrainState `json:"drain,omitempty" yaml:"drain,omitempty"`
// Configuration records where editable policy values came from. Static
// provider, template, store, and secret definitions remain local-file owned.
Configuration PoolConfigurationState `json:"configuration,omitempty" yaml:"configuration,omitempty"`
// Inventory is the current contents of the pool.
Inventory ResourceCollection `json:"inventory" yaml:"inventory"`
}
Pool is a user-facing container of resources.
func (Pool) EffectivelyDrained ¶
EffectivelyDrained reports whether the pool should currently be drained.
type PoolConfigurationState ¶ added in v0.1.65
type PoolConfigurationState struct {
Provenance string `json:"provenance,omitempty" yaml:"provenance,omitempty"`
LocalRevision string `json:"local_revision,omitempty" yaml:"local_revision,omitempty"`
Pending bool `json:"pending,omitempty" yaml:"pending,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty" yaml:"updated_at,omitempty"`
}
type PoolDebugPolicy ¶ added in v0.1.65
type PoolDebugPolicy struct {
// RetainFailedResources keeps a resource's VM and rotated guest
// credential running after admission (personalization or package
// application) fails, instead of the default power-down-and-remove
// teardown. A manual Retry against a retained resource re-admits it in
// place -- reusing the same VM and credential -- rather than destroying
// and recreating it from the template. Intended only for
// troubleshooting: a retained failed resource still consumes pool
// max_total capacity and can make the pool blocked exactly like any
// other failed resource.
RetainFailedResources bool `json:"retain_failed_resources,omitempty" yaml:"retain_failed_resources,omitempty"`
}
PoolDebugPolicy controls operator-opt-in troubleshooting behavior for a pool.
type PoolDrainState ¶
type PoolDrainState struct {
// ConfigDeclared is true when config declares the pool drained.
ConfigDeclared bool `json:"config_declared,omitempty" yaml:"config_declared,omitempty"`
// Operator is a persisted operator/debug override.
Operator bool `json:"operator,omitempty" yaml:"operator,omitempty"`
}
PoolDrainState records whether a pool should destroy and avoid creating unused ready inventory.
func (PoolDrainState) Effective ¶
func (d PoolDrainState) Effective() bool
Effective reports whether either config or operator state keeps the pool drained.
type PoolName ¶
type PoolName string
PoolName is the stable, user-facing handle for a pool (the thing typed in CLI/config).
type PoolPolicies ¶
type PoolPolicies struct {
// Preheat controls keeping resources ready ahead of time.
Preheat PreheatPolicy `json:"preheat,omitempty" yaml:"preheat,omitempty"`
// Recycle controls periodic replacement of unused pool inventory.
//
// This does NOT mean resources are returned to the pool after sandbox use.
// Resources remain single-use; recycle applies only to unused inventory.
Recycle RecyclePolicy `json:"recycle,omitempty" yaml:"recycle,omitempty"`
// Debug controls operator-opt-in troubleshooting behavior that trades
// safety/cost for investigability. Debug settings are local-config-owned
// only, like provider/template/store/secret definitions -- they are not
// exposed through the pool Save-and-Apply web/API surface.
Debug PoolDebugPolicy `json:"debug,omitempty" yaml:"debug,omitempty"`
}
PoolPolicies captures pool-level behavior without prescribing a specific CLI/API surface yet.
type PreheatPolicy ¶
type PreheatPolicy struct {
// MinReady is the number of ready units the pool should try to keep
// available in the background. It is a soft preheat target, not a
// second hard admission cap stacked on top of MaxTotal: failing to
// reach MinReady alone never rejects an allocation request (see
// #240) -- though a request can still fail for other reasons, e.g. a
// drained pool or a provisioning error. A live allocation call may
// still opportunistically top up toward MinReady in the background,
// so a failure in that best-effort top-up can itself surface as an
// error even when the request was already satisfiable -- see #249
// for that residual gap.
MinReady int `json:"min_ready,omitempty" yaml:"min_ready,omitempty"`
// MaxTotal is the maximum total units that may exist for the pool.
MaxTotal int `json:"max_total,omitempty" yaml:"max_total,omitempty"`
}
PreheatPolicy is the pool policy for keeping resources ready ahead of time.
type Profile ¶
type Profile struct {
Type ResourceType `json:"type" yaml:"type"`
Name ResourceProfile `json:"name" yaml:"name"`
}
Profile is a catalog entry defining an allowed (Type, Profile) pair.
This is intentionally minimal scaffolding. It exists to prevent "random strings at call sites" from becoming the de facto API.
type ProfileRegistry ¶
type ProfileRegistry struct {
// contains filtered or unexported fields
}
ProfileRegistry is a simple in-memory catalog of supported profiles.
It is Boxy-owned (not provider-owned): a profile name is a stable identifier that Boxy components can match on across pools and requests.
func NewProfileRegistry ¶
func NewProfileRegistry(profiles []Profile) (*ProfileRegistry, error)
func (*ProfileRegistry) Has ¶
func (r *ProfileRegistry) Has(t ResourceType, name ResourceProfile) bool
type ProviderRef ¶
type ProviderRef struct {
Name string `json:"name" yaml:"name"`
// AgentID is the specific agent instance (embedded or remote) that
// provisioned this resource, stamped once at creation time. It is
// deliberately distinct from Name (the provider type/instance): once
// more than one agent can advertise the same provider type, any
// lifecycle call on an existing resource (Destroy, Allocate) must
// route back to this exact agent rather than re-resolving by type,
// or it risks silently misrouting to a different agent that knows
// nothing about the resource. See docs/adr/0005-remote-agent-transport-and-registration.md.
AgentID string `json:"agent_id,omitempty" yaml:"agent_id,omitempty"`
}
ProviderRef identifies the provider instance that owns a resource.
This intentionally does not embed provider connection/config data. The canonical configured providers live in the runtime config (see providersdk.Instance).
For now, Name is the stable handle and must match a configured provider name. If/when renames become a real feature, introduce an immutable ID here.
type RecyclePolicy ¶
type RecyclePolicy struct {
// MaxAge is an optional upper bound on how long an unused resource may sit in
// a pool before it should be recycled (destroy + replace).
// Example values: "30m", "8h", "24h".
MaxAge string `json:"max_age,omitempty" yaml:"max_age,omitempty"`
}
RecyclePolicy describes when unused resources should be destroyed and replaced.
type Resource ¶
type Resource struct {
ID ResourceID `json:"id,omitempty" yaml:"id,omitempty"`
// Type is intrinsic to the resource, independent of which container holds it.
Type ResourceType `json:"type,omitempty" yaml:"type,omitempty"`
// Profile is a Boxy-defined variant identifier for this resource's Type.
// Example: vm "win-2022", container "ubuntu-2204".
Profile ResourceProfile `json:"profile,omitempty" yaml:"profile,omitempty"`
// OriginPool is the immutable pool that originally provisioned this resource.
// It is used for pool-level capacity accounting even after allocation removes
// the resource from ready inventory.
OriginPool PoolName `json:"origin_pool,omitempty" yaml:"origin_pool,omitempty"`
// CurrentPool is the pool that currently owns this resource for inventory
// and capacity accounting. Empty on legacy records means OriginPool.
CurrentPool PoolName `json:"current_pool,omitempty" yaml:"current_pool,omitempty"`
// PendingPool is set while a resource is being promoted into another pool.
// It is cleared when promotion succeeds or the resource is quarantined.
PendingPool PoolName `json:"pending_pool,omitempty" yaml:"pending_pool,omitempty"`
// Provider identifies the external system instance this resource belongs to.
Provider ProviderRef `json:"provider" yaml:"provider"`
State ResourceState `json:"state,omitempty" yaml:"state,omitempty"`
// Properties holds provider-specific data that Boxy core should not interpret.
Properties map[string]any `json:"properties,omitempty" yaml:"properties,omitempty"`
// AppliedPackages records successful resource-package applications. The
// package engine uses the immutable reference and canonical input digest for
// idempotency; this is not a guest drift detector.
AppliedPackages []resourcepack.AppliedPackage `json:"applied_packages,omitempty" yaml:"applied_packages,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty" yaml:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty" yaml:"updated_at,omitempty"`
}
Resource is a provisioned instance tracked by Boxy.
func (Resource) EffectivePool ¶ added in v0.1.54
EffectivePool returns the current inventory owner, preserving compatibility with resources persisted before current ownership was introduced.
type ResourceCollection ¶
type ResourceCollection struct {
// ExpectedType is a constraint: all Resources must have Resource.Type == ExpectedType.
ExpectedType ResourceType `json:"expected_type" yaml:"expected_type"`
// ExpectedProfile is a constraint: all Resources must have Resource.Profile == ExpectedProfile.
ExpectedProfile ResourceProfile `json:"expected_profile" yaml:"expected_profile"`
Resources []Resource `json:"resources,omitempty" yaml:"resources,omitempty"`
}
ResourceCollection is a homogeneous container of resources.
func (*ResourceCollection) Add ¶
func (c *ResourceCollection) Add(r Resource) error
Add appends r if it satisfies the collection invariant.
func (ResourceCollection) Validate ¶
func (c ResourceCollection) Validate() error
Validate checks that the collection is internally consistent.
type ResourceID ¶
type ResourceID string
ResourceID is a stable identifier for a resource tracked by Boxy.
type ResourceProfile ¶
type ResourceProfile string
ResourceProfile is a Boxy-defined variant identifier for a ResourceType.
Think of it as the "pooling key" beyond the coarse ResourceType: - VM: "win-2022", "ubuntu-2204", "ubuntu-2204-devbox" - Container: "ubuntu-2204", "ubuntu-2204-lamp" - Share: "default", "smb-basic"
Profiles are type-dependent by design; "win-2022" only makes sense for vm.
const ( // ResourceProfileDefault is the conventional "no special customization" profile. // // Using an explicit default keeps pools deterministic (no implicit meaning for ""). ResourceProfileDefault ResourceProfile = "default" )
type ResourceRequest ¶
type ResourceRequest struct {
Type ResourceType `json:"type" yaml:"type"`
Profile ResourceProfile `json:"profile" yaml:"profile"`
Count int `json:"count" yaml:"count"`
Packages []string `json:"packages,omitempty" yaml:"packages,omitempty"`
}
ResourceRequest expresses demand for one or more resources matching a (Type, Profile) key.
This is intentionally small scaffolding: - It is not a full "spec" or "configuration". - It exists to make pooling/matching deterministic beyond coarse ResourceType.
Examples:
- {Type: vm, Profile: "win-2022", Count: 3}
- {Type: container, Profile: "ubuntu-2204", Count: 1}
- {Type: share, Profile: "default", Count: 1}
func (ResourceRequest) Validate ¶
func (r ResourceRequest) Validate() error
type ResourceState ¶
type ResourceState string
ResourceState is the lifecycle state of a resource.
const ( ResourceStateUnknown ResourceState = "unknown" ResourceStateProvisioning ResourceState = "provisioning" ResourceStateReady ResourceState = "ready" ResourceStateAllocated ResourceState = "allocated" ResourceStateReleased ResourceState = "released" // ResourceStateRecycling marks a resource being torn down by pool-level // max-age recycling (see RecyclePolicy) specifically, distinct from // ResourceStateDestroying (drain and explicit sandbox-triggered destroy). // It exists purely for observability: without it, a resource mid-teardown // looks identical to a healthy one (via the REST API, CLI, or persisted // state) until it suddenly disappears, which is indistinguishable from a // stalled/hung backend. ResourceStateRecycling ResourceState = "recycling" ResourceStateDestroying ResourceState = "destroying" ResourceStatePromoting ResourceState = "promoting" ResourceStateDestroyed ResourceState = "destroyed" ResourceStateError ResourceState = "error" )
type ResourceTemplate ¶ added in v0.1.54
type ResourceTemplate struct {
Name string `json:"name" yaml:"name"`
Extends string `json:"extends,omitempty" yaml:"extends,omitempty"`
Type string `json:"type,omitempty" yaml:"type,omitempty"`
Provider string `json:"provider,omitempty" yaml:"provider,omitempty"`
Agent string `json:"agent,omitempty" yaml:"agent,omitempty"`
Source string `json:"source,omitempty" yaml:"source,omitempty"`
Config map[string]any `json:"config,omitempty" yaml:"config,omitempty"`
Packages []string `json:"packages,omitempty" yaml:"packages,omitempty"`
}
ResourceTemplate is a reusable desired shape for a resource. It is kept separate from Pool because a template describes what should be built while a Pool describes how much inventory to maintain.
type ResourceType ¶
type ResourceType string
ResourceType is the domain category of a resource (vm/container/share/etc).
const ( ResourceTypeUnknown ResourceType = "unknown" ResourceTypeVM ResourceType = "vm" ResourceTypeContainer ResourceType = "container" ResourceTypeNetwork ResourceType = "network" ResourceTypeDB ResourceType = "db" )
type RevokedAgentIdentity ¶
type RevokedAgentIdentity struct {
ID AgentIdentityID `json:"id" yaml:"id"`
AgentID string `json:"agent_id" yaml:"agent_id"`
CertSerial string `json:"cert_serial" yaml:"cert_serial"`
RevokedAt time.Time `json:"revoked_at" yaml:"revoked_at"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
}
RevokedAgentIdentity is a deny-list entry: once an agent's client certificate serial is revoked, the server must refuse new connections presenting that certificate, regardless of expiry, and tear down any live connection using it.
type Sandbox ¶
type Sandbox struct {
ID SandboxID `json:"id" yaml:"id"`
Name string `json:"name,omitempty" yaml:"name,omitempty"`
OwnerID string `json:"owner_id,omitempty" yaml:"owner_id,omitempty"`
// Policies are sandbox-level behavioral controls (security, retention, etc).
Policies SandboxPolicies `json:"policies,omitzero" yaml:"policies,omitempty"`
// Status is the async lifecycle state of the sandbox request.
Status SandboxStatus `json:"status,omitempty" yaml:"status,omitempty"`
// Requests are the desired resources for this sandbox.
Requests []ResourceRequest `json:"requests,omitempty" yaml:"requests,omitempty"`
// Error is a human-readable failure detail when Status=failed.
Error string `json:"error,omitempty" yaml:"error,omitempty"`
// Resources are the resources that make up this sandbox.
Resources []ResourceID `json:"resources,omitempty" yaml:"resources,omitempty"`
// ExpiresAt is the absolute time this sandbox should be automatically
// destroyed, computed from Policies.AutoDestroyAfter at creation time.
// Nil means no automatic expiry.
ExpiresAt *time.Time `json:"expires_at,omitempty" yaml:"expires_at,omitempty"`
}
Sandbox is a user-facing environment that contains 1..N resources.
This model is intentionally minimal. Orchestration state and richer composition semantics are layered on later.
type SandboxID ¶
type SandboxID string
SandboxID is a stable identifier for a sandbox (user-facing handle).
type SandboxPolicies ¶
type SandboxPolicies struct {
// AutoDestroyAfter is an optional retention setting (e.g. "30m", "8h").
// Empty means "no policy set here".
AutoDestroyAfter string `json:"auto_destroy_after,omitempty" yaml:"auto_destroy_after,omitempty"`
// SecurityProfile is an optional label for sandbox hardening posture.
// Examples: "default", "lab", "pentest", "vdi".
SecurityProfile string `json:"security_profile,omitempty" yaml:"security_profile,omitempty"`
}
SandboxPolicies captures sandbox-level behavior without prescribing a specific CLI/API surface yet.
type SandboxStatus ¶
type SandboxStatus string
SandboxStatus is the lifecycle state of a sandbox request.
const ( SandboxStatusPending SandboxStatus = "pending" SandboxStatusProvisioning SandboxStatus = "provisioning" SandboxStatusReady SandboxStatus = "ready" SandboxStatusDeleting SandboxStatus = "deleting" SandboxStatusFailed SandboxStatus = "failed" )
func (SandboxStatus) IsTransient ¶ added in v0.1.44
func (s SandboxStatus) IsTransient() bool
IsTransient reports whether the sandbox is actively changing state (pending/provisioning/deleting) rather than settled into a terminal state (ready/failed). This is the single source of truth for that distinction — consumers such as the web dashboard's "in progress" badge styling should call this instead of hardcoding the transient status list, so a future lifecycle status only needs to be classified here once.
type Session ¶ added in v0.1.53
type Session struct {
ID SessionID `json:"id" yaml:"id"`
Hash string `json:"hash" yaml:"hash"`
Kind SessionKind `json:"kind" yaml:"kind"`
// Subject identifies the principal within Kind: the local admin
// account's username for SessionKindLocalAdmin, or the OIDC subject
// claim for SessionKindOIDC.
Subject string `json:"subject" yaml:"subject"`
Role APIKeyRole `json:"role" yaml:"role"`
CreatedAt time.Time `json:"created_at" yaml:"created_at"`
ExpiresAt time.Time `json:"expires_at" yaml:"expires_at"`
}
Session is a server-side web-UI login session. This is a browser-only concept, separate from and unaffected by the CLI/API bearer-key model in APIKey: a session authenticates a human at the dashboard, not a programmatic REST caller. Only Hash is persisted; the raw cookie value is generated once at login (see internal/auth) and never stored, matching how APIKey stores a hash rather than the raw key.
type SessionID ¶ added in v0.1.53
type SessionID string
SessionID identifies a persisted web-UI login session record.
type SessionKind ¶ added in v0.1.53
type SessionKind string
SessionKind identifies how a session's principal was established.
const ( // SessionKindLocalAdmin is a session created by logging in with the // bootstrapped local admin account (see LocalAdminAccount). SessionKindLocalAdmin SessionKind = "local_admin" // SessionKindOIDC is a session created by a completed OIDC login. // Not produced anywhere yet; reserved for when OIDC support lands. SessionKindOIDC SessionKind = "oidc" )