Skip to content

security(agent-rbac): deny mother-agent cross-namespace wallet keystore reads#602

Merged
OisinKyne merged 2 commits into
mainfrom
chore/agent-sa-wallet-scope
Jun 5, 2026
Merged

security(agent-rbac): deny mother-agent cross-namespace wallet keystore reads#602
OisinKyne merged 2 commits into
mainfrom
chore/agent-sa-wallet-scope

Conversation

@bussyjd
Copy link
Copy Markdown
Contributor

@bussyjd bussyjd commented Jun 5, 2026

What

Scopes the default (mother) agent's secrets access so it can no longer read other namespaces' wallet keystores.

The gap

hermes-agent-factory-write (bound to the default agent SA) granted cluster-wide secrets get/patch — so the mother agent could read any namespace's remote-signer-keystore / -password (every other agent's private key) plus the LiteLLM master key. The mother agent is intended to be privileged (it spawns + monitors child agents — reading their logs / litellm / the master key is by design), but reading arbitrary wallet keystores is not.

Fix

Wallet keys are only ever served via the in-namespace remote-signer REST API (port 9000) — never read through the k8s secrets API by any agent flow. So secrets get/patch is restricted to a resourceNames allow-list; create stays open (it cannot read or overwrite an existing wallet):

  • allow: litellm-secrets, x402-buyer-admin, hermes-api-server, hermes-profile-seed, hermes-env, ca-certificates
  • denied (by omission): remote-signer-keystore, remote-signer-keystore-password, anything else

Preserved — verified with kubectl auth can-i on a live cluster

litellm-secrets (master key) ✅ yes
hermes-profile-seed (factory idempotent create) ✅ yes
other agents' pods/log (admin monitoring) ✅ yes
secrets create (factory child seeding) ✅ yes
remote-signer-keystore in another ns 🔒 no
blanket secrets get 🔒 no

Test

embed_crd_test.go now asserts the factory secrets get is resourceNames-restricted and excludes wallet keystores. go test ./internal/embed/ ✓ · go build ./cmd/obol ✓.

Scope

One template file + one test assertion. Independent of #600; applies cleanly on main.

bussyjd added 2 commits June 5, 2026 20:10
… wallet reads

The default (mother) agent's hermes-agent-factory-write ClusterRole granted
cluster-wide secrets get/patch, letting it read any namespace's remote-signer
wallet keystore. Wallet keys are only ever served via the in-namespace
remote-signer REST API (never the k8s secrets API), so restrict secrets get/patch
to a resourceNames allow-list (litellm-secrets, x402-buyer-admin, hermes-api-server,
hermes-profile-seed, hermes-env, ca-certificates) and keep create open. The mother
keeps its admin reads (logs, litellm, master key) and the agent-factory keeps
working; only cross-namespace wallet keystore reads are denied. embed_crd_test
now asserts this.
…crets allow-list

ca-certificates is a ConfigMap (x402 ns), populated by the host CLI, never read
by the agent via the k8s secrets API; allow-listing the name was pointless and a
latent risk (a future TLS CA *secret* by that name often holds the CA private
key). x402-buyer-admin (buyer admin token) is likewise not read by any agent
flow. Allow-list is now the minimal set the agent/factory actually touches:
litellm-secrets, hermes-api-server, hermes-profile-seed, hermes-env.
@OisinKyne OisinKyne force-pushed the chore/agent-sa-wallet-scope branch from 125bfab to ac2cbf7 Compare June 5, 2026 18:10
@OisinKyne OisinKyne enabled auto-merge (rebase) June 5, 2026 18:11
@OisinKyne OisinKyne merged commit a3ef52f into main Jun 5, 2026
8 checks passed
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.

2 participants