Skip to content

[Bug]: atelet credential-provider configuration is hard-coded to GKE host paths #2669

Open
kagent-dev/substrate
#88

Description

@skamboj

What happened?

Since PR #917, the base atelet DaemonSet always passes --image-credential-provider-config and --image-credential-provider-bin-dir.

These are populated from GKE-specific host paths:

  • /home/kubernetes/bin, mounted as DirectoryOrCreate
  • /etc/srv/kubernetes/cri_auth_config.yaml, mounted as FileOrCreate

On vanilla Kubernetes nodes, these paths may not exist or the node's credential provider may be installed elsewhere.

DirectoryOrCreate creates an empty plugin directory. If /etc/srv/kubernetes exists, FileOrCreate creates an empty configuration file. Atelet rejects that file because it is not a valid CredentialProviderConfig and exits. If the parent directory does not exist, the pod instead fails during volume setup.

The Kind overlay avoids this by removing the credential-provider arguments and mounts. Other installations have no supported configuration for disabling the GKE paths or supplying alternative volume sources, so they must patch the DaemonSet.

Expected Behavior

The vanilla Kubernetes installation should:

  • Start atelet with anonymous image pulls when no credential provider is configured.
  • Allow operators to supply a CredentialProviderConfig and its provider executable through supported installation settings.
  • Allow provider executables to be delivered through a container image and pod-local shared storage, such as an init or sidecar-style container copying them into an emptyDir mounted by atelet. Installing binaries on every node or sharing host directories should not be required.
  • Keep hostPath-based providers, including the current GKE paths, as optional platform-specific configuration rather than the default.

Steps to Reproduce

  1. Use a non-GKE Kubernetes cluster whose nodes do not contain the GKE credential-provider paths.

  2. Deploy without the Kind profile:

    go run ./cmd/ate-setup deploy ate-system \
      --credential-provider='{"enabled":false}'
  3. Inspect the atelet pods:

    kubectl -n ate-system get pods -l app=atelet
    kubectl -n ate-system describe pods -l app=atelet
    kubectl -n ate-system logs daemonset/atelet
    
  4. Observe either a hostPath volume setup failure or atelet exiting while loading the empty credential-provider configuration.

Sandbox Runtime

Both / Runtime Agnostic

Agent Substrate Version / Commit SHA

22863c3

Kubernetes Version & Environment

On-prem Kubernetes 1.36.0, Ubuntu 24.04 nodes, containerd 2.2.3. Not GKE or Kind.

Host OS & Architecture

No response

Relevant Logs and Diagnostic Output

Additional Context

Atelet already supports anonymous pulls when --image-credential-provider-config is unset. The Kind overlay uses this behavior by deleting both credential-provider arguments and mounts.

The credential-provider interface itself accepts configurable paths, but the supplied manifests and installer do not expose a way to populate those paths from operator-selected volumes.

A provider container image backed by a shared emptyDir would provide a portable option for vanilla Kubernetes while retaining hostPath mounting for environments where the provider is intentionally installed on each node.

Confirmation

  • I have searched existing issues and verified that this is not a duplicate.
  • I have verified that this issue occurs on the latest commit on main.

Activity

  1. BenTheElder commented on Oct 17, 2026

    @BenTheElder
    Collaborator

    Start atelet with anonymous image pulls when no credential provider is configured.

    That already exists.

    Allow operators to supply a CredentialProviderConfig and its provider executable through supported installation settings.

    You can use a kustomize overlay, like kind

    Allow provider executables to be delivered through a container image and pod-local shared storage, such as an init or sidecar-style container copying them into an emptyDir mounted by atelet. Installing binaries on every node or sharing host directories should not be required.

    You can do this with a custom atelet manifest / overlay / image.

    Keep hostPath-based providers, including the current GKE paths, as optional platform-specific configuration rather than the default.

    I don't think we should remove it as the default, it's lower friction. We can add more common paths to the default mount by making them optional directory mounts.

  2. BenTheElder commented on Oct 17, 2026

    @BenTheElder
    Collaborator

    Ah right, can't do a truly optional hostpath.

    Well ... cc Steven Shriver (@stshrive) something else to consider for your installer revamp doc. We'll need to customize this in the chart etc.

    In the meantime, the accepted solution is to kubectl kustomize the manifest.

  3. stshrive commented on Oct 17, 2026

    @stshrive
    Collaborator

    5. Ah right, can't do a truly optional hostpath.
    Well ... cc Steven Shriver (@stshrive) something else to consider for your installer revamp doc. We'll need to customize this in the chart etc.

    Thanks for bringing this to my attention. I'm in the middle of scoping out all of the areas that will need updates so this will be included as well.

  4. marcellodesales commented on Oct 17, 2026

    @marcellodesales

    Following the direction in this thread (make the credential-provider wiring work off GKE rather than hard-coding the node paths), I opened #2799. It's an opt-in kustomize component, components/image-credential-secret:

    • the provider plugin is installed from its image into an emptyDir by an init container, so there are no host paths;
    • the CredentialProviderConfig comes from a ConfigMap;
    • credentials come from a kubernetes.io/dockerconfigjson Secret, through a small cmd/dockerconfig-credential-provider plugin.

    It doesn't change atelet itself, any API or the proto. It's proven by a two-phase e2e on the kind install against a private GHCR repo, with a fresh digest each run: refused without the Secret (UNAUTHORIZED: authentication required in atelet's log), pulled with it.

    The Helm-chart side for kagent-dev/substrate is kagent-dev#88 (atelet.imageCredentialProviderPlugins / imageCredentialProviderSecrets). cc Steven Shriver (@stshrive) in case you'd rather fold this into the installer revamp; happy to reshape it into settings there.

    (Prepared with AI assistance; I verified it on our CI and production cluster and will handle review myself.)

  5. BenTheElder commented on Oct 17, 2026

    @BenTheElder
    Collaborator

    Marcello DeSales (@marcellodesales) as evidenced by the comments above, a design is being prepared for the installer, which was discussed at the community meeting Thursday and is in the meeting notes and other open issues.

    I don't think we want to add MORE non-tenant-scope secrets right ahead of GA and the right installer approach is an open thread.

  6. marcellodesales commented on Oct 17, 2026

    @marcellodesales

    Benjamin Elder (@BenTheElder) sounds good... No worries... I just wanted to move forward as we are preparing our product and we've been testing substrate in our requirements... I hope to make to the upcoming meetings...

    Can you please also point me to the thread you are referring to? I tried to follow most of the threads here...

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

Metadata

Metadata

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions