No description
  • Rust 82.6%
  • TypeScript 15.4%
  • CSS 0.6%
  • Shell 0.6%
  • PLpgSQL 0.6%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Luxxy 1d35a3e7cd
Some checks failed
Backend CI / Format, lint and test (push) Failing after 2s
Backend CI / Migrations apply to an empty database (push) Failing after 1s
Security / Advisories, licences and sources (push) Failing after 2s
Security / No secrets or placeholder credentials committed (push) Failing after 2s
Security / Frontend dependency audit (push) Failing after 32s
Refresh a node's inventory automatically on every connect
The customer image catalogue lives only in memory (services::live_inventory)
and forgets everything on a panel restart; nothing previously asked a
freshly (re)connected agent to report in, so a customer's "Operating
system" list stayed empty after any panel or agent restart until an
operator happened to click "Refresh" or pull a new image. Confirmed live:
a rebuilt agent reconnected fine, but the wizard's OS and the admin
Images page both showed nothing until manually refreshed.

Dispatches a NodeRefreshInventory operation right after every successful
handshake, same as the existing manual admin button and the automatic
post-pull refresh - all three now share one
services::operations::dispatch_inventory_refresh helper instead of each
building an OperationRequest by hand.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 03:01:38 +01:00
.github/workflows Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
agent Fix RefreshInventory always failing with CommandNotSupported 2026-08-02 23:35:21 +01:00
backend Refresh a node's inventory automatically on every connect 2026-08-03 03:01:38 +01:00
crates Allow real Linux interface names as a macvlan pool's parent interface 2026-08-03 02:51:18 +01:00
deploy Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
docs Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
frontend Fix image pulls never actually running past the first attempt 2026-08-03 02:39:06 +01:00
migrations dagon 2026-08-02 23:03:40 +01:00
scripts Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
.editorconfig Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
.env.example Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
.gitattributes Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
.gitignore Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
Cargo.lock Phase 4 frontend: create-instance wizard, console, metric charts, and six real bugs found by actually running the system 2026-08-02 13:14:09 +01:00
Cargo.toml Phase 4 frontend: create-instance wizard, console, metric charts, and six real bugs found by actually running the system 2026-08-02 13:14:09 +01:00
clippy.toml Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
deny.toml Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
full2.svg Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
package.json Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
pnpm-lock.yaml Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
pnpm-workspace.yaml Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
README.md Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
rust-toolchain.toml Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00
rustfmt.toml Phase 1: foundation for the Bee.host Cloud Control Panel 2026-08-01 17:45:11 +01:00

Bee.host Cloud Control Panel

A multi-node Incus management platform: a Rust control plane, a Rust node agent, and a React operator/customer interface.

Status: Phase 1 of 6. The foundation is complete and every gate passes. Real Incus inventory, power operations and provisioning land in Phases 2–4. See Phase status for exactly what works today.


What this is

Three components:

Component Binary Runs on Responsibility
Control plane bee-panel Your infrastructure Identity, ownership, permissions, desired state, operations, audit
Node agent incus-agent Every Incus host Talks to the local runtime, reports observed state, executes commands
Web interface — Browser Operator app at /admin, customer app at /
Browser ──HTTPS/WSS──▶ bee-panel ──WSS (agent dials out)──▶ incus-agent ──unix socket──▶ Incus
                           │
                           ▼
                       PostgreSQL

Design commitments

These shaped most of the code, and are worth stating plainly:

  • The panel never touches a node directly. No SSH, no remote Incus API, no mounted sockets. Agents dial out to the panel, so nodes need no inbound port and work behind NAT.
  • The panel does not assume a command succeeded. Every long-running action becomes a durable operations row before a node is contacted, and observed state is reconciled against desired state rather than presumed to match.
  • There is no remote shell. The agent's command set is a closed Rust enum. Adding a variant that runs arbitrary host commands would be a deliberate, reviewable change — and should not happen.
  • Customers never see infrastructure. Customer and operator DTOs are separate types, so exposing a node id to a customer requires adding a field to a customer struct. A test walks every customer payload looking for infrastructure vocabulary.
  • Tenancy is a property of queries, not of handlers. Customer reads join through project_members. There is no "fetch globally, then filter" path to forget a check in.

Quick start

Prerequisites

  • Rust 1.95 (pinned by rust-toolchain.toml)
  • Node 22 and pnpm 9+
  • Docker with Compose v2, or a local PostgreSQL 15+
  • An Incus host — only needed from Phase 2 onward

Run everything

git clone <repository-url> bee-host
cd bee-host
pnpm install
./scripts/dev.sh

That starts PostgreSQL, the control plane and the frontend dev server. The panel applies its own migrations and seeds roles and permissions on first boot.

Run the pieces separately

# PostgreSQL only
docker compose -f deploy/docker-compose.dev.yml up postgres

# Control plane
cp deploy/examples/backend.env.example .env    # then edit it
cargo run -p bee-panel

# Frontend
pnpm --filter @bee-host/frontend dev

# Node agent — on an actual Incus host, not in a container
cargo run -p incus-agent -- --config ./agent-dev.toml

docs/development.md covers the development administrator, the mock-agent path, and what to do without an Incus host.


Repository layout

backend/          bee-panel: Axum control plane
  src/api/          HTTP and websocket handlers — parse, authorise, delegate
  src/services/     Orchestration; owns multi-step workflows
  src/repositories/ Every SQL statement in the backend
  src/domain/       Types and invariants, storage- and transport-independent
  src/auth/         Sessions, permissions, the Actor every handler receives

agent/            incus-agent: one per Incus host
  src/connection/   Handshake, connection loop, reconnect backoff
  src/collectors/   Host metrics from /proc
  src/state/        The command journal that makes reconnects safe

crates/
  core/             Typed ids, permissions, lifecycle enums, error codes
  agent-protocol/   The versioned panel ⇄ agent wire protocol
  incus-client/     Typed client for the Incus Unix socket
  runtime/          Runtime-neutral abstraction; Incus is the first backend
  api-types/        HTTP DTOs — customer and operator types are separate
  test-support/     MockRuntime and fixtures

frontend/         React + Vite + TypeScript
migrations/       SQL migrations, embedded into the binary at compile time
deploy/           Dockerfiles, compose stacks, systemd unit, nginx config
docs/             Architecture, protocol, permissions, security, operations

Development commands

# Rust
cargo test --workspace --all-features
cargo clippy --workspace --all-targets --all-features
cargo fmt --all -- --check
cargo run -p bee-panel
cargo run -p incus-agent -- --config ./agent-dev.toml --check

# Frontend
pnpm typecheck
pnpm lint
pnpm test
pnpm build

# Database
DATABASE_URL=postgres://... ./scripts/migrate.sh run
DATABASE_URL=postgres://... ./scripts/migrate.sh check   # against a scratch DB

Phase status

Phase 1 is complete. The table is deliberately specific, because a page that looks finished and is not is worse than one that says so.

Delivered
Phase 1 ✅ Workspace, migrations, config validation, error model, structured logging, Argon2 sessions, RBAC, agent registration and the authenticated agent websocket, login page, both application shells, both route trees
Phase 2 Typed Incus socket client wired to real inventory, node list and detail, global instance list, stale-node detection, reconciliation
Phase 3 Power operations, the operation state machine end to end, audit logging, realtime streaming, customer instance views
Phase 4 Create-instance wizard, placement scheduler, plans, SSH keys, cloud-init, snapshots, console proxy, metrics
Phase 5 Reconciliation workers, credential rotation, node drain, operation timeouts, retention, API documentation
Phase 6 Responsive polish, command palette, accessibility and performance review, end-to-end suite

Pages whose backend does not exist yet render an explicit notice naming the phase and what it is waiting on. Endpoints that are not implemented are not mounted, so nothing 404s where a control implies it should work.

Working today: sign in and out, session listing and revocation, /me and /me/permissions, health/readiness/version, node registration, and the full agent handshake with heartbeats.


Testing

cargo test --workspace --all-features    # 568 tests
pnpm test                                # 8 tests

The Rust tests concentrate on the things that are expensive to get wrong: permission scope widening, the operation state machine's terminal states, instance-name validation against traversal and shell metacharacters, protocol round-trips and rejection of unknown fields, challenge-response authentication including replay and node-substitution attempts, reconnect backoff, and duplicate-command suppression across an agent restart.


Documentation

Document Contents
architecture.md Components, data flow, why the split is where it is
agent-protocol.md Envelope, handshake, commands, console
incus-integration.md Socket client, response envelopes, the CLI fallback
permissions.md Roles, permissions, scoping, tenancy
operations.md The operation lifecycle and reconciliation
development.md Local setup, seeded accounts, testing
deployment.md Production install, TLS, agents, upgrades
security.md The security model, and its known limitations

Licence

Proprietary. © Bee.host.