feat(auth): client_credentials proxy auth mode for service accounts#170
Merged
Conversation
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)
Contributor
Contributor
🔭 Langfuse traces |
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.
This was referenced Jun 11, 2026
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
client_credentialsauth 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)credentials/proxy.auth.username/password(with${ENV}substitution) and fail-fast validationPANDA_ON_BEHALF_OFenv →X-Panda-On-Behalf-Ofrequest 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
pkg/proxy/client_credentials_test.go: cache hit, expiry re-mint, 401-then-retry, no-retry-loop, mint-outage fallbackpkg/auth/client