From 6eb2de5dc01fb3852b0c107a33ad294cdcaa3f2663f8447fff35af4d98478739 Mon Sep 17 00:00:00 2001 From: Tyler King Date: Sun, 5 Apr 2026 17:17:18 -0400 Subject: [PATCH] docs: update all documentation for management API + dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated 9 files to reflect: Management API (axum, port 9090) — embedded in bascule-server Dioxus dashboard components (WASM web target) 6 crates in workspace (was 4) README.md: Added Management API + Dashboard features section Added dashboard row to comparison table docs/architecture.md: Updated diagram showing dual-listener architecture Added Management API section explaining Arc sharing Updated crate table (6 crates) docs/configuration.md: Added [dashboard] config section reference docs/observability.md: Added Management API monitoring section with curl examples docs/quickstart.md: Added Management API quick start section docs/comparison.md: Added dashboard and TPM attestation rows CLAUDE.md + CONTRIBUTING.md: Updated crate lists and feature flags config/bascule.example.toml: Added [dashboard] section All 17 README links verified valid. Build clean. Signed-off-by: Tyler King --- CLAUDE.md | 7 ++++-- CONTRIBUTING.md | 8 ++++--- README.md | 10 +++++++++ config/bascule.example.toml | 6 +++++ docs/architecture.md | 45 +++++++++++++++++++++++++------------ docs/comparison.md | 2 ++ docs/configuration.md | 11 +++++++++ docs/observability.md | 17 ++++++++++++++ docs/quickstart.md | 15 +++++++++++++ 9 files changed, 102 insertions(+), 19 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index f9e0283..b615773 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,10 +6,12 @@ Bascule is an identity-aware SSH proxy. It authenticates operators via SSH keys ## Workspace -- `crates/bascule-core/` — Library: SSH server, auth, session backends, hooks -- `crates/bascule-server/` — Binary: CLI wrapper, config loading, telemetry setup +- `crates/bascule-core/` — Library: SSH server, auth, session backends, hooks, session store +- `crates/bascule-server/` — Binary: SSH proxy + embedded management API (axum) - `crates/bascule-auth-agent-id/` — Optional: Entra Agent ID auth provider - `crates/bascule-shell/` — Binary: Identity-aware login shell with TPM attestation +- `crates/bascule-dashboard/` — Library: Dioxus UI components +- `crates/bascule-dashboard-web/` — Binary: WASM web dashboard target - `charts/bascule/` — Helm chart for K8s deployment - `images/` — Curated container images for operator environments @@ -30,6 +32,7 @@ make dev # Run locally in dev mode ## Feature flags (bascule-server) +- `dashboard` — Management API on port 9090 (default on) - `agent-id` — Entra Agent ID auth ## Rules diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9a5f3af..edf6926 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,10 +15,12 @@ Bascule is a Rust workspace: | Crate | Purpose | |-------|---------| -| `bascule-core` | Library — SSH server, auth, PTY, proxy, container, hooks | -| `bascule-server` | Binary — CLI, config, telemetry | +| `bascule-core` | Library — SSH server, auth, PTY, proxy, container, hooks, store | +| `bascule-server` | Binary — SSH proxy + management API (axum) | | `bascule-auth-agent-id` | Optional — Entra Agent ID auth | -| `bascule-shell` | Binary — Identity-aware login shell | +| `bascule-shell` | Binary — Identity-aware login shell with TPM | +| `bascule-dashboard` | Library — Dioxus UI components | +| `bascule-dashboard-web` | Binary — WASM web dashboard target | ## Testing diff --git a/README.md b/README.md index 1216525..f82be1e 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,19 @@ See [docs/quickstart.md](docs/quickstart.md) for Docker, Helm, and container mod - Read-only rootfs option - NetworkPolicy for Kubernetes deployments +### Management API + Dashboard + +Built-in HTTP management API (port 9090, `--features dashboard`): +- `GET /api/sessions` — active sessions with auth/backend/TPM status +- `GET /api/stats` — aggregate analytics (auth breakdown, peak concurrent, TPM %) +- `GET /api/health` — server health and version +- WASM dashboard at `/dashboard/` *(coming soon)* + ### Observability - Structured JSON logging (`BASCULE_LOG_FORMAT=json`) - Tracing spans on auth, session lifecycle, exec requests +- Management API for real-time session monitoring ## Client: bascule-shell @@ -76,6 +85,7 @@ See [docs/bascule-shell.md](docs/bascule-shell.md). | Container sessions | Yes | No | No | | AI Agent Identity | Yes (Entra Agent ID) | No | No | | Binary size | ~7MB | ~150MB | ~100MB | +| Built-in dashboard | Yes (port 9090) | Yes | No | See [docs/comparison.md](docs/comparison.md). diff --git a/config/bascule.example.toml b/config/bascule.example.toml index b89899e..a287f66 100644 --- a/config/bascule.example.toml +++ b/config/bascule.example.toml @@ -79,6 +79,12 @@ mode = "accept-all" # shell_container = "shell" # shell = "/bin/bash" +# ─── Dashboard / Management API ───────────────────────── +# Enabled by default with --features dashboard +[dashboard] +enabled = true +listen = "0.0.0.0:9090" + # ─── Telemetry ────────────────────────────────────────── # [telemetry] # otlp_endpoint = "http://localhost:4317" diff --git a/docs/architecture.md b/docs/architecture.md index cb7bb56..f238b13 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -2,20 +2,28 @@ ## Overview -Bascule is a single-binary SSH proxy with three pluggable layers: +Bascule is a single-binary SSH proxy with a built-in management API: ``` -Client SSH → Bascule Server - │ - ├── AuthProvider (SSH keys / OIDC / Agent ID) - │ - ├── SessionHandler hooks - │ on_session_start → build_session_env → on_exec → on_session_end - │ - └── SessionBackend - ├── LocalPty (portable-pty → /bin/bash) - ├── RemoteProxy (upstream SSH → target host) - └── Container (docker/podman → ephemeral image) + ┌─────────────────────────────────────┐ +Operator workstation │ bascule (single binary) │ +┌───────────────┐ │ │ +│ bascule-shell │ SSH │ Port 2222: SSH Proxy (russh) │ +│ identity + │─────▶│ ├── AuthProvider │ +│ TPM attest │ │ ├── SessionHandler hooks │ +└───────────────┘ │ └── SessionBackend │ + │ ├── Local PTY │ +Browser / curl │ ├── Remote Proxy │ +┌───────────────┐ HTTP │ └── Container │ +│ Dashboard │─────▶│ │ +│ /api/* │ │ Port 9090: Management API (axum) │ +└───────────────┘ │ ├── /api/sessions │ + │ ├── /api/stats │ + │ ├── /api/health │ + │ └── /dashboard (WASM, planned) │ + │ │ + │ Arc shared │ + └─────────────────────────────────────┘ ``` ## Session Backends @@ -81,10 +89,19 @@ When `ephemeral = true` (default), the container is `--rm` and destroyed on disc Set `network = "none"` to completely isolate the container from the network. The operator can run local tools but can't reach external services. +## Management API + +The management API runs alongside the SSH proxy in the same process. Both share an `Arc` — when a session starts via SSH, the store updates; when the dashboard polls `/api/sessions`, it reads the same store. Zero serialization, zero IPC. + +Enable via `[dashboard]` config section or `--features dashboard` (default on). + ## Crate Structure | Crate | Purpose | |-------|---------| -| `bascule-core` | Library — server, handler, auth, PTY, proxy, container, hooks | -| `bascule-server` | Binary — CLI, config loading, tracing setup | +| `bascule-core` | Library — server, handler, auth, PTY, proxy, container, hooks, store | +| `bascule-server` | Binary — CLI, config, tracing, management API | | `bascule-auth-agent-id` | Optional — Entra Agent ID authentication | +| `bascule-shell` | Binary — Identity-aware login shell with TPM | +| `bascule-dashboard` | Library — Dioxus UI components | +| `bascule-dashboard-web` | Binary — WASM web dashboard target | diff --git a/docs/comparison.md b/docs/comparison.md index 7a3d39f..d11e55e 100644 --- a/docs/comparison.md +++ b/docs/comparison.md @@ -14,6 +14,8 @@ | Extensibility | SessionHandler trait | Plugin system | No | No | | Proxy mode | Built-in | Built-in | Built-in | SaaS | | Config | Single TOML file | Complex YAML | Complex HCL | Web UI | +| Built-in dashboard | Yes (port 9090) | Yes | No | Yes (SaaS) | +| TPM attestation | Yes (bascule-shell) | No | No | No | ## When to choose Bascule diff --git a/docs/configuration.md b/docs/configuration.md index 32d6dd1..9e9d94c 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -111,6 +111,17 @@ memory_limit = "512m" network = "none" ``` +## `[dashboard]` + +Management API and dashboard (requires `--features dashboard`, default on). + +| Field | Type | Default | Description | +|-------|------|---------|-------------| +| `enabled` | bool | `true` | Enable management API | +| `listen` | string | `0.0.0.0:9090` | Listen address for HTTP API | + +## Example Configs + ### Jumphost (proxy) ```toml diff --git a/docs/observability.md b/docs/observability.md index f3bb9d5..0735a59 100644 --- a/docs/observability.md +++ b/docs/observability.md @@ -38,6 +38,23 @@ RUST_LOG=bascule=debug ./bascule --config config.toml # debug bascule only | Upstream connected | INFO | Proxy session connected to target | | Session ended | INFO | Disconnect or exit | +## Management API + +The built-in management API (port 9090) provides real-time session monitoring: + +```bash +# Active sessions +curl http://localhost:9090/api/sessions + +# Aggregate stats (auth breakdown, TPM %, peak concurrent) +curl http://localhost:9090/api/stats + +# Server health +curl http://localhost:9090/api/health +``` + +Configure via `[dashboard]` in your config file. See [configuration.md](configuration.md). + ## OTel Tracing (Planned) OpenTelemetry OTLP export is planned as an optional feature flag (`--features telemetry`). Not yet implemented. Session lifecycle will map to OTel spans: diff --git a/docs/quickstart.md b/docs/quickstart.md index 45de379..61b9bc4 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -56,6 +56,21 @@ TOML ./target/release/bascule --config proxy-config.toml ``` +## Management API + +The management API starts automatically on port 9090: + +```bash +# Check server health +curl http://localhost:9090/api/health + +# View active sessions +curl http://localhost:9090/api/sessions + +# Aggregate stats +curl http://localhost:9090/api/stats +``` + ## Next Steps - [Configuration Reference](configuration.md)