pocketcoder runs model-driven code in isolated workspaces. The security model starts from one assumption: anything a workspace can read will eventually be read — by the coding agent debugging itself, by code the agent writes, or by a prompt-injected turn. Agents dump their environment into transcripts, and transcripts are durable. Design so that none of this matters.
There is no security boundary inside a workspace. The harness, its plugins and hooks, and every process the agent spawns share one uid, one filesystem, and one environment — and harnesses load executable configuration (MCP server definitions, hooks) from the workspace the agent writes to, so even a harness-vs-tools split would not hold. Treat the whole workspace as a single zone with the agent's authority, and place controls at its edges: the control channel, the egress firewall, and the deployment's model gateway.
Interactive terminal access does not add caller-supplied command execution.
The immutable template selects one command, cwd, and environment; callers with
terminal:attach can only exchange PTY input, output, and resize messages
with that command. Use a separate terminal:read scope for session audit
metadata. PocketCoder records who opened a session, timestamps, exit status,
and byte counts, but never persists terminal content.
A leaked credential is an incident only if it outlives or out-scopes the place it leaked from. The rule for every credential a workspace can read:
- One door — it works against exactly one endpoint (e.g. the deployment's model gateway), nowhere else.
- No extra authority — presenting it grants nothing beyond what the workspace's declared policy already allows.
- Dies with the workspace — it expires or is revoked at teardown, so there is nothing to rotate after a compromise.
What this prevents is not hypothetical: given a standing gateway bearer in its environment, a workspace agent has re-encoded an uploaded document as images and POSTed them directly to the model endpoint — bypassing the harness's text-only request path — and printed the bearer itself into the durable transcript while debugging. Every part of that is ordinary agent behavior. The only mistake was the credential's lifetime and scope.
Hiding a credential from the agent does not substitute for scoping it. A supervisor that holds a hidden token and attaches it automatically hands the agent the same authority with less friction — the channel is the capability, not the token. Scope the channel; assume the token is public within the workspace.
| Credential | Holder | Lifetime rule |
|---|---|---|
Machine keys (pcd keys issue) |
Operator backends, never workspaces | Prefer --expires <ISO8601> plus rotation; --expires never is for deliberate operational choices, not examples or ephemeral runs |
| Workspace registration secret | Supervisor | Single-use, spent at connect |
| Reconnect credential | Supervisor | Memory-only, never touches the workspace filesystem |
Git/source credentials (secretRef:) |
Setup process (memory-only) | Delivered at registration, consumed during create-time setup, cleared before the harness starts |
| Model gateway credential | Workspace | Per-workspace, minted at launch, dead at teardown — never a shared or standing bearer |
PocketCoder core does not operate a shared model gateway. A deployment provides one, and it is the only place provider API keys exist. The repository includes a single-session example; a multi-workspace service can instead use a dedicated gateway such as agentgateway. Because the workspace is one trust zone, the gateway must not assume requests come from the harness — agent-written code can reach it with the same credential. Enforce policy per workspace identity so that this does not matter:
- allowed models, and modalities (reject image parts for text-only use — this alone blocks the document-exfiltration replay above);
- request size and rate limits;
- a hard token budget per workspace;
- per-request attribution and audit.
When the envelope is identical for every caller inside the workspace, direct gateway use stops being an escalation: it is capability-equivalent to the harness's own turns. That is the goal — make misuse worthless, not impossible.
The residual risk no gateway removes: data the model legitimately reads can leave inside legitimate turns. Size, rate, and budget limits bound it; audit exposes it; nothing eliminates it.
Classify by when the secret's authority is exercised, and by whom:
- By the platform at launch (clone credentials): deliver in memory over the control channel, consume during setup, gone before the harness starts — the same pattern launch input uses. Prefer this over any file mount.
- By the platform on request (a future push/publish flow): expose a narrow, policy-checked action the agent can invoke; the credential stays outside the workspace.
- By agent code at runtime (a database the code under test connects to): it cannot be hidden from the reader. Make the backing resource ephemeral and workspace-scoped instead, and revoke it at teardown.