VNET layout
Jail sandboxes attach to coppicenet0 with a per-sandbox
epair pair. IPv4 lives under 10.78.0.0/24; IPv6 uses the
fd77::/64 ULA. The gateway records both addresses on the
sandbox detail response.
Each sandbox gets a source-IP-scoped pf anchor. Policy updates do not reload the root ruleset; they mutate the sandbox anchor.
Air-gap
Air-gap mode installs a default-deny fragment for outbound traffic while keeping gateway/DNS control-plane paths reachable. New connections fail after air-gap is enabled. Existing pf states need to be killed when the operator wants an immediate cut; the gateway does that on policy flips.
API keys
By default, a tunnelled local deployment has no API auth. Set
COPPICE_API_KEYS or COPPICE_API_KEYS_FILE to
require credentials on the API and envd surfaces:
export COPPICE_API_KEYS='team-a:sk-team-a:admin|exec'
Send X-API-Key: sk-team-a or
Authorization: Bearer sk-team-a. Use
/auth/whoami to confirm which tenant/scopes the gateway
matched. Scopes are coarse on purpose: read can inspect
state, exec can operate sandbox/envd surfaces, and
admin can mutate templates, pools, secrets, schedules,
volumes, webhooks, limits, and network policy.
Authenticated creates are labelled with reserved
coppice_tenant_id metadata. To cap concurrent
running/paused sandboxes per tenant, set:
export COPPICE_TENANT_MAX_SANDBOXES=8
export COPPICE_TENANT_SANDBOX_LIMITS='team-a=2,team-b=10,*=4'
The specific map is optional; * is the fallback when present.
Quota checks run before a backend clone starts, so a tenant at its cap
gets a fast 403 instead of consuming pool capacity.
Mutating requests, auth failures, scope denials, and HTTP errors are kept in the in-memory audit ring:
curl /audit/events?limit=20
Set COPPICE_AUDIT_LOG=/var/log/coppice-audit.jsonl for a
durable JSONL copy. The admin dashboard renders the same feed.
Secrets
Use the secrets store for env-var injection and the credential proxy for
host-side request brokering. The first writes selected values into
/run/coppice/secrets.env. The second keeps the real upstream
credential on the host and gives the sandbox only a proxy token.
VNET wedge diagnostics
If a FreeBSD VNET attach wedges in the kernel, the gateway now captures a
bundle under /var/log/coppice-diagnostics. The admin panel
and API expose live status through:
curl /diagnostics/vnet
curl /diagnostics/vnet/latest
A reboot clears the D-state process; the retained bundle explains what happened before the reboot.