bascule-oss/README.md
Tyler King 043b9b9bdc feat: bascule-shell — identity-aware shell with TPM attestation
New crate: bascule-shell (471 lines, 1.8MB binary)
  Login shell that detects identity + platform attestation at startup.
  Wraps bash/zsh/fish — operator works normally, identity travels with them.

Identity detection (priority order):
  1. Entra via WSL2 interop
  2. Azure CLI
  3. Kerberos TGT
  4. Cached OIDC token
  5. System user (fallback)

Platform attestation:
  TPM 2.0 PCR values via tpm2_pcrread (PCRs 0,1,2,7,10,14)
  IMA measurement log hash + count
  Keylime agent state
  Entra device compliance (WSL2 only)
  Composite SHA-256 hash over all evidence

Shell features:
  Banner with identity + attestation summary
  BASCULE_* env vars injected into inner shell
  --info mode for dry-run display
  --json mode for machine-readable output
  --exec mode for single-command execution
  Configurable via ~/.config/bascule/shell.toml

Tested on Fedora with real TPM 2.0:
  6 PCRs successfully read from hardware
  All env vars propagated to inner shell
  1.8MB binary, 0 substrate deps

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:47:46 -04:00

110 lines
3.4 KiB
Markdown

# Bascule
Identity-aware SSH proxy for modern infrastructure.
**Bascule** is a lightweight SSH proxy that authenticates users via SSH keys 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 file
- **AI agent authentication** — Microsoft Entra Agent ID support (optional feature)
- **Session limiting** — configurable max concurrent sessions
- **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 |
| Auth | SSH keys, Entra Agent ID | OIDC, SAML, GitHub | OIDC, LDAP |
| 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 custom authorization, audit logging, and session governance.
## 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)
## Roadmap
- [ ] OIDC authentication (Keycloak, Entra, Okta, Google)
- [ ] Certificate-based authentication
- [ ] OpenTelemetry OTLP trace export
- [ ] Prometheus metrics endpoint
- [ ] Session recording
- [ ] Web UI for session management
## License
Apache 2.0