feat: --vks-auth passthrough — every VKS call runs as the caller#40
Merged
Conversation
added 2 commits
July 14, 2026 14:35
The AgentBase Gateway now forwards the inbound user's IAM bearer token in the Authorization header (replacing gateway->server auth). In passthrough mode the server uses THAT token for every VKS/vServer call — per-user projects, permissions, and results, instead of the shared service account. - mcp-core: user_token_var contextvar (request-scoped, safe under concurrency) + current_identity() (short sha256, never the raw token). BaseClient sends the user token when set; a rejected user token (401) raises immediately and NEVER retries with the service account (privilege confusion). - vks: --vks-auth service-account|passthrough (env GRN_MCP_VKS_AUTH). UserTokenPassthroughMiddleware requires a Bearer token on every request (401 + WWW-Authenticate otherwise; /health stays open) and scopes it to the request context. Fail-fast on nonsensical combos: passthrough+stdio, passthrough+--auth-mode api-key (both would fight over the Authorization header). - Cache isolation per caller identity: DiscoveryCache prefixes every key; K8sClientCache keys (identity, cluster_id) — user A's kubernetes client is never served to user B; _require_project_id resolves and caches the project per (identity, region) and never lets a passthrough user inherit the service account's GRN_PROJECT_ID. - Bonus: cluster_locate had no TTL_CONFIG entry since the derive-zone work, so it was never actually cached — added (1800s). - Runtime-mode addendum states the VKS identity (PASSTHROUGH per-user vs shared service account); docs drop "per-user is a future phase". Verified end-to-end over real streamable-http: tokenless request -> 401; real IAM token in Authorization -> initialize + list_clusters through the forwarded-token code path. 278 + 18 tests.
…ics) - vks README: GRN_MCP_VKS_AUTH in the env table, an HTTP-transport example, and an "Upstream VKS identity" section separating inbound auth (who may call the server) from upstream identity (whose credentials hit VKS). - vks CLAUDE.md: passthrough example in the server-flags block. - mcp-core README: http module row notes user_token_var/current_identity.
vks-team
force-pushed
the
feat/user-token-passthrough
branch
from
July 14, 2026 07:36
90c53d0 to
1b28bcf
Compare
added 3 commits
July 14, 2026 16:09
…ount, else 401 Simplification decided in review: the AgentBase Gateway forwards the caller's IAM token in Authorization, so the server needs exactly one rule, no flags: 1. Request carries a Bearer token -> every VKS/vServer call runs as THAT caller (per-user projects/permissions; a rejected user token is surfaced, never retried as the service account; caches isolated per caller identity). 2. No token, service-account credentials configured (~/.greenode or GRN_CLIENT_ID/GRN_CLIENT_SECRET) -> the shared service account. 3. Neither -> 401 + WWW-Authenticate. Removed: --auth-mode (none/api-key/jwt), --api-key, the five --jwt-*/ --resource-url flags, BearerTokenMiddleware, the auth_verifier module (+ its tests), --vks-auth/GRN_MCP_VKS_AUTH, GRN_MCP_API_KEY and GRN_MCP_JWT_* env vars. Kept: --auth-debug diagnostics. New: the server boots credential-less on the HTTP transport (passthrough-only deployments behind the Gateway; boot note printed); stdio without credentials fails fast with a clear message. The runtime-mode addendum describes the per-request identity. Docs rewritten around the single behavior. BREAKING CHANGE: --auth-mode/--api-key/--jwt-* CLI flags and the GRN_MCP_API_KEY/GRN_MCP_JWT_*/GRN_MCP_VKS_AUTH env vars are gone; deployments using api-key/jwt inbound auth must drop those settings. Verified E2E over streamable-http: with token (per-user path), without token (service-account fallback), and credential-less boot -> 401.
This was referenced Jul 14, 2026
Merged
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.
What
Per-user VKS access (phase 2). The AgentBase Gateway now forwards the inbound user's IAM bearer token in
Authorization(replacing gateway→server auth); with--vks-auth passthroughthe server uses that token for every VKS/vServer call — per-user projects, permissions, and results.Design (as decided in review)
Authorization→ incompatible combos fail fast (passthrough+stdio,passthrough+--auth-mode api-key).serviceotherwise):DiscoveryCacheprefixes every key (one choke point covers all 8 discovery tools + cluster locate)K8sClientCachekeys(identity, cluster_id)— user A's kubernetes client can never serve user B_require_project_idresolves + caches per(identity, region); a passthrough user never inherits the service account'sGRN_PROJECT_IDAlso
cluster_locatehad no TTL entry since feat!: list_flavors/list_volume_types derive region+zone from cluster_id+subnet_id #27 — it was never actually cached; now 1800s.Verification
/healthopen; a real IAM token inAuthorization→ initialize (addendum shows PASSTHROUGH) +list_clustersreturns data through the forwarded-token path.Remaining before rollout: one real request through the AgentBase Gateway once deployed (contract measured earlier with --auth-debug).