dca8c3b643f3c21a41107ac217b4395b34083762
A pile of correctness bugs that all stopped real Tailscale peers from being able to send WireGuard packets back to us. Found while building out the e2e test against the docker-compose stack. 1. WireGuard static key was wrong (lifecycle.rs) We were initializing the WgTunnel with `keys.wg_private`, a separate x25519 key from the one Tailscale advertises in netmaps. Peers know us by `node_public` and compute mac1 against it; signing handshakes with a different private key meant every init we sent was silently dropped. Use `keys.node_private` instead — node_key IS the WG static key in Tailscale. 2. DERP relay couldn't route packets to us (derp/client.rs) Our DerpClient was sealing the ClientInfo frame with a fresh ephemeral NaCl keypair and putting the ephemeral public in the frame prefix. Tailscale's protocol expects the *long-term* node public key in the prefix — that's how the relay knows where to forward packets addressed to our node_key. With the ephemeral key, the relay accepted the connection but never delivered our peers' responses. Now seal with the long-term node key. 3. Headscale never persisted our DiscoKey (proto/types.rs, control/*) The streaming /machine/map handler in Headscale ≥ capVer 68 doesn't update DiscoKey on the node record — only the "Lite endpoint update" path does, gated on Stream:false + OmitPeers:true + ReadOnly:false. Without DiscoKey our nodes appeared in `headscale nodes list` with `discokey:000…` and never propagated into peer netmaps. Add the DiscoKey field to RegisterRequest, add OmitPeers/ReadOnly fields to MapRequest, and call a new `lite_update` between register and the streaming map. Also add `post_json_no_response` for endpoints that reply with an empty body. 4. EncapAction is now a struct instead of an enum (wg/tunnel.rs) Routing was forced to either UDP or DERP. With a peer whose advertised UDP endpoint is on an unreachable RFC1918 network (e.g. docker bridge IPs), we'd send via UDP, get nothing, and never fall back. Send over every available transport — receivers dedupe via the WireGuard replay window — and let dispatch_encap forward each populated arm to its respective channel. 5. Drop the dead PacketRouter (wg/router.rs) Skeleton from an earlier design that never got wired up; it's been accumulating dead-code warnings.
Sunbeam CLI
Sunbeam CLI is a local development stack manager for Kubernetes-based applications. It simplifies cluster management, service operations, secret handling, and manifest deployment.
Quick Start
# Install from source
cargo install --path sunbeam
# Start your local cluster
sunbeam up
# Apply manifests
sunbeam apply
# Check status
sunbeam status
Features
- Cluster Management: Bring up local Kubernetes clusters with cert-manager, Linkerd, TLS
- Service Operations: Status, logs, restart, health checks across namespaces
- Secret Management: OpenBao KV seeding, DB engine config, VSO verification
- Manifest Management: Kustomize + Helm builds with domain/email substitution
- User Management: Kratos identity CRUD, onboarding/offboarding with mailbox and project provisioning
- Image Building: Buildkit-based builds with registry push and rollout deploy
- Project Management: Unified ticket management across Planka and Gitea
- Self-Update: Binary update from the latest mainline commit
- Tool Bundling: kustomize and helm binaries embedded at compile time
Installation
Prerequisites
- Rust (2024 edition)
- Docker
- Lima (for local VM management)
- A running Kubernetes cluster (kubectl context
sunbeamfor local dev)
Install from Source
git clone https://src.sunbeam.pt/studio/cli.git
cd cli
cargo install --path sunbeam
sunbeam --help
Self-Update
Once installed, sunbeam can update itself:
sunbeam update
Workspace Layout
cli/
Cargo.toml # [workspace] — sunbeam-sdk + sunbeam
sunbeam-sdk/ # Library crate — all logic
src/
lib.rs
error.rs, config.rs, output.rs, constants.rs
kube/ # client, apply, exec, secrets, kustomize_build, tools
openbao/ # BaoClient HTTP API
auth/ # OAuth2 PKCE, token cache
services/ # status, logs, get, restart
images/ # build, mirror, per-service builders
secrets/ # seed, verify, KV seeding, DB engine
users/ # identity CRUD, provisioning (mailbox, projects, email)
checks/ # functional health probes, S3 auth
pm/ # Planka + Gitea ticket management
cluster/ # cert-manager, Linkerd, TLS
manifests/ # kustomize apply, namespace filtering
gitea/ # bootstrap (orgs, repos, OIDC)
update/ # self-update, version
sunbeam/ # Binary crate — thin CLI wrapper
src/
main.rs # tokio, rustls, tracing init
cli.rs # Clap structs + dispatch
Usage
Basic Commands
sunbeam up # Full cluster bring-up
sunbeam status # Pod health across all namespaces
sunbeam status ory # Scoped to namespace
sunbeam apply # Build + apply all manifests
sunbeam apply lasuite # Apply single namespace
sunbeam logs ory/kratos # Stream logs
sunbeam logs ory/kratos -f # Follow mode
sunbeam restart # Rolling restart all services
sunbeam restart ory/kratos # Restart specific deployment
Configuration
sunbeam config set --domain sunbeam.pt --host user@server.example.com
sunbeam config get
sunbeam config use-context production
Building and Deploying
sunbeam build proxy # Build image
sunbeam build proxy --push # Build + push to registry
sunbeam build proxy --deploy # Build + push + apply + restart
sunbeam build proxy --no-cache # Disable buildkit cache
sunbeam mirror # Mirror amd64-only images
User Management
sunbeam user list
sunbeam user create user@example.com --name "User Name"
sunbeam user set-password user@example.com
sunbeam user onboard new@example.com --name "New User" --department Engineering
sunbeam user offboard departed@example.com
sunbeam user recover user@example.com
Secret Management
sunbeam seed # Generate + store all credentials in OpenBao
sunbeam verify # E2E VSO + OpenBao integration test
Project Management
sunbeam pm list # List tickets (Planka + Gitea)
sunbeam pm show p:42 # Show Planka card
sunbeam pm show g:studio/cli#7 # Show Gitea issue
sunbeam pm create "Title" --source gitea --target studio/cli
sunbeam pm assign p:42 user@example.com
sunbeam pm close g:studio/cli#7
Health Checks
sunbeam check # Run all functional probes
sunbeam check devtools # Scoped to namespace
Passthrough
sunbeam k8s get pods -A # kubectl passthrough
sunbeam bao status # bao CLI inside OpenBao pod
Production
sunbeam config set --domain sunbeam.pt --host user@62.210.145.138
sunbeam config use-context production
sunbeam apply # Opens SSH tunnel automatically
Running Tests
cargo nextest run --workspace # 232 tests
cargo test --workspace # Alternative
Python CLI (Legacy)
The original Python implementation is in the sunbeam/ package and remains functional:
pip install -e .
python -m sunbeam --help
License
MIT — see LICENSE.
Description
The Sunbeam Studios CLI. It contains tools for Kubernetes, Docker, Lima VM, Cargo, and many other ecosystems. It is designed to be a general-purpose tool for small indie game studios.
https://sunbeam.pt
Releases
4
Languages
Rust
99.9%
Shell
0.1%