# Bascule Identity-aware SSH proxy for modern infrastructure. **Bascule** is a lightweight SSH proxy that authenticates users via SSH keys, OIDC, or AI agent tokens, then connects them to a local shell, remote host, or ephemeral container. No agents. No control plane. One binary. ## Quick Start ```bash cargo build --release -p bascule-server ./target/release/bascule --config config/bascule.example.toml # In another terminal: ssh -p 2222 localhost ``` See [docs/quickstart.md](docs/quickstart.md) for Docker and container mode. ## Session Modes | Mode | Config | Use case | |------|--------|----------| | **Local PTY** | (default) | Spawn a local shell | | **Remote proxy** | `[proxy]` | Forward to a remote SSH host | | **Container** | `[container]` | Ephemeral container per session | ### Container mode Each SSH session spawns a fresh container. The image defines the toolset — if it's not in the image, the operator can't use it. ```toml [container] image = "bascule-shell:k8s-ops" ephemeral = true hardened = true memory_limit = "512m" ``` ## Features - **Three backends** — local PTY, remote SSH proxy, ephemeral containers - **Identity-aware sessions** — every connection authenticated and attributed - **SSH key authentication** — standard authorized_keys, no surprises - **AI agent authentication** — native Microsoft Entra Agent ID support - **Right-sized images** — curated container images (minimal, k8s-ops, net-ops, dev) - **SessionHandler trait** — extend with custom policy, audit, or recording - **Structured logging** — JSON format for production observability - **Small footprint** — single binary, ~7MB, <64MB memory ## Comparison | | Bascule | Teleport | Boundary | |---|---|---|---| | Agents | None | Required | Required | | Control plane | None | Required | Required | | License | Apache 2.0 | AGPL | MPL | | Container sessions | Native | No | No | | AI Agent Identity | Native | No | No | | Binary size | ~7MB | ~150MB | ~100MB | See [docs/comparison.md](docs/comparison.md) for the full comparison. ## Extending Bascule Implement the `SessionHandler` trait to add custom behavior: ```rust use bascule_core::hooks::{SessionHandler, SessionInfo}; struct MyAuditHandler; #[async_trait] impl SessionHandler for MyAuditHandler { async fn on_session_start(&self, session: &SessionInfo) -> anyhow::Result<()> { log::info!("{} connected from {}", session.principal, session.source_ip); Ok(()) } async fn on_exec(&self, session: &SessionInfo, command: &str) -> anyhow::Result<()> { log::info!("{} executed: {}", session.principal, command); Ok(()) } } ``` Projects like [Guildhouse](https://guildhouse.dev) use the SessionHandler trait to add authorization contexts, completion receipts, and merkle-anchored audit trails. ## Documentation - [Quick Start](docs/quickstart.md) - [Configuration](docs/configuration.md) - [Authentication](docs/authentication.md) - [Architecture](docs/architecture.md) - [Observability](docs/observability.md) - [Comparison](docs/comparison.md) - [Container Images](images/README.md) ## License Apache 2.0