Open-source SSH proxy with identity-aware shell (Rust)
Helm chart (charts/bascule/): Deployment with shell sidecar container (shared jumphost model) Service (LoadBalancer/NodePort/ClusterIP) ConfigMap with auto-generated config.toml RBAC (Role + RoleBinding for pods/exec) NetworkPolicy (restrict shell egress, allow DNS + K8s API) ServiceAccount with create flag Configurable shell image (k8s-ops, net-ops, dev, minimal) Helm lint passes clean K8s backend config (bascule-core): [k8s] section: enabled, namespace, pod_name, shell_container, shell Auto-detection via POD_NAME/POD_NAMESPACE env vars (downward API) Backend priority: K8s > proxy > container > local PTY K8s exec implementation deferred to --features k8s (kube crate) SPIFFE/SPIRE auth config: [auth.spiffe] section: trust_domain, trust_bundle_path, workload_api_socket JWT-SVID token-as-password authentication pattern Implementation deferred to bascule-auth-spiffe crate Zero substrate dependencies. Default build unchanged. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .github/workflows | ||
| charts/bascule | ||
| config | ||
| crates | ||
| docs | ||
| images | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
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
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 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.
[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 for the full comparison.
Extending Bascule
Implement the SessionHandler trait to add custom behavior:
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 use the SessionHandler trait to add custom authorization, audit logging, and session governance.
Documentation
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