Skip to content

feat(panda-chat)!: service-account bot identity + privileged sidecar split#481

Merged
qu0b merged 2 commits into
masterfrom
qu0b/panda-chat-client-credentials
Jun 11, 2026
Merged

feat(panda-chat)!: service-account bot identity + privileged sidecar split#481
qu0b merged 2 commits into
masterfrom
qu0b/panda-chat-client-credentials

Conversation

@qu0b

@qu0b qu0b commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

Chart 0.1.0 → 0.2.0, two breaking changes (design: ethpandaops/chat docs/identity-and-attribution-plan.md):

1. Bot identity via Authentik client_credentials (replaces seeded refresh-token credentials):

  • credentials.panda.{credentialsJson,credentialsFile}{botUsername,botToken} (both required when panda.enabled)
  • panda-config.yaml renders a proxy.auth block with mode: client_credentials against the Authentik issuer (trailing slash is part of the issuer); Dex default removed
  • seed-panda-creds initContainer deleted — tokens are minted on demand and live in memory only

2. Container split — hermes is never privileged:

  • hermes container: always unprivileged (uid 10000, caps dropped), no docker socket, no bot credential
  • panda-server sidecar (only when panda.enabled): privileged (dockerd), same image with panda-stack entrypoint arg, and the ONLY container that mounts the new dedicated <name>-panda-secret (PANDA_BOT_USERNAME/PANDA_BOT_TOKEN). Hermes executes LLM-driven shell commands, so it must never share an environment with the credential.
  • Hermes reaches the sidecar on 127.0.0.1:2480 (shared pod netns); sidecar probes are exec-based (server binds loopback)
  • Resources split: .resources → hermes, panda.resources → sidecar

Requires the hermes-agent-panda image with the dispatch entrypoint (ethpandaops/chat) built on a panda release that includes client_credentials (ethpandaops/panda#170) — do not roll to a devnet before both exist.

Verification

  • helm template (panda enabled): hermes privileged=False runAsUser=10000 envFrom=[hermes-secret]; panda-server privileged=True envFrom=[panda-secret]; secrets carry the right keys
  • helm template (panda disabled): single unprivileged container, no panda Secret
  • Missing botUsername/botToken fails with a clear required error
  • The client_credentials chain itself was live-tested against staging Authentik + proxy with the panda-ci service account (mint, cache reuse, ClickHouse query through the proxy)
  • README regenerated via helm-docs

qu0b added 2 commits June 11, 2026 14:20
…credentials

Replace the seeded-credentials bot identity (credentials.panda.credentialsJson
/ credentialsFile + seed-panda-creds initContainer) with an Authentik service
account: credentials.panda.botUsername / botToken materialize as
PANDA_BOT_USERNAME / PANDA_BOT_TOKEN, and panda-config.yaml now configures
proxy.auth mode client_credentials against the Authentik panda-proxy
application issuer (default panda.issuerUrl switches from Dex to Authentik;
the trailing slash is part of the issuer). panda-server mints access tokens
on demand and keeps them in memory — nothing is written under credentials/.

Both bot values are required when panda.enabled, so a values gap fails at
template time instead of producing a half-authenticated pod.

Requires a hermes-agent-panda image carrying panda with client_credentials
support. Part of chat docs/identity-and-attribution-plan.md (Phase 3).
Two-container pod: hermes always runs unprivileged (uid 10000, caps
dropped) and panda-server + dockerd move to a privileged sidecar that is
the only container holding PANDA_BOT_USERNAME/TOKEN — the credential gets
its own Secret so hermes' envFrom can no longer expose it to LLM-driven
shell execution. Hermes reaches the sidecar on 127.0.0.1:2480 via the
shared pod netns; sidecar probes are exec-based (server binds loopback).
Resources split: .resources -> hermes, panda.resources -> sidecar.
@qu0b qu0b force-pushed the qu0b/panda-chat-client-credentials branch from 7dca5ff to e8d4774 Compare June 11, 2026 12:21
@qu0b

qu0b commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

Rebased onto master (#479's .helmignore fix + 0.1.1 republish). Conflict resolution: chart version stays 0.2.0, appVersion keeps master's CalVer 2026.6.5 (the branch's stale 0.11.0 dropped). Re-verified post-rebase: split renders correctly (hermes unprivileged + hermes-secret only; panda-server privileged + panda-secret only). The matching image bump to panda v0.32.0 (first release with client_credentials) is on the chat PR.

@qu0b qu0b merged commit da4e85a into master Jun 11, 2026
14 checks passed
@qu0b qu0b deleted the qu0b/panda-chat-client-credentials branch June 11, 2026 13:15
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