bascule-oss/README.md
Tyler King 2fa92f8635 docs: comprehensive documentation + developer experience polish
New files:
  CONTRIBUTING.md — dev setup, code style, PR process
  CLAUDE.md — workspace context for Claude Code
  Makefile — build, test, lint, fmt, docker, helm-lint, dev, ci
  .editorconfig — consistent formatting
  rustfmt.toml — Rust formatting config
  docs/kubernetes.md — Helm install, values, architecture
  docs/bascule-shell.md — client shell install, config, TPM
  charts/bascule/README.md — Helm quick start

Updated:
  README.md — accurate feature matrix, clear shipped vs planned
  config/bascule.example.toml — full reference (72 lines, all fields)

All 15 README links verified valid.
Helm lint clean. Build passes. 0 substrate deps.

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

4.1 KiB

Bascule

Identity-aware SSH proxy for modern infrastructure.

Bascule authenticates operators via SSH keys or AI agent tokens, then connects them to a local shell, remote host, or ephemeral container. No agents to install. No control plane. One binary.

Quick Start

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 for Docker, Helm, and container mode.

Features

Session Backends

Mode Config Description
Local PTY (default) Spawn a local shell process
Remote Proxy [proxy] Forward to a remote SSH host
Container [container] Ephemeral container per session (Docker/Podman/nerdctl)
Kubernetes [k8s] Shared jumphost with shell sidecar (config ready, runtime coming)

Authentication

  • SSH Keys — standard OpenSSH authorized_keys files
  • Accept All — development only, accepts any key
  • Entra Agent ID — Microsoft AI agent identity (--features agent-id)
  • SPIFFE/SPIRE — workload identity (config ready, runtime coming)

Security

  • Session limiting (semaphore-based max_sessions)
  • Container hardening (--cap-drop ALL, --security-opt no-new-privileges)
  • Container config validation (injection prevention)
  • Read-only rootfs option
  • NetworkPolicy for Kubernetes deployments

Observability

  • Structured JSON logging (BASCULE_LOG_FORMAT=json)
  • Tracing spans on auth, session lifecycle, exec requests

Client: bascule-shell

Identity-aware login shell with TPM attestation:

./target/release/bascule-shell --info
╔═══════════════════════════════════════════════════════╗
║  Bascule Shell v0.1.0                                 ║
║  Principal:  tking                                     ║
║  Method:     ssh-key                                   ║
║  TPM:        available (6 PCRs verified)               ║
║  Platform:   sha256:e9b95f002f54222d...                ║
╚═══════════════════════════════════════════════════════╝

See docs/bascule-shell.md.

Comparison

Bascule Teleport Boundary
License Apache 2.0 AGPL / Commercial MPL / Commercial
Agents required No Yes Yes
Control plane No Required Required
Container sessions Yes No No
AI Agent Identity Yes (Entra Agent ID) No No
Binary size ~7MB ~150MB ~100MB

See docs/comparison.md.

Deployment

  • Standalone: cargo build --release -p bascule-server
  • Docker: docker build -t bascule .
  • Kubernetes: helm install bascule charts/bascule/ — see docs/kubernetes.md

Extending Bascule

Implement SessionHandler to add custom policy:

use bascule_core::hooks::{SessionHandler, SessionInfo};

struct AuditHandler;

#[async_trait]
impl SessionHandler for AuditHandler {
    async fn on_session_start(&self, s: &SessionInfo) -> anyhow::Result<()> {
        println!("{} connected from {}", s.principal, s.source_ip);
        Ok(())
    }
}

See docs/architecture.md.

Roadmap

Not yet implemented:

  • OIDC authentication (Keycloak, Entra, Okta)
  • K8s API exec backend runtime
  • SPIFFE/SPIRE auth runtime
  • OpenTelemetry OTLP exporter
  • Prometheus metrics endpoint
  • Session recording
  • Per-session Pod isolation

Documentation

License

Apache 2.0