Skip to content

MCPServer spec.secrets list-map-keys=[name] makes two keys from one Secret unrepresentable #6686

Closed

Description

@lightsabit

The 0.49.0 CRDs declare spec.secrets as x-kubernetes-list-type: map with x-kubernetes-list-map-keys: [name], but every entry is a per-key reference {name, key, targetEnvName} (name and key both required).

The operator's env builder (cmd/thv-operator/pkg/controllerutil/podtemplatespec_builder.go, WithSecrets) maps each entry to one secretKeyRef env var, so referencing several keys of the SAME Secret is the intended use — but with the merge keys on [name] alone that shape is unrepresentable: any CR listing two entries with the same secret name fails server-side apply/dry-run with duplicate entries for key [name="..."]. Mine (one Secret, five keys) fails exactly that way against the 0.49.0 CRDs; the same manifest was fine against 0.0.106, which had no list-type markers.

A CR-side workaround (splitting one Secret into N single-key Secrets) is ugly, so I patched the CRD's list-map-keys to [name, key] via a post-renderer — everything else about the schema works, and the operator code already treats entries as per-key.

Affects both served versions (v1alpha1 and v1beta1) and is still on main.

Activity

  1. Sanskarzz commented on Sep 28, 2026

    @Sanskarzz
    Collaborator

    @lightsabit Thanks for raising this and including the failure details.

  2. lightsabit commented on Sep 28, 2026

    @lightsabit
    ContributorAuthor

    Minimal repro (trimmed from a live MCPServer whose login is a username/password pair held in a single Secret — the most natural way two keys end up in one Secret):

    apiVersion: toolhive.stacklok.dev/v1beta1
    kind: MCPServer
    metadata:
      name: secrets-repro
    spec:
      image: example/mcp-server:latest # any image — secrets is the relevant part
      transport: stdio
      secrets:
        - name: shared-secret
          key: username
        - name: shared-secret
          key: password
    kubectl apply --server-side --dry-run=server -f repro.yaml

    Against the 0.49.0 CRDs (and current unfixed main) both writes are rejected — captured from an envtest apiserver with the unfixed CRDs installed:

    create:  MCPServer.toolhive.stacklok.dev "secrets-repro" is invalid: spec.secrets[1]: Duplicate value: {"name":"shared-secret"}
    apply:   .spec.secrets: duplicate entries for key [name="shared-secret"]
    

    With the [name, key] merge keys from #6690 the object is admitted (created (server dry run)), both entries stored; an exact duplicate pair (name and key equal) is still rejected, with duplicate entries for key [key="username",name="shared-secret"] — the composite key visible in the error itself.

  3. added a commit that references this issue on Sep 30, 2026
    47dbcab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

needs-triageIssue needs initial triage by a maintainer

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions