docs: document hostd API proxy architecture for jail agents
The hostd-bridge now routes through the controlplane API instead of direct Unix socket. 6 files updated: - ARCHITECTURE.md: jail isolation section — hostd via API, no socket mount - doc/CONTROLPLANE-ARCHITECTURE.md: hostd tree shows API proxy route - doc/CONTROLPLANE-MESSAGE-CONTRACT.md: add POST /api/controlplane/hostd endpoint with request/response examples - docs/public/operate/security.md: hostd section describes HTTP proxy model with CONTROLPLANE_SHARED_SECRET auth - .env.example: document CONTROLPLANE_HOST_IP (default 10.0.1.1) - doc/HANDOFF-ISO-AGENT.md: add sections 4 (hostd API proxy) and 5 (legacy agent ID removal) to breaking changes Build: pass | Tests: not run (Linux) (Sam & Claude)
This commit is contained in:
parent
cac8b4ae05
commit
8010ab3b3c
6 changed files with 49 additions and 0 deletions
|
|
@ -190,6 +190,8 @@ CONTROLPLANE_NAME=clawdie
|
|||
CONTROLPLANE_DAILY_TOKENS=100000
|
||||
CONTROLPLANE_PORT=3100
|
||||
CONTROLPLANE_BIND_HOST=0.0.0.0
|
||||
# IP address that jailed agents use to reach the host API (default: 10.0.1.1).
|
||||
# CONTROLPLANE_HOST_IP=10.0.1.1
|
||||
CONTROLPLANE_AUTH_MODE=local_trusted
|
||||
# Shared secret for agent-to-API Bearer token auth (required for agent subprocesses).
|
||||
# Generate with: openssl rand -base64 32
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ Skills are injected as a compact index (~200 tokens) instead of full content (~1
|
|||
|
||||
When `CONTROLPLANE_JAIL_ISOLATION=YES`, specialist agents run inside dedicated thin jails. Each jail gets scoped secrets (DB creds for db-worker, SSH keys for git-worker) and restricted network access via PF. Feature flag defaults to `NO`.
|
||||
|
||||
Jail agents reach hostd **through the controlplane API** (`POST /api/controlplane/hostd`), not via direct Unix socket. The API authenticates the request and proxies to the hostd daemon. This means no socket mount is needed inside jails — only network access to `CONTROLPLANE_HOST_IP:CONTROLPLANE_API_PORT`.
|
||||
|
||||
## Split-Brain Database
|
||||
|
||||
All three databases run on the same PostgreSQL 18 instance, each with its own user and permissions:
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ HOST (osa)
|
|||
│
|
||||
├── hostd daemon (existing)
|
||||
│ └── Privileged ops (bastille, zfs, pf) via Unix socket
|
||||
│ └── API proxy: POST /api/controlplane/hostd (for jail agents)
|
||||
│
|
||||
└── PostgreSQL jail (10.0.0.3, existing)
|
||||
├── clawdie_ai_* tables (existing)
|
||||
|
|
|
|||
|
|
@ -122,6 +122,32 @@ Authorization: Bearer {CONTROLPLANE_SHARED_SECRET}
|
|||
}
|
||||
```
|
||||
|
||||
### 6. Proxy hostd Operation (jail agents)
|
||||
|
||||
Jail agents use this endpoint to execute privileged host operations (bastille, zfs, pf) through the controlplane API instead of direct Unix socket access.
|
||||
|
||||
```http
|
||||
POST /api/controlplane/hostd
|
||||
Authorization: Bearer {CONTROLPLANE_SHARED_SECRET}
|
||||
|
||||
{
|
||||
"op": "bastille-list",
|
||||
"params": {}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"output": "JID IP Address Hostname Path",
|
||||
"exitCode": 0
|
||||
}
|
||||
```
|
||||
|
||||
The API proxies the request to the hostd daemon on the host. Available ops match those in `src/hostd/privileged-commands.ts` (bastille-list, bastille-cmd, zfs-snapshot, etc.).
|
||||
|
||||
---
|
||||
|
||||
## Agent Posts
|
||||
|
|
|
|||
|
|
@ -56,6 +56,22 @@
|
|||
- rc.d service uses `run-${AGENT_NAME}.sh` written by `generateRunScript()`
|
||||
- ISO should run `just setup-service` which generates the correct script
|
||||
|
||||
### 4. hostd routed through controlplane API (cac8b4a)
|
||||
|
||||
- Jail agents no longer connect to hostd Unix socket directly
|
||||
- `hostd-bridge.ts` rewritten as HTTP client → `POST /api/controlplane/hostd`
|
||||
- API authenticates via `CONTROLPLANE_SHARED_SECRET`, proxies to hostd daemon
|
||||
- No socket mount needed in jails — only network access to host IP
|
||||
- New config var: `CONTROLPLANE_HOST_IP` (default `10.0.1.1`) — IP jails use to reach the API
|
||||
- Jail env `CONTROLPLANE_API_URL` now uses `http://${CONTROLPLANE_HOST_IP}:${CONTROLPLANE_API_PORT}` instead of `localhost`
|
||||
|
||||
### 5. Legacy agent IDs removed (0f7fbc4)
|
||||
|
||||
- 8 agents → 5 agents (removed `sysadmin`, `db-admin`, `git-admin` alias rows)
|
||||
- `resolveCanonicalAgentId()` removed — identity function since legacy IDs gone
|
||||
- `CANONICAL_AGENT_MAP` deleted, `AGENT_JAIL_MAP` trimmed to canonical IDs only
|
||||
- Role constraint in schema updated (removed legacy role values)
|
||||
|
||||
## What still works unchanged
|
||||
|
||||
- `.pi/extensions/clawdie-harness/skill-tools.ts` — self-contained, reads `/opt/skills` in jails
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ At runtime, privileged host operations from the agent go through `hostd`
|
|||
The agent user calls `hostd(op, params)`; the daemon validates params with Zod
|
||||
and runs the handler as root. Unknown ops and invalid params are rejected.
|
||||
|
||||
**Jail agents call hostd through the controlplane API** (`POST /api/controlplane/hostd`), not via direct socket. The extension's `hostd-bridge.ts` sends an HTTP request to the API, which authenticates via `CONTROLPLANE_SHARED_SECRET` and proxies to the hostd daemon. This eliminates the need to mount the Unix socket into jails — only network access to the host IP is required.
|
||||
|
||||
Shell injection prevention: `hostd` applies Zod regex validators on all
|
||||
string parameters in `src/privileged-commands.ts` — `jailName`, `datasetName`,
|
||||
`snapshotTag`, and `serviceName` must match strict patterns before any command
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue