Skip to content

abendrothj/bastion

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bastion

A zero-trust routing hub for running autonomous AI agents safely. Bastion sits between the open internet and your local agents, enforcing hard security boundaries before any code executes on your host.

Built in Rust on Axum. Lean, fast, and deployable on ARM64.


Architecture

Internet / Agents
      │
 ┌────▼────────────────────────────────────────────┐
 │  Ingress Firewall (axum reverse proxy)           │
 │  • Validates all webhooks and WebSocket events   │
 │  • Drops malformed requests before routing       │
 └────┬────────────────────────────────────────────┘
      │
 ┌────▼────────────────────────────────────────────┐
 │  API Security Layer                              │
 │  • Per-IP rate limiting (tower-governor)         │
 │  • Configurable payload size cap                 │
 │  • Authorization header enforcement              │
 └────┬────────────────────────────────────────────┘
      │
 ┌────▼────────────────────────────────────────────┐
 │  Cognitive Firewall                              │
 │  • Static regex blocklist (jailbreak strings,   │
 │    system-prompt overrides, shell signatures)    │
 │  • serde + validator schema enforcement          │
 └────┬────────────────────────────────────────────┘
      │
 ┌────▼────────────────────────────────────────────┐
 │  Routing Layer                                   │
 │  • /api/v1/llm     — LLM proxy endpoint          │
 │  • /api/v1/sandbox/run — ephemeral execution     │
 │  • /ws             — WebSocket ingress           │
 │  • /health /ready  — liveness probes             │
 └────┬────────────────────────────────────────────┘
      │
 ┌────▼────────────────────────────────────────────┐
 │  Sandbox Manager (bollard / Docker)              │
 │  • Ephemeral isolated containers per task        │
 │  • Hard TTL — runaway containers are killed      │
 │  • No network, read-only FS, capped CPU/RAM      │
 └─────────────────────────────────────────────────┘

The Sandbox is the ultimate failsafe. Even if an adversarial payload slips past every layer above it, the container is a dead end — no network, no host filesystem, and a hard timeout that kills it if an agent loops forever.


Configuration

All settings live in bastion.toml at the same directory as the binary. Every field is optional; the defaults are production-ready out of the box.

[api]
listen_addr    = "0.0.0.0:8080"
upstream_base  = "http://localhost:3001"
max_body_bytes = 1_048_576   # 1 MiB

[rate_limit]
requests_per_second = 5
burst_size          = 10

[sandbox]
default_image = "alpine:latest"
memory_bytes  = 134_217_728   # 128 MiB
cpu_quota     = 50_000        # 50% of one vCPU
read_only     = true
ttl_seconds   = 30            # hard kill after 30 s
max_pids      = 64

Environment variables override bastion.toml for deployment-time injection:

Variable Overrides
LISTEN_ADDR api.listen_addr
UPSTREAM_BASE api.upstream_base
RUST_LOG log filter (tracing)

Endpoints

Method Path Description
GET /health Liveness probe — returns 200 ok
GET /ready Readiness probe — same as /health
POST /api/v1/llm Submit a chat payload; cognitive firewall runs
POST /api/v1/sandbox/run Run a command in an ephemeral Docker container
GET /ws WebSocket ingress
* /* Catch-all reverse proxy to upstream_base

POST /api/v1/llm

{
  "model": "llama3",
  "messages": [
    { "role": "user", "content": "What is the capital of France?" }
  ],
  "temperature": 0.7
}

Returns the sanitized payload after the cognitive firewall has run. Flagged messages are stripped; if the entire payload is adversarial, 400 is returned.

POST /api/v1/sandbox/run

{
  "image": "alpine:latest",
  "command": ["sh", "-c", "echo hello"],
  "ttl_seconds": 10
}

All fields except command are optional and fall back to bastion.toml. Returns stdout, stderr, and exit code.

{
  "stdout": "hello\n",
  "stderr": "",
  "exit_code": 0
}

Running

From source

cargo build --release
RUST_LOG=info ./target/release/hub

Docker Compose

docker compose up -d

The hub mounts the host Docker socket (/var/run/docker.sock) so it can spawn sibling containers for sandbox execution. ARM64-compatible.


Security model

Threat Mitigation
Endpoint hammering Per-IP rate limiting via tower-governor
Oversized payloads Configurable byte cap, enforced before parsing
Missing auth Authorization header required on all non-probe routes
Prompt injection Static regex blocklist strips known jailbreak patterns
Malformed LLM schema serde + validator rejects at deserialization
Runaway agent (infinite loop) Container TTL — hard SIGKILL after ttl_seconds
Lateral movement NetworkMode::None on all sandbox containers
Host filesystem access readonly_rootfs: true by default
Privilege escalation cap_drop: ALL, no-new-privileges: true
Fork bombs pids_limit enforced via Docker

Roadmap

  • OpenTelemetry (OTLP) — export spans to Prometheus / Grafana / Datadog
  • SSE streaming — stream LLM token chunks directly to clients
  • Human-in-the-Loop hooks — pause agent execution on high-stakes actions pending signed operator approval
  • MCP host — register and route Model Context Protocol tool servers

About

bastion is a lightweight, zero-trust control plane for OpenClaw. Built in Rust, it acts as an ingress firewall and orchestration engine: intercepting malicious payloads, sanitizing prompt injections, and spinning up ephemeral, network-isolated Docker sandboxes for safe agent execution.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors