Repository navigation
[BUG] API-exposed authentication modes fail with gateway credential injection #2873
Description
After #2868 switched runtime credentials to Substrate v0.2.0-beta4 gateway injection, several authentication modes exposed by the public API can no longer be compiled. Gateway bindings support static HTTP headers; the affected modes need credentials inside the runtime for signing or token exchange.
Affected components: harness compilation, ModelConfig/Harness APIs, model-provider discovery, and UI configuration.
Authentication modes broken by the merge
All resource field paths below refer to kagent.dev/v1alpha3.
| Authentication mode | API fields that enable it | Current failure / affected harnesses |
|---|---|---|
| AWS Bedrock IAM / SigV4 | ModelConfig.spec.provider: Bedrock, spec.bedrock.region, and spec.apiKeySecret referencing AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, optionally AWS_SESSION_TOKEN |
kagent, BYO, Claude, and Codex generate secret-backed signing environment variables that the shared credential compiler rejects. There is no separate authentication-mode field; the Secret contents select this path. Bedrock bearer-token authentication through AWS_BEARER_TOKEN_BEDROCK remains supported. |
| Google service-account authentication for Claude on Vertex AI | ModelConfig.spec.provider: AnthropicVertexAI, spec.anthropicVertexAI, spec.apiKeySecret, and spec.apiKeySecretKey referencing service-account JSON |
Claude generates KAGENT_CLAUDE_GOOGLE_CREDENTIALS_JSON for its GOOGLE_APPLICATION_CREDENTIALS flow; the shared credential compiler rejects this secret-backed environment variable. |
| SAP AI Core OAuth client credentials | ModelConfig.spec.provider: SAPAICore, spec.sapAICore.{baseUrl,resourceGroup,authUrl}, and spec.apiKeySecret containing client_id and client_secret |
kagent/BYO generate SAP_AI_CORE_CLIENT_ID and SAP_AI_CORE_CLIENT_SECRET; the shared credential compiler rejects them. apiKeySecretKey is not used for this provider. SAP caller-token passthrough remains implemented, so this is specifically the client-credentials path. |
| Arbitrary runtime secret environment variables | Harness.spec.env[].credentialRef.{name,key,optional} |
The shared compiler rejects every credentialRef, across all harness compilers, regardless of the variable name. The field is still accepted by the CRD schema. |
The shared compiler reports errors such as:
environment credential "AWS_SECRET_ACCESS_KEY" cannot use gateway header injection; local signing and arbitrary secret environment variables are unsupported
For Harness credential references:
Harness environment "<name>": arbitrary credentialRef values cannot be injected into HTTP headers; configure credentials on ModelConfig or RemoteMCPServer
Related API paths already unsupported before this merge
These are current failures, but were not introduced by #2868:
- Google service-account authentication in kagent/BYO:
ModelConfig.spec.provider: GeminiVertexAIorAnthropicVertexAI, the correspondingspec.geminiVertexAI/spec.anthropicVertexAIblock, andspec.apiKeySecret/spec.apiKeySecretKey. These paths construct a Secret volume and setGOOGLE_APPLICATION_CREDENTIALSto a file under/creds. Compilation already rejected the required volume mounts. The forms without a Secret can compile and rely on ambient Google credentials; that does not establish that authentication works in the provisioned runtime. - GDCH service-account token exchange:
ModelConfig.spec.provider: OpenAI,spec.openAI.tokenExchange.type: GDCHServiceAccount,spec.openAI.tokenExchange.gdchServiceAccount.audience, andspec.apiKeySecret/spec.apiKeySecretKey. This also requires a credential-file mount already rejected by kagent/BYO compilation. - Custom upstream CA Secret mounts:
ModelConfig.spec.tls.caCertSecretRef/caCertSecretKeyandRemoteMCPServer.spec.tls.caCertSecretRef/caCertSecretKey. kagent/BYO reject the volume requirements. Native model compilers reject TLS configuration; native MCP compilers ignore it with a compatibility warning. This is not a claim that every TLS field is rejected in every harness.
API surfaces still exposing these modes
- Kubernetes
ModelConfigprovider enum, provider-specific configuration blocks, and credential fields. - Kubernetes
Harness.spec.env[].credentialRef. ModelService.ListSupportedModelProvidersandListSupportedModelsstill list the Vertex and SAP providers without describing these runtime authentication restrictions.ModelService.CreateModelConfigandUpdateModelConfigexpose a genericresourceplusapi_key/secretsinputs through which these configurations can be submitted. The restrictions are encountered during compilation rather than expressed in those request schemas.- The UI still exposes these provider choices, Secret references, and custom CA fields.
Scope and evidence
This report is based on a source and pre-merge history audit at 850c4647, not live cloud-provider authentication tests.
Ordinary OpenAI, Anthropic, Azure OpenAI, Foundry, and Gemini API-key bindings, Bedrock bearer tokens, and Secret-backed MCP headers remain implemented. The failures above do not imply that every authentication mode of each named provider is broken.
Relevant source:
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsBacklog
Activity
yashrajshuklaaa commentedon Sep 20, 2026
@EItanya I'd like to work on this if it's still free.
I've read through the code and this is what I'd propose for a first PR. ResolveModelConfig already feeds SemanticFailures into the Accepted condition on ModelConfig, so I could report the unsupported modes there (Bedrock IAM keys, SAP client credentials, Vertex with an apiKeySecret, GDCH) as Accepted=False with reason UnsupportedCredentialMode. Right now users only see a generic error on the AgentTemplate that names an env var, not the ModelConfig.
I haven't written any code yet. Before I start, three questions:
If that works, could you assign it to me?
QuentinBisson commentedon Sep 22, 2026
One more mode belongs in the table, though #2868 did not break it, since it never existed upstream: a skill or plugin source on a private git repository. The materialiser clones with the process environment and no helper, so
spec.skills[].source.gitandspec.plugins[].source.gitcannot point at a private repository. It needs the same decision as the rows above: a credential inside the runtime (a git credential helper reading a Secret-backed variable, which the shared compiler now rejects), or a gateway binding for the source host. #2899 is a draft of the second shape,credentialRefper source compiled toAuthorization: Basicfor the host. A Harness-level list of host bindings would cover it as well, together with any other static header an admitted agent needs, if that is the direction you take for this issue.QuentinBisson commentedon Oct 15, 2026
For the Bedrock IAM and Vertex rows: we route both through the egress-side gateway rather than carrying signing credentials into the runtime. Vertex works for us with a credential provider that mints a Google access token from the service-account key at fetch time (the shape of #2888 and kagent-dev/substrate#47, carried in our fork), so the compiler binds
authorization: Beareron the Vertex hostname to that provider's authority and Claude Code runs withCLAUDE_CODE_SKIP_VERTEX_AUTH=1. Bedrock with IAM keys we do not bind per ModelConfig at all: the LLM gateway (agentgateway's Bedrock provider with an assumed role) takes Anthropic-format requests, so agents keep an Anthropic ModelConfig. If a maintainer wants the Vertex binding upstream, the provider side belongs in a plugin provider rather than the reference Kubernetes provider; happy to file it that way.