Octovalve
Secure the bridge between LLMs and your servers. Octovalve provides a policy-driven remote gateway to audit, validate, and control every tool call before execution.
Ask AI about Octovalve
Powered by Claude · Grounded in docs
I know everything about Octovalve. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Octovalve Command Gateway for AI Agents
English | 中文
Octovalve is a policy-driven command gateway for AI agents. It exposes MCP tools over stdio via octovalve-proxy,
validates and constrains each tool call, and executes approved commands on remote targets over SSH with an auditable
trail of requests and outputs.
Built-in AI risk assessment can auto-approve low-risk commands when enabled; higher-risk actions stay behind approval.
Components
octovalve-proxy: MCP stdio server that exposes therun_commandtool and forwards requests.console: approval + execution service that tracks targets and runs commands via SSH.protocol: shared request/response types between components.console-ui: optional desktop UI (Tauri + Vue).
Requirements
- Rust 1.88 (see
rust-toolchain.toml).
Quick Start
- Prepare the approval policy config (whitelist/limits):
config/config.toml
auto_approve_allowed = true
[whitelist]
allowed = [
"ls",
"cat",
"head",
"tail",
"sed",
"rg",
"grep",
"wc",
"sort",
"uniq",
"find",
"ps",
"uname",
"df",
"free",
]
denied = ["rm", "shutdown"]
arg_rules = { grep = "^[A-Za-z0-9_./-]+$" }
[limits]
timeout_secs = 30
max_output_bytes = 1048576
- Prepare the target config (see
config/local-proxy-config.tomlfor an example):
default_target = "example-target"
[defaults]
timeout_ms = 30000
max_output_bytes = 1048576
# terminal_locale = "zh_CN.UTF-8"
# ssh_args = ["-o", "ServerAliveInterval=30", "-o", "ServerAliveCountMax=3"]
[[targets]]
name = "example-target"
desc = "primary dev host"
ssh = "devops@192.168.2.162"
# ssh_password = "your password"
# tty = true
Note: ssh must include the username (user@host); it will not auto-fill a default user.
- Start the console (approval + SSH execution):
cargo run -p console -- \
--config config/local-proxy-config.toml \
--broker-config config/config.toml
By default, console listens on:
- HTTP/WS:
127.0.0.1:19309 - command channel:
127.0.0.1:19310
- Start the proxy:
cargo run -p octovalve-proxy -- --config config/local-proxy-config.toml
- Point your MCP client to
octovalve-proxy(stdio).
Example for Codex CLI (~/.codex/config.toml):
[mcp_servers.octovalve]
command = "~/octovalve/target/release/octovalve-proxy"
args = ["--config", "~/.octovalve/local-proxy-config.toml",
"--client-id", "codex-1"]
env = { RUST_LOG = "info" }
During development, you can use cargo run:
[mcp_servers.octovalve]
command = "cargo"
args = ["run", "-p", "octovalve-proxy", "--",
"--config", "~/.octovalve/local-proxy-config.toml",
"--client-id", "codex-1"]
env = { RUST_LOG = "info" }
run_command Parameters
command: command string.intent: required; why you want to run this command (for auditing).target: required; target name (defined inoctovalve-proxyconfig).mode:shell(runs via/bin/bash -lc).- Optional:
cwd,timeout_ms,max_output_bytes,env.
Common Read-Only Commands (Recommended for Whitelist)
Search/locate:
rg -n "pattern" pathrg --files -g "*.rs"grep -R -n "pattern" path
Browse/inspect:
ls,ls -lacat,head -n 20,tail -n 20sed -n '1,120p' file
Count/filter:
wc -l,sort,uniq -cfind path -type f -name "*.rs"
System/environment (read-only):
ps -ef,uname -a,df -h,free -m
list_targets
Returns the configured target list with fields like name/desc/last_seen/ssh/status/last_error.
Console API (Optional)
GET /health: health checkGET /targets: target list (name/desc/ssh/status/pending_count)GET /targets/:name/snapshot: get a target snapshotPOST /targets/:name/approve/deny: approve/denyGET /ws: WebSocket pushtargets_snapshot: initial full targets snapshottarget_updated: single-target update
Console UI (Tauri)
The optional desktop UI lives under console-ui/ (Tauri + Vue 3).
Prerequisites:
- Node.js + npm
Dev/build:
cd console-ui
npm install
# Start Tauri dev mode (runs Vite first)
npm run tauri dev
# Recommended: one command for Tauri + sidecars (auto rebuild/sync/restart)
npm run dev:tauri
# Optional: auto build/sync sidecars (octovalve-console / octovalve-proxy)
# Run in another terminal; when sidecar code changes, it rebuilds and syncs into the Tauri dev output.
npm run dev:sidecars
# Build desktop app
npm run tauri:build:dmg
# macOS universal build (arm64 + x86_64)
# Requires Xcode Command Line Tools (for lipo)
rustup target add aarch64-apple-darwin x86_64-apple-darwin
npm run tauri:build:universal:dmg
Windows NSIS notes: see docs/windows-nsis-build.md.
Runtime notes:
- On startup, the app automatically launches
console(sidecar). - On first launch, it creates
~/.octovalve/local-proxy-config.toml.example.- Copy to
local-proxy-config.toml, edit it, then restart the app.
- Copy to
remote-broker-config.tomlis stored under the app config directory (approval policy).- Default macOS path:
~/Library/Application Support/com.octovalve.console/
- Default macOS path:
Password Login
Prefer SSH keys. If you must use a password, configure ssh_password per target.
console/octovalve-proxy inject the password via a temporary SSH_ASKPASS script (~/.octovalve/ssh-askpass.sh) without requiring sshpass.
If the server requires keyboard-interactive/2FA, SSH_ASKPASS cannot complete the flow; use SSH keys or change the auth method.
CLI Options
octovalve-proxy:
--config(default:config/local-proxy-config.toml)--client-id(default:octovalve-proxy)--command-addr(default:127.0.0.1:19310)--timeout-ms(default:30000)--max-output-bytes(default:1048576)
console:
--config(targets config; same format asconfig/local-proxy-config.toml)--listen-addr(default:127.0.0.1:19309)--command-listen-addr(default:127.0.0.1:19310)--broker-config(approval policy config; default:config/config.toml)--local-audit-dir(default:~/.octovalve/logs/local)--log-to-stderr(default: off)
Security Notes
- No built-in authentication; keep console bound to
127.0.0.1. - SSH uses
BatchMode=yesto avoid interactive prompts. If you want auto-accept on first connect, addStrictHostKeyChecking=accept-newtossh_args. - Only
shellmode is supported (/bin/bash -lc). - Run as a non-root user and monitor audit logs.
Output Persistence
Each request writes full request/result metadata and outputs under the audit directory (default: ~/.octovalve/logs/local/<target>):
<id>.request.json<id>.result.json<id>.stdout<id>.stderr
request.json includes intent, mode, raw_command, pipeline, etc.
License
Licensed under the Apache License, Version 2.0. See LICENSE.
