npx skills add https://github.com/getcolors/agent-network-doks --skill package-agent-network-doks-redSKILL.md
NetBird Agent Network on DigitalOcean Kubernetes
A Red workflow that turns one colors.yml into a running Agent Network
demo on a managed Kubernetes cluster: OpenTofu for the DOKS cluster and the
container registry (created and profile-named, or adopted by name) plus two
Cloudflare records (the base name and its wildcard); kubectl for the gateway
(Traefik behind a TCP-mode DigitalOcean regional Load Balancer, the combined
netbird-server with its datastore on a CSI volume, the dashboard in
agent-network-only mode, the NetBird reverse proxy in private mode), a
launcher-side control-plane bootstrap, an in-cluster kaniko build of the
agent image, and the two-pod application: the NetBird client in
netstack/SOCKS5 mode — userspace WireGuard, no TUN, no capabilities — and
the isolated agent running headless Claude Code.
The demo's claim: the agent pod has no network egress but the SOCKS5
listener — default-deny NetworkPolicy with a single allow, in a
restricted Pod Security namespace, with no ServiceAccount token and no DNS
— and its only road to an LLM is the keyless agent-network endpoint over the
WireGuard tunnel, where every request carries the peer's identity, passes
the model allowlist and the budget caps, and is metered. Convergence proves
the claim from both sides: raw probes around the proxy AND CONNECT probes
through it (NetworkPolicy cannot constrain what a CONNECT names, so the
"only the overlay is dialable" property is probed on every converge, never
assumed) — and, before any secret enters the cluster, a throwaway canary
pod pair proves Cilium is actually enforcing NetworkPolicy on this cluster.
Verbs
./red build # render .colors/<profile>/ — no provider calls, no credentials
./red create --dry-run # walk the workflow, skip every side effect
./red create # converge for real
./red delete # guarded; needs a one-run override
./red status # cluster, certificate, endpoint, tunnel, usage
./red kubectl -- get pods -A # kubectl with this deployment's kubeconfig
Exit code 2 is validation or usage failure and lists every problem at once.
The launcher walks up from the working directory to find colors.yml.
Before you converge
- The hostname and its wildcard must be free in the Cloudflare zone. The DNS stage creates both and never adopts a foreign record.
- Five credentials must be set in
.envrc.private; seereferences/configuration.md. Never exportCOLORS_PAR_PROFILE. - A deliberately fake
COLORS_PAR_ANTHROPIC_API_KEYis a supported mode: the acceptance gates then expect Anthropic's own 401 relayed through the proxy, which proves everything NetBird owns with nothing billable. A real key upgrades the same gates to require completions; swapping is an.envrc.privateedit and a re-converge. doks-versionis checked against DOKS's live supported list before anything is created; the error names the slugs on offer.- Registries are account-scoped and tier-limited. With no
digitalocean-registry-name, the package creates a profile-named registry — behind a preflight that fails loudly when the account's subscription has no free registry slot. Recovery is adopting the existing registry: setdigitalocean-registry-nameAND removedigitalocean-registry-tier(the tier key is create-mode-only). Either way only the profile-named repository inside the registry is deployment-owned.
What create does
infrastructure (DOKS + registry + credentials; cluster subnets read back, never supplied) → deploy (Cilium canary, namespaces, create-once secrets, kaniko build under an ephemeral push credential, gateway, proxy token, LB) → dns (base + wildcard, unproxied) → certificate (lego DNS-01, both SANs, launcher-side; then the edge and proxy readiness deliberately deferred until the Secret exists) → bootstrap (headless: setup-PAT exchange, endpoint minted by the settings POST, provider claiming two models, guardrail allowing one, per-group caps on the agents peer group, account-wide ceiling) → agent (the two pods; one-off setup key streamed over exec stdin into memory-backed storage, revoked after enrollment) → acceptance (isolation outer and inner, tunnel, keyless call, both denial classes, external pre-identity 403, LB firewall verified through the DigitalOcean API, attribution, limits read back, credential hygiene, and — once — a bounded disruption suite including a node drain).
Recovery
Disposable by design: no backups. Recovery is a guarded delete
(COLORS_PAR_COMPUTE_PREVENT_DESTROY=false for one run) followed by
create, which regenerates the endpoint hostname and every peer identity;
anything that memorized the old endpoint breaks. The dashboard admin
password: ./red kubectl -- -n agent-network-gateway get secret an-admin-password -o jsonpath='{.data.value}' | base64 -d.