Bridge API

Endpoint reference, request gating, environment variables, audit events

Cockpit Bridge API Reference

The Bridge is a single loopback HTTP server (default `127.0.0.1:8140`). This page documents its surface as implemented. All `/api/*` routes pass four gates before dispatch; see Trust & Security for the model.

GateFailure
Loopback, same-port browser origin403 `forbidden_origin`
Bearer token (`Authorization: Bearer …` or `?token=`), constant-time compare401 `unauthorized`
CSRF header `x-cockpit-csrf` = token, for mutating verbs with an Origin403 `csrf_required`
Real-executor assertion (mock refused unless explicitly allowed)502 `mock_executor_refused`

`GET /healthz` is the one unauthenticated route (shell liveness probe). Unhandled upstream failures return 502 `bridge_upstream_error`.

Endpoints

Health

Method & pathPurpose
`GET /healthz`Unauthenticated liveness (`{status:'ok'}`)
`GET /api/health`Bridge health + config echo (`executor_url`, `mock_executor_allowed`)
`GET /api/executor/capabilities`Deep-probe the executor (`host_runtime_enabled`, raw status; `unreachable` on failure)

Events & telemetry

Method & pathPurpose
`GET /api/events`Server-Sent Events stream — `cockpit.refresh` on connect, heartbeat every 5s. (The Bridge serves no WebSocket; pty streams go browser→executor.)
`GET /api/events/snapshot`Unified event model v1 — typed events aggregated from inventory, running, approvals, missions, sessions
`GET /api/running`Running board, derived from per-instance A2A task lists (not an executor admin route)
`GET /api/missions`Mission Control projection — merges durable `aiwg mc` disk state with the live executor task session

Inventory & instances

Method & pathPurpose
`GET /api/inventory`Normalized instance inventory (runtime/transport/daemon posture per instance); agent-registry fallback; degraded envelope instead of hard failure
`GET /api/loadouts`Loadout catalog passthrough
`POST /api/instances`Launch a runtime target via the executor's v2 admin API. `runtime:'qemu'` requires a resolvable SSH public key (400 `ssh_public_key_required` / `ssh_public_key_not_found`)
`GET /api/operations/:id`Poll an async provisioning operation
`POST /api/instances/:id/start` · `/stop`Lifecycle
`POST /api/instances/:id/reconnect`Stale-agent recovery — full semantics in Recovery
`DELETE /api/instances/:id`Destroy, with Docker-CLI reconciliation and already-gone synthesis (Recovery)
`POST /api/tasks/:instanceId/:taskId/cancel`Cancel an A2A task

Sessions

Method & pathPurpose
`GET /api/sessions?instance=`List sessions; each row carries a normalized `attach_url` for the direct browser→executor pty WebSocket
`POST /api/instances/:id/sessions`Create a session (`mode`, `backend`, `loadout` query params). Recovers an in-flight create by name on timeout; 409 `agent_not_registered` when no agent
`DELETE /api/instances/:id/sessions/:sessionId`End a session
`GET /api/instances/:id/sessions/:sessionId/screen`Screen snapshot (404 `session_screen_unavailable` when the backend has no screen)

Approvals

Method & pathPurpose
`GET /api/approvals?status=`HITL inbox derived from A2A `input-required` / `hitl-prompt/v1` tasks (default `pending`)
`POST /api/approvals/:id?decision=approve\deny`Decide; `:id` is `instanceId::taskId`; posted via the A2A respond surface

Cost

`GET /api/cost`Spend passthrough (executor `/admin/cost`)

Catalog, index, contributions

These shell out to the AIWG CLI (read-only):

Method & pathPurpose
`GET /api/capabilities?q=&limit=&type=``aiwg discover` (limit 1–50; type `all\skill\agent\command\rule\flow`)
`GET /api/show?path=` or `?type=&name=`Artifact body; path access is corpus-sandboxed (400 `path_outside_corpus`), name resolution can 409 `ambiguous_artifact`
`GET /api/contributions`Validated declarative UI contribution manifests
`GET /api/index/status` · `GET /api/index/query?...` · `POST /api/index/rebuild`Artifact-index operations (`aiwg index`)

Library

Method & pathPurpose
`GET /api/library`List operator-owned assets under `~/.aiwg/cockpit/library`
`POST /api/library/clone?type=&name=&path=`Clone a catalog asset into the library (201; refuses existing destinations)
`DELETE /api/library/:name`Remove (path-sandboxed; 404 `not_in_library`)

The library invariant: catalog reads are read-only and AIWG install files are never written — the library holds copies the operator owns.

Audit

Method & pathPurpose
`GET /api/audit?limit=`Tail of the redacted audit log (1–200, default 50)
`POST /api/audit/intent`Record an operator intent event (the web UI logs `action.inject.requested` through this)

Static

`/` serves the built web app with the per-launch token injected (`window.__COCKPIT_TOKEN__`) and a `SameSite=Strict` CSRF cookie; other paths serve hashed, immutable-cached assets from the web build, path-sandboxed. A legacy fallback page renders when no web build is present.

Environment variables

The Bridge is configured entirely by environment (no CLI flags):

VariableDefaultEffect
`AIWG_COCKPIT_EXECUTOR_URL` (alias `EXECUTOR_URL`)`http://127.0.0.1:8122`Upstream executor
`PORT` / `AIWG_COCKPIT_BRIDGE_PORT``8140`Listen port; refuses the executor-reserved 8120–8122
`AIWG_COCKPIT_AUTOSTART_EXECUTOR`on`0` disables best-effort executor autostart
`AIWG_COCKPIT_EXECUTOR_COMMAND`Pin the autostart command (otherwise an installed `agentic-mgmt` is tried)
`AIWG_COCKPIT_ALLOW_MOCK_EXECUTOR`off`1` permits the automated-test mock (Development)
`AIWG_COCKPIT_AUDIT_DIR``~/.aiwg/cockpit/audit`Audit log location
`AIWG_COCKPIT_CONTRIB`Additional contribution-manifest directory, layered after first-party
`AIWG_COCKPIT_AGENT_CACHE_TTL_MS``5000`Agent-list cache TTL
`AIWG_ROOT`Extra corpus root for `/api/show` path resolution
`AIWG_COCKPIT_KEYCHAIN_STRICT`off`1`: never persist a plaintext token when a keychain ref exists; fail launch if the keychain fails
`AIWG_COCKPIT_REQUIRE_KEYCHAIN`off`1`: fail launch if the keychain store fails
`AIWG_COCKPIT_KEYCHAIN_DISABLED`off`1`: skip OS keychain entirely
`AIWG_COCKPIT_ENABLE_KWALLET` / `AIWG_COCKPIT_KWALLET`off / `kdewallet`Opt-in KWallet backend and wallet name

Dev-launcher variables (`AIWG_COCKPIT_ENSURE_EXECUTOR`, `AIWG_COCKPIT_START_HOST_DAEMON`, e2e/UAT knobs) are covered in Development.

Audit events

Written as redacted JSONL to `~/.aiwg/cockpit/audit/events.jsonl` (file 600, dir 700). Secret-looking keys and values (tokens, API keys, bearer strings) are redacted before write. Events:

`instance.launch.requested` / `instance.launch.result` · `instance.lifecycle.requested` (start/stop) · `instance.reconnect.requested` · `instance.destroy.requested` · `task.cancel.requested` · `session.start.requested` · `approval.response.submitted` · `index.rebuild.requested` / `index.rebuild.completed` · operator intents via `/api/audit/intent` (the web UI records `action.inject.requested` for every action injection).

Executor compatibility

Upstream calls use candidate-list fallbacks to tolerate executor version skew (legacy `/admin/` and v2 `/api/v2/admin/` surfaces both probed; see Architecture). Snake_case and camelCase payloads are both normalized; unknown fields render as opaque posture rather than errors.