Commit graph

4 commits

Author SHA256 Message Date
8d789524e8 feat: container backend — ephemeral right-sized shell containers
Third session backend: per-session ephemeral containers.
SSH session → container spawns → operator works → disconnect → destroyed.

Container runtime abstraction:
  Docker, Podman, Nerdctl via CLI execution (auto-detect)
  No libdocker dependency — any OCI-compliant runtime

Container config ([container] section):
  image, pull_policy, mounts, env, memory/cpu limits
  ephemeral (destroy on exit), hardened (drop caps)
  read_only_rootfs, network mode, user override

Handler: SessionBackend enum now has three variants:
  Local(PtyBridge) — spawn local shell
  Proxy(UpstreamSession) — forward to remote SSH host
  Container(ContainerSession) — spawn ephemeral container
  Priority: proxy > container > local PTY

Curated base images (images/):
  minimal — bash, coreutils, curl, jq, ssh (~50MB)
  k8s-ops — + kubectl, helm (~120MB)
  net-ops — + nmap, dig, traceroute, tcpdump (~90MB)
  dev — + git, make, gcc, python3 (~250MB)

The container IS the access boundary:
if it's not in the image, the operator can't run it.

SessionHandler hooks fire in all three modes.
6.5MB binary, 0 substrate deps, 1197 lines bascule-core.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 23:23:39 -04:00
2212f7f870 feat: remote SSH proxy mode
Bascule now supports two session modes:
  Local — spawns a PTY on this machine (default, existing)
  Proxy — forwards the session to a target SSH host (NEW)

Proxy mode:
  SSH client ←→ bascule (auth + hooks) ←→ target SSH host
  Authenticates client via configured auth provider
  Connects to upstream SSH host via russh client
  Bridges I/O between client and upstream channels
  PTY, shell, and exec requests forwarded to target
  Exit status propagated back to client

Config:
  [proxy]
  target_host = "192.168.1.100"
  target_port = 22
  target_user = "deploy"           # optional, defaults to principal
  target_key_path = "/etc/bascule/target_key"
  accept_target_host_key = false   # dev only

SessionHandler hooks fire in both modes:
  on_session_start, on_exec, on_session_end
  Custom handlers can enforce policy regardless of mode

New file: proxy.rs (152 lines)
  UpstreamHandler — minimal russh client handler
  connect_upstream — connects + authenticates to target
  bridge_upstream_to_client — bidirectional I/O bridge

Binary: 6.3MB, zero substrate deps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 23:01:08 -04:00
02142f7be4 feat: Entra Agent ID auth provider + governance leak cleanup
New crate: bascule-auth-agent-id
  Microsoft Entra Agent ID authentication for AI agents
  Validates OAuth tokens against Entra JWKS (60min cache)
  Extracts agent metadata: type, blueprint, sponsor, scopes
  Detects on-behalf-of (delegated) agents
  Token-as-password pattern for SSH auth

Cleanup:
  Removed all governance-specific references from comments
  SessionHandler trait is the only extension point
  Zero substrate/chronicle/gsap dependencies
  Config example uses neutral terminology

Config:
  [auth.agent_id] section for Entra configuration
  tenant_id, audiences, multi_tenant fields

3 crates: bascule-core, bascule-server, bascule-auth-agent-id
938 lines total, 5.6MB binary, 0 substrate deps.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:35:32 -04:00
bfa26cfd15 feat: Bascule — identity-aware SSH proxy
Open-source SSH proxy with pluggable authentication and
extensible session handling. Zero external governance dependencies.

Core (bascule-core):
  russh 0.46 SSH server with PTY bridge (portable-pty)
  Pluggable auth: AuthProvider trait (SSH keys, accept-all dev mode)
  SessionHandler trait for extending behavior (audit, governance)
  TOML configuration, ephemeral Ed25519 host key generation

Binary (bascule-server):
  Single binary, 5.6MB release build
  CLI with --config flag
  Default: accept-all auth on port 2222

Extension points:
  AuthProvider — implement for OIDC, certificates, custom auth
  SessionHandler — implement for audit, governance, recording
  DefaultHandler — passthrough (ships with open-source version)

Zero substrate/chronicle/gsap/hfl dependencies.
Apache 2.0 License.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:25:33 -04:00