Skip to content

[BUG] Align v1alpha3 API fields with current Substrate and harness support #3258

Open

Description

@EItanya

Several api.kagent.dev/v1alpha3 fields are still exposed even though the current Substrate or harness path ignores them, rejects them later in compilation, or cannot use them during startup. For example, setting RemoteMCPServer.spec.tls.disableVerify: true does not let an actor connect to a self-signed upstream because Substrate verifies that upstream certificate independently.

We should remove or defer fields with no supported runtime path, and reject unsupported combinations early for fields that work in some harnesses. This issue tracks the findings from the current API audit. The credential failures overlap with #2873, and artifact delivery overlaps with #2815.

Affected components: CRDs, controller compilation/discovery, Substrate preparation, and Go/Python/native harness consumers.

Fields to remove or defer

  • RemoteMCPServer.spec.tls and ModelConfig.spec.tls. The only served option is disableVerify. All compiled HTTPS destinations use Substrate's intercepting gateway, including destinations without credentials. The flag changes certificate verification inside the actor, but the gateway makes a separate upstream connection and still validates the origin certificate. No upstream TLS configuration reaches that gateway. Controller MCP discovery and MCP Apps also ignore spec.tls; Codex/Claude reject model TLS and warn when ignoring MCP TLS. Defer these blocks until upstream trust can be configured at the component that owns the connection. Update the documentation that currently describes compiler support as runtime support. Egress policy, actor trust setup, discovery client.

  • AgentTemplate skill/plugin source.git and source.bucket.s3. The compiler adds these destinations to the eventual session actor's egress, but package downloads happen during startup, before the golden actor is ready. Substrate creates that golden actor in ate-golden without an egress policy. A fresh installation therefore cannot complete those downloads through the standard preparation path; an image with a populated package cache can hide the failure. Defer these source variants until preparation has a supported acquisition path. Keep digest-pinned OCI sources, which Substrate mounts before runtime startup. Source compilation, Git/S3 fetch, Go startup. Related: [FEATURE] Private skill and plugin sources in the v1alpha3 API #2815.

  • RemoteMCPServer.spec.allowedNamespaces.{from,selector}. MCP bindings use TypedLocalObjectReference, and resolution always uses the template's namespace. AllowsNamespace has no production callers, so setting All or Selector cannot enable cross-namespace references. Remove the field and unused supporting types/helper. Binding resolution, helper.

  • ModelConfig.spec.azureOpenAI.azureAdToken. Translation emits the plaintext value as AZURE_AD_TOKEN, but neither current Azure runtime path consumes that variable. Go/Python select API-key, caller-token, or default Azure credential authentication instead. Remove the field and emitted value so an ineffective credential is not carried in the runtime environment and provenance. Translation, Go auth, Python auth.

  • ModelProviderConfig discovery configuration and status. The CRD still exposes spec.type, spec.endpoint, spec.secretRef, and discovery status, but there is no production reconciler/refresher implementation wired in. Refresh returns provider model refresher is not configured; non-refresh queries rely on status with no production writer here. Restore a supported discovery owner or defer the CRD and dependent discovery API. Service, production wiring.

Unsupported ModelConfig credential modes

spec.apiKeySecret and spec.apiKeySecretKey are still needed for supported gateway header injection. The problem is the modes that require credential files, local signing, or token exchange:

Configuration Current failure Follow-up
GeminiVertexAI / AnthropicVertexAI with a service-account Secret ADK translation produces Secret volumes and then rejects them at the ActorTemplate boundary. Claude emits a Secret environment reference rejected by credential compilation. Reject the unsupported mode during shared ModelConfig resolution. Defer provider support unless another authentication path is verified.
Bedrock with IAM keys in apiKeySecret Resolution accepts AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and optional AWS_SESSION_TOKEN, but credential compilation rejects local signing credentials. Reject IAM mode earlier. Keep AWS_BEARER_TOKEN_BEDROCK gateway injection.
SAPAICore OAuth client_id / client_secret Translation emits Secret environment references that credential compilation rejects, although the CRD documents this as the expected auth method. Defer the OAuth path and its advertised support. SAP caller-token passthrough also lacks a destination case in the current credential compiler, so it is not a verified replacement.
  • Align shared resolution, provider discovery, and public descriptions with the credential modes that actually work. Omitting credentials and relying on ambient Kubernetes workload identity is not a verified replacement: ActorTemplate does not transfer pod service accounts or projected cloud credentials into actors.

Shared resolution, credential compilation, ADK volume rejection. Related: #2873.

Fields that need harness/protocol compatibility enforcement

These have useful consumers, so the fix should preserve supported behavior while implementing or rejecting the unsupported combinations.

Field Current behavior
RemoteMCPServer.spec.timeout Go/Python and controller discovery consume it. Codex/Claude ignore it and warn for nondefault values.
RemoteMCPServer.spec.sseReadTimeout Python forwards it. Go applies it only to legacy SSE, not Streamable HTTP. Codex/Claude drop it without a compatibility warning.
RemoteMCPServer.spec.terminateOnClose Python forwards it. The ADK compiler emits it, but the Go registry never reads it. Codex/Claude ignore false with a warning.
RemoteMCPServer.spec.tokenPassthrough Go kagent supports it. Codex/Claude reject it during compilation; Python fails at startup. Move incompatible-runtime failure earlier where possible.
ModelConfig.spec.defaultHeaders, tokenPassthrough, and provider tuning options ADK supports these in various provider paths; Codex/Claude reject many explicitly. Make compatibility clear and preserve the working configurations. spec.stream already documents its kagent-only scope.
ModelConfig.spec.geminiVertexAI / anthropicVertexAI tuning ADK drops temperature, topP, topK, and stopSequences for both; also Gemini Vertex candidateCount / responseMimeType, and Anthropic Vertex maxTokens. Gemini Vertex maxOutputTokens is forwarded. Implement the missing translations or defer those fields if the provider path is retained.
AgentTemplate skills / plugins through the compiled agent_plugins contract Go, Codex, and Claude consume the contract; Python ADK does not yet. Preserve supported OCI behavior and reject unsupported runtime combinations.
  • Enforce the actual support matrix and stop silently accepting ineffective values.

Go MCP registry, Python connection parameters, Codex MCP compilation, Claude MCP compilation, Vertex translation.

Other contract mismatches

  • ModelConfig.status.secretHash: still maintained, but its documented restart role is obsolete. Revision identity uses Secret references, and the gateway owns credential rotation. No production Go/UI readers were found. Remove it or define a current status purpose. Writer.
  • Harness.spec.env / SandboxTemplate.spec.env: schemas admit up to 100 entries, while Substrate allows 32 total runtime entries, including platform-generated ones. Align validation/errors with the effective budget. ActorTemplate limit.
  • Model/MCP endpoint strings: the public schema accepts literal IPs, but compiled egress requires DNS names. Validate this earlier and explain the restriction. Origin validation.

Expected behavior and validation

Every served field should have a supported consumer, or fail early with a clear explanation for the chosen harness/provider/protocol. Remove/defer unsupported API surface at its source, regenerate the CRDs, and update affected discovery/UI/documentation rather than leaving options that cannot take effect. Add focused coverage for rejection paths and runtime coverage where behavior is implemented.

The audit used kagent 962ec4c5d5c01ce845315985e99e0cbe6f01ea5e and pinned Substrate v0.5.0-alpha2. Generated CRDs were checked, and focused compiler/credential/egress tests passed across five packages. The TLS and golden-actor download findings are based on source tracing, not live-cluster reproductions. In the pinned Substrate source, see manifests/ate-install/atenet-egress.yaml:972 for upstream certificate verification and cmd/ateapi/internal/controlapi/template_reconciler.go:421 for golden-actor creation.

Custom CA Secret fields (caCertSecretRef, caCertSecretKey, disableSystemCAs), runtime env[].credentialRef, openAI.tokenExchange, RemoteMCPServer status.secretHash, and dedicated subagent agentRef are already absent from served CRDs. They are not additional removal work for this issue.

Activity

  1. QuentinBisson commented on Oct 18, 2026

    @QuentinBisson
    Contributor

    @EItanya about the Vertex row: instead of rejecting it, could we go with #3259? The gateway sets the Vertex token, so the key never ends up in the runtime. Which credential provider handles it is a controller setting, k8s.io by default. We run it with our own provider that mints the token from a service account key: https://github.com/giantswarm/substrate-credential-providers (routed with kagent-dev/substrate#90). Bedrock IAM might come later. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions