Skip to content

feat(auth): client_credentials proxy auth mode for service accounts#170

Merged
samcm merged 3 commits into
masterfrom
qu0b/panda-client-credentials
Jun 11, 2026
Merged

feat(auth): client_credentials proxy auth mode for service accounts#170
samcm merged 3 commits into
masterfrom
qu0b/panda-client-credentials

Conversation

@qu0b

@qu0b qu0b commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

Adds a client_credentials auth mode to the proxy auth client so non-interactive deployments (the panda-chat Hermes bot) authenticate with an Authentik service account instead of seeded refresh-token credential files.

  • Client.ClientCredentials() POSTs the issuer token endpoint with Authentik's service-account form (grant_type=client_credentials + client_id + username + password)
  • In-memory token cache with 5-min pre-expiry re-mint; nothing written under credentials/
  • 401 → invalidate → re-mint → retry-once path; cached-token fallback across mint outages
  • Config gains proxy.auth.username/password (with ${ENV} substitution) and fail-fast validation
  • PANDA_ON_BEHALF_OF env → X-Panda-On-Behalf-Of request header for per-user attribution at the proxy audit layer (header-only; never used for authz)

The proxy itself is unchanged — Authentik-issued service-account tokens already verify against the existing issuer config.

Design context: ethpandaops/chat docs/identity-and-attribution-plan.md.

Test plan

  • New pkg/proxy/client_credentials_test.go: cache hit, expiry re-mint, 401-then-retry, no-retry-loop, mint-outage fallback
  • New fake-token-endpoint tests in pkg/auth/client
  • Full suite passes (30 packages)

qu0b added 2 commits June 10, 2026 13:33
panda-server can now authenticate to a hosted proxy non-interactively via
an Authentik service account: proxies[].auth.mode "client_credentials"
with issuer_url, client_id, username, and password (app password). Access
tokens are minted from the issuer's token endpoint using Authentik's
service-account form, cached in memory only, re-minted before expiry, and
re-minted+retried once when the proxy rejects a cached token (401/403).
No credential files are written; no refresh tokens are involved.
Chat agents acting for a human user set PANDA_ON_BEHALF_OF per
invocation; the CLI forwards it to panda-server as X-Panda-On-Behalf-Of
and the server passes all non-Authorization headers through to the
proxy. Untrusted free-text attribution for audit only — never used in
authorization decisions. (identity-and-attribution-plan.md B3)
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Eval Smoke

4 tests  ±0   4 ✅ ±0   2m 31s ⏱️ +4s
1 suites ±0   0 💤 ±0 
1 files   ±0   0 ❌ ±0 

Results for commit 87a48fe. ± Comparison against base commit a16cc83.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

go run ./scripts/ccsmoke with PANDA_SMOKE_USERNAME/PASSWORD exercises
the real chain: OIDC discovery, client_credentials mint (in-memory
cache reuse), datasource discovery, and a ClickHouse query through the
staging proxy. Verified passing with panda-ci-svc.
@samcm samcm merged commit 45365c8 into master Jun 11, 2026
11 checks passed
samcm added a commit that referenced this pull request Jun 11, 2026
…183)

PR #170 added the CLI side: PANDA_ON_BEHALF_OF becomes an
X-Panda-On-Behalf-Of header on CLI->server requests. The advertised
server->proxy forwarding was missing; the header dead-ended at
panda-server.

pkg/attribution owns the header/env constants and a context carrier.
Server middleware lifts the inbound header into the request context,
both proxy-bound request paths (generic datasource passthrough and
ClickHouseQuery) forward it, and the proxy auditor logs it as
on_behalf_of. Values stay audit-only free-text.
qu0b added a commit to ethpandaops/chat that referenced this pull request Jun 11, 2026
…redentials

Resolves the do-not-roll TODO: v0.32.0 ships ethpandaops/panda#170, so
images built from this tag work with panda-chat chart >= 0.2.0.
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