Skip to content

docs(security): RFC — per-agent remote-signer keystore isolation (follow-up to #570)#571

Closed
bussyjd wants to merge 1 commit into
mainfrom
security/per-agent-keystore-isolation
Closed

docs(security): RFC — per-agent remote-signer keystore isolation (follow-up to #570)#571
bussyjd wants to merge 1 commit into
mainfrom
security/per-agent-keystore-isolation

Conversation

@bussyjd
Copy link
Copy Markdown
Collaborator

@bussyjd bussyjd commented May 29, 2026

Summary

Design RFC (no controller code yet) for the isolation follow-up that #570 explicitly defers. #570 scopes the controller's Secret access to three names, but a name-scoped ClusterRole still matches remote-signer-keystore in any namespace — so the controller can read every agent's keystore + password. This RFC captures the verified custody flow and a recommended path out.

Full doc: plans/per-agent-keystore-isolation.md

Verified custody flow (code-level)

  • Keys are minted in the controller processopenclaw.GenerateKeystoreInMemory() (internal/openclaw/wallet.go:136).
  • remote-signer:v0.3.0 only consumes a mounted keystore; no evidence it self-generates.
  • Post-mint the controller reads only the address annotation, but GET on the Secret returns the key + password too, so the standing capability is the real exposure.

Two sub-risks

  1. Standing cross-agent read — a compromised controller GETs every agent's keystore → drains every agent wallet.
  2. In-process custody at mint — the controller holds each private key + password at provisioning time, regardless of RBAC.

Options (full tradeoffs in the doc)

Option Verdict
0 — Accept + document Honest fallback, not the goal
A — Per-namespace Role for the controller SA ❌ Rejected — isolation theater (controller manages all agents, binds itself everywhere)
B — Agent self-mints; controller leaves custody path Recommended
C — Unique per-agent names Only useful layered onto B

Recommendation

Option B, phased: in-pod keystore generation → namespaced Role for the agent SA + address-via-Agent.status → drop remote-signer-keystore from the controller ClusterRole (+ guard test).

Open questions (gate Phase 1)

  1. Can remote-signer:v0.3.0 self-generate a keystore on first boot (empty keystore dir)? If not → init-container mint tool.
  2. Is Agent.status.walletAddress the right address channel, with the agent SA granted namespaced patch on agents/status?
  3. Anything besides the remote-signer pod consuming the keystore Secret directly?

🤖 Generated with Claude Code

Follow-up to PR #570 (controller Secret RBAC scoping), which scopes the
controller's keystore access by name but cannot isolate one agent's keystore
from another's: all agents share the Secret name remote-signer-keystore, and a
name-scoped ClusterRole matches that name in any namespace.

Captures the verified custody flow (controller mints keys in-process via
openclaw.GenerateKeystoreInMemory; standing cluster-wide GET on every agent's
keystore + password), the threat model, four options (rejecting the
"per-namespace Role for the controller SA" approach as isolation theater), and
recommends Option B: move keystore minting into the agent pod so the controller
leaves the signer-key custody path entirely.

No controller code yet -- gated on open questions about remote-signer self-mint
capability and the address-reporting channel.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@bussyjd
Copy link
Copy Markdown
Collaborator Author

bussyjd commented May 30, 2026

Superseded by #573 — the per-agent keystore isolation design now lives as a diagram-rich tracking issue (decoupled from any code branch) so it can be discussed and scheduled independently. The immediate RBAC hardening remains in #570. Branch security/per-agent-keystore-isolation is left intact for reference.

@bussyjd bussyjd closed this May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant