Skip to content

Commit bd49e34

Browse files
committed
docs(readme): redesign with product focus and quickstart guides
1 parent 899b80b commit bd49e34

1 file changed

Lines changed: 119 additions & 166 deletions

File tree

README.md

Lines changed: 119 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -1,242 +1,195 @@
11
# Sluice
22

3-
[![CI](../../actions/workflows/ci.yml/badge.svg)](../../actions/workflows/ci.yml)
4-
[![E2e Linux](../../actions/workflows/e2e-linux.yml/badge.svg)](../../actions/workflows/e2e-linux.yml)
5-
[![E2e macOS](../../actions/workflows/e2e-macos.yml/badge.svg)](../../actions/workflows/e2e-macos.yml)
3+
Credential-injecting approval proxy for AI agents. Sluice sits between your AI agent and the internet, ensuring every outbound connection and tool call is governed by policy, approved by a human when needed, and never exposes real credentials to the agent.
64

7-
Credential-injecting approval proxy for AI agents. Two layers of governance: MCP-level (semantic tool control) and network-level (all-protocol interception). Asks for human approval via Telegram, injects credentials, and forwards.
5+
## Why Sluice
86

9-
**Status:** v0.0.1-alpha. Core proxy, policy engine, MCP gateway, and Telegram approval flow functional.
7+
AI agents need API keys, database credentials, and service tokens to do useful work. Giving them real credentials is risky. They can leak secrets in tool outputs, exfiltrate data to unexpected endpoints, or make destructive API calls without oversight.
108

11-
## Quick Start
9+
Sluice solves this with two layers of governance:
1210

13-
```bash
14-
go build -o sluice ./cmd/sluice/
15-
./sluice --db sluice.db --config examples/config.toml
16-
```
11+
- **MCP Gateway** -- intercepts tool calls between the agent and MCP servers. Sees tool names, arguments, and responses. Blocks dangerous operations (file writes, exec, deletions) and redacts secrets from responses. Governs local tools that never touch the network.
12+
- **SOCKS5 Proxy** -- intercepts every TCP and UDP connection from the agent's container. Supports HTTP, HTTPS, WebSocket, gRPC, SSH, IMAP, SMTP, DNS, and QUIC/HTTP3. Injects real credentials at the network level via MITM so the agent never sees them.
1713

18-
On first run with an empty database, `--config` seeds the DB from the TOML file. Subsequent runs use the SQLite store directly.
14+
The agent gets phantom tokens (random strings that look like real API keys). Sluice swaps them for real credentials in-flight. If the agent leaks a phantom token, it's useless outside the proxy.
1915

20-
Test with curl:
16+
## How It Works
2117

22-
```bash
23-
curl -x socks5h://127.0.0.1:1080 https://api.anthropic.com/
2418
```
19+
Container (Docker / Apple Container / macOS VM):
20+
AI Agent (OpenClaw) -- uses phantom tokens, thinks they're real
21+
tun2proxy -- routes all traffic to SOCKS5
2522
26-
## CLI Flags
23+
Host:
24+
Sluice SOCKS5 Proxy -- policy + MITM + credential injection
25+
Sluice MCP Gateway -- tool-level policy + argument inspection
26+
Telegram Bot -- human approval for "ask" verdicts
27+
```
2728

28-
| Flag | Default | Description |
29-
|------|---------|-------------|
30-
| `--listen` | `127.0.0.1:1080` | SOCKS5 listen address |
31-
| `--db` | `sluice.db` | Path to SQLite policy database |
32-
| `--config` | (none) | TOML seed file (imported only when DB is empty) |
33-
| `--audit` | `audit.jsonl` | Path to audit log file |
34-
| `--telegram-token` | `$TELEGRAM_BOT_TOKEN` | Telegram bot token for approval flow |
35-
| `--telegram-chat-id` | `$TELEGRAM_CHAT_ID` | Telegram chat ID for approvals |
36-
| `--health-addr` | `127.0.0.1:3000` | Health check HTTP address |
37-
| `--shutdown-timeout` | `10s` | Graceful shutdown timeout |
38-
| `--runtime` | `auto` | Container runtime: `docker`, `apple`, `none`, `auto` |
39-
| `--container-name` | `openclaw` | Agent container name (env: `SLUICE_AGENT_CONTAINER`) |
40-
| `--docker-socket` | (auto-detect) | Docker socket path for container management |
41-
| `--phantom-dir` | (none) | Shared volume path for phantom token files (enables hot-reload) |
29+
Every connection is evaluated against policy rules (allow / deny / ask). "Ask" verdicts send a Telegram notification with inline buttons. The agent blocks until the human responds. Credentials are managed via Telegram commands or CLI, stored encrypted with age, and hot-reloaded into the agent container without restarts.
4230

43-
## CLI Subcommands
31+
## Quick Start
4432

45-
### Policy management
33+
### Docker (Linux)
4634

47-
```
48-
sluice policy list [--verdict allow|deny|ask|redact] [--db sluice.db]
49-
sluice policy add allow <destination> [--ports 443,80] [--name "reason"]
50-
sluice policy add deny <destination> [--name "reason"]
51-
sluice policy add ask <destination> [--ports 443] [--name "reason"]
52-
sluice policy remove <id>
53-
sluice policy import <path.toml>
54-
sluice policy export
55-
```
35+
The recommended setup for Linux. Three containers share a network namespace: sluice (proxy), tun2proxy (routes all traffic through SOCKS5), and your AI agent.
5636

57-
### MCP upstream management
37+
```bash
38+
# 1. Clone and configure
39+
git clone https://github.com/nnemirovsky/sluice.git && cd sluice
40+
cp examples/config.toml config.toml # edit policy rules
5841

59-
```
60-
sluice mcp add <name> --command <cmd> [--args "arg1,arg2"] [--env "KEY=VAL,..."] [--timeout 120]
61-
sluice mcp list
62-
sluice mcp remove <name>
63-
sluice mcp # start MCP gateway
64-
```
42+
# 2. Set up credentials
43+
export TELEGRAM_BOT_TOKEN="your-bot-token"
44+
export TELEGRAM_CHAT_ID="your-chat-id"
6545

66-
### Credential management
46+
# 3. Start
47+
docker compose up -d
6748

68-
```
69-
sluice cred add <name> [--destination host] [--ports 443] [--header Authorization] [--template "Bearer {value}"]
70-
sluice cred list
71-
sluice cred remove <name>
49+
# 4. Add API credentials (phantom tokens auto-generated, hot-reloaded to agent)
50+
docker exec sluice sluice cred add anthropic_api_key \
51+
--destination api.anthropic.com --ports 443 \
52+
--header x-api-key
7253
```
7354

74-
When `--destination` is provided, `sluice cred add` also creates an allow rule and binding in the store.
55+
### Apple Container (macOS)
56+
57+
Native macOS micro-VMs via Virtualization.framework. Lightweight isolation with sub-second boot. Runs Linux guests.
58+
59+
```bash
60+
# 1. Build sluice
61+
go build -o sluice ./cmd/sluice/
7562

76-
### Other subcommands
63+
# 2. Start with Apple Container runtime
64+
./sluice --runtime apple --container-name openclaw \
65+
--phantom-dir /tmp/sluice-phantoms
7766

67+
# 3. Network routing (requires root for pf rules)
68+
sudo ./scripts/apple-container-setup.sh
7869
```
79-
sluice cert generate # generate CA certificate for HTTPS MITM
80-
sluice audit verify # verify audit log hash chain integrity
70+
71+
### macOS VM (via tart)
72+
73+
Full macOS guest VM with access to Apple frameworks (iMessage, EventKit, Keychain, Shortcuts). Use this when your agent needs to interact with Apple ecosystem services that are unavailable in Linux containers.
74+
75+
```bash
76+
# 1. Install tart
77+
brew install cirruslabs/cli/tart
78+
79+
# 2. Build sluice
80+
go build -o sluice ./cmd/sluice/
81+
82+
# 3. Start with macOS VM runtime
83+
./sluice --runtime macos \
84+
--vm-image ghcr.io/cirruslabs/macos-sequoia-base:latest \
85+
--container-name openclaw \
86+
--phantom-dir /tmp/sluice-phantoms
87+
88+
# 4. Host network routing (requires root for pf rules)
89+
sudo ./scripts/macos-vm-setup.sh
8190
```
8291

83-
## Policy Store
92+
Requires macOS with Apple Silicon (M1+). The macOS EULA allows up to 2 additional macOS VMs per Apple-branded host.
8493

85-
All runtime policy state is stored in a SQLite database (default: `sluice.db`). TOML files are used only for initial seeding via `sluice policy import`. The CLI, Telegram commands, and approval buttons all write to the same database. Changes persist across restarts.
94+
## Policy
8695

87-
### TOML Seed File Format
96+
All policy is stored in SQLite and persists across restarts. Seed from TOML on first run, then manage via CLI or Telegram.
8897

8998
```toml
9099
[policy]
91-
default = "deny" # "allow", "deny", or "ask"
92-
timeout_sec = 120 # timeout for ask verdicts
93-
94-
[vault]
95-
provider = "age"
96-
97-
# Network rules (destination field)
100+
default = "deny"
98101

102+
# Network rules
99103
[[allow]]
100104
destination = "api.anthropic.com"
101105
ports = [443]
102106

103-
[[allow]]
104-
destination = "*.github.com" # glob: * matches within one DNS label
105-
ports = [443, 80]
106-
107-
[[deny]]
108-
destination = "169.254.169.254" # block metadata endpoint
109-
110107
[[ask]]
111108
destination = "*.openai.com"
112109
ports = [443]
113110

114-
# Tool rules (tool field)
111+
[[deny]]
112+
destination = "169.254.169.254" # block cloud metadata
115113

114+
# MCP tool rules
116115
[[allow]]
117116
tool = "github__list_*"
118-
name = "read-only github list"
119117

120118
[[deny]]
121119
tool = "exec__*"
122-
name = "block all exec"
123-
124-
# Content inspection rules (pattern field)
125120

121+
# Content inspection
126122
[[deny]]
127123
pattern = "(?i)(sk-[a-zA-Z0-9_-]{20,})"
128-
name = "api key in tool arguments"
124+
name = "block API keys in tool arguments"
129125

130126
[[redact]]
131127
pattern = "(?i)(sk-[a-zA-Z0-9_-]{20,})"
132-
replacement = "[REDACTED_API_KEY]"
133-
name = "api key in responses"
128+
replacement = "[REDACTED]"
129+
name = "redact API keys in responses"
134130
```
135131

136-
Rules use a unified format. Each `[[allow]]`, `[[deny]]`, `[[ask]]`, or `[[redact]]` entry carries exactly one of: `destination` (network rule), `tool` (MCP tool rule), or `pattern` (content inspection rule). The section name determines the verdict.
137-
138-
Glob patterns: `*` matches within a single DNS label (not across dots). `**` matches across dots (any depth of subdomains). `?` matches a single non-dot character. Matching is case-insensitive (RFC 4343). An empty ports list matches all ports.
132+
Glob patterns: `*` matches within a single DNS label. `**` matches across dots. Evaluation order: deny, allow, ask, default.
139133

140-
Evaluation order: deny rules first, then allow, then ask, then the default verdict.
134+
## Credential Providers
141135

142-
## Telegram Approval Bot
136+
Sluice supports multiple credential backends. Set `provider` in `[vault]` config:
143137

144-
When configured, connections matching `ask` policy rules trigger an approval request via Telegram. The bot sends an inline keyboard message to the configured chat with three options: Allow Once, Always Allow, and Deny.
138+
| Provider | Auth | Notes |
139+
|----------|------|-------|
140+
| `age` (default) | Auto-generated X25519 key | Local encrypted files, no dependencies |
141+
| `env` | Environment variables | Credential name maps to env var |
142+
| `hashicorp` | Token or AppRole | HashiCorp Vault KV v2 |
143+
| `1password` | Service Account token | Via official Go SDK |
144+
| `bitwarden` | Access token | Via `bws` CLI |
145+
| `keepass` | Password + optional key file | Local .kdbx files, auto-reloads on change |
146+
| `gopass` | CLI auth | Via `gopass` binary |
145147

146-
The connection blocks until the user responds or the timeout expires (controlled by `timeout_sec`, default 120s). On timeout, the connection is denied.
148+
Chain multiple providers with `providers = ["1password", "age"]`. First provider with the credential wins.
147149

148-
"Always Allow" writes a persistent allow rule to the SQLite store with `source="approval"`. The rule survives restarts.
150+
## Telegram Bot
149151

150-
Without Telegram configured, all `ask` verdicts are treated as `deny`.
151-
152-
### Telegram Commands
153-
154-
Commands are only accepted from the configured chat ID.
152+
Manage sluice from your phone. Approve connections, add credentials, update policy.
155153

156154
| Command | Description |
157155
|---------|-------------|
158156
| `/policy show` | List current rules |
159-
| `/policy allow <dest>` | Add allow rule (persisted to SQLite) |
160-
| `/policy deny <dest>` | Add deny rule (persisted to SQLite) |
161-
| `/policy remove <id>` | Remove rule by ID |
162-
| `/cred add <name> <value>` | Add credential |
163-
| `/cred list` | List credential names |
164-
| `/cred rotate <name> <value>` | Replace credential |
165-
| `/cred remove <name>` | Remove credential |
166-
| `/status` | Show proxy status |
167-
| `/audit recent [N]` | Show last N audit entries (default 10) |
168-
| `/help` | Show available commands |
169-
170-
Policy changes via Telegram are persisted to the SQLite store and survive restarts.
171-
172-
## Hot Reload
173-
174-
Send SIGHUP to recompile the policy engine from the SQLite store without restarting the proxy. Existing connections are not affected. New connections use the updated policy. SIGHUP also updates the policy engine used by Telegram command handlers.
175-
176-
Telegram bot credentials are read from environment variables (`TELEGRAM_BOT_TOKEN`, `TELEGRAM_CHAT_ID`) at startup and cannot be hot-reloaded. Changing Telegram credentials requires a full restart.
177-
178-
```bash
179-
kill -HUP $(pgrep sluice)
180-
```
157+
| `/policy allow <dest>` | Add allow rule |
158+
| `/policy deny <dest>` | Add deny rule |
159+
| `/cred add <name>` | Add credential (value sent as next message, auto-deleted) |
160+
| `/cred rotate <name>` | Replace credential, hot-reload agent |
161+
| `/status` | Proxy stats and pending approvals |
162+
| `/audit recent [N]` | Last N audit entries |
181163

182164
## Audit Log
183165

184-
JSON Lines format written to the audit file path. Each line includes a `prev_hash` field with the blake3 hash of the previous line for tamper detection. Verify the chain with:
166+
Tamper-evident JSON Lines log with blake3 hash chaining. Every connection, tool call, approval, and denial is recorded.
185167

186168
```bash
187-
sluice audit verify
169+
sluice audit verify # check hash chain integrity
188170
```
189171

190-
## Docker Compose
191-
192-
Three-container architecture: sluice + tun2proxy + openclaw. All agent traffic is routed through sluice's SOCKS5 proxy via TUN device. Phantom tokens are delivered to the agent via a shared volume (`sluice-phantoms`). See `compose.yml` for details.
193-
194-
## Apple Container
195-
196-
Apple Container (macOS Virtualization.framework micro-VMs) is supported as an alternative to Docker. It provides native macOS isolation with access to Apple frameworks (EventKit, Messages, CallKit) that Linux containers cannot reach.
197-
198-
```bash
199-
./sluice --runtime apple --container-name openclaw
200-
```
201-
202-
Traffic routing uses macOS pf rules to redirect VM bridge traffic through tun2proxy on the host to sluice's SOCKS5 proxy. APNS traffic (port 5223) is detected as a distinct protocol for policy rules.
203-
204-
See `docs/apple-container-quickstart.md` for full setup instructions.
172+
## Protocol Support
205173

206-
## Standalone Mode
174+
| Protocol | Credential Injection | Content Inspection |
175+
|----------|---------------------|--------------------|
176+
| HTTP/HTTPS | MITM phantom swap | Full request/response |
177+
| gRPC | Header phantom swap | Metadata |
178+
| WebSocket | Handshake + text frames | Text frame content |
179+
| SSH | Jump host, key from vault | -- |
180+
| IMAP/SMTP | AUTH command proxy | -- |
181+
| DNS | -- | Domain-level policy |
182+
| QUIC/HTTP3 | HTTP/3 MITM | Full request/response |
207183

208-
Run sluice as a proxy without any container runtime:
209-
210-
```bash
211-
./sluice --runtime none --listen 127.0.0.1:1080
212-
```
213-
214-
Then configure your application to use the proxy:
215-
216-
```bash
217-
export ALL_PROXY=socks5://localhost:1080
218-
```
219-
220-
Credential injection (MITM proxy) and MCP gateway work normally. Only container lifecycle management is disabled.
221-
222-
## Testing
223-
224-
```bash
225-
make test # unit tests
226-
make test-coverage # unit tests with HTML coverage report
227-
make test-e2e # all e2e tests
228-
make test-e2e-docker # Linux e2e tests via Docker Compose (builds containers)
229-
make test-e2e-linux # Linux e2e tests (go test with linux build tag)
230-
make test-e2e-macos # macOS e2e tests (Apple Container)
231-
```
232-
233-
E2e tests use build tags (`e2e`, `linux`, `darwin`) and live in `e2e/`. CI enforces a minimum 75% coverage threshold.
184+
## Requirements
234185

235-
See [CONTRIBUTING.md](CONTRIBUTING.md) for details on writing tests.
186+
| Runtime | Requirements |
187+
|---------|-------------|
188+
| Docker | Docker Engine |
189+
| Apple Container | macOS, `container` CLI |
190+
| macOS VM | macOS, Apple Silicon, `tart` CLI |
191+
| All | Telegram bot token (optional, for approval flow) |
236192

237-
## Requirements
193+
## License
238194

239-
- Go 1.22+
240-
- Telegram bot token (from @BotFather) for the approval flow (optional)
241-
- Docker (optional, for container deployment)
242-
- macOS with Apple Container runtime (optional, for Apple Container deployment)
195+
See [LICENSE](LICENSE).

0 commit comments

Comments
 (0)