Skip to content

Let credential_helper supply API keys and other secrets, not only DOCKER_TOKEN #4703

Description

@aheritier

Overview

Let credential_helper (in ~/.config/cagent/config.yaml) supply provider API keys and MCP tokens, not only DOCKER_TOKEN.

Motivation

"Credential helper" reads as the generic way to plug a secret store into docker-agent (as with git and Docker credential helpers), and the secrets guide described it that way until #4701. In the code it has only ever answered DOCKER_TOKEN (pkg/environment/credential_helper.go).

1Password users are covered by op:// references, which work in every source. Users of other stores (HashiCorp Vault, Bitwarden, pass, a corporate secrets daemon) have no equivalent. The macOS Keychain and pass sources were removed, so a generic helper would also be their natural replacement.

Use cases

# ~/.config/cagent/config.yaml
credential_helper:
  command: vault-get          # prints the secret for the name it receives
  variables: [ANTHROPIC_API_KEY, OPENAI_API_KEY, GITHUB_PERSONAL_ACCESS_TOKEN]

Proposed solution

Backward compatibility is the constraint. Existing helpers ignore their input and print the Docker token. Calling them for ANTHROPIC_API_KEY would send the Docker token as an API key. So serving other names must be opt-in:

  • New optional variables list (or "*"). Without it, behavior is unchanged: DOCKER_TOKEN only.
  • The requested name is passed to the command, as the final argument and/or a DOCKER_AGENT_SECRET_NAME env var (to decide).
  • Empty output or a non-zero exit means "not found": the chain falls through to the next source (Docker Desktop).
  • Cache results per process: the helper is spawned at most once per name, as the op:// resolver does.
  • op:// output is still resolved, since the helper sits inside the 1Password wrapper.
  • docker agent doctor reports credential-helper as the source.

Open questions:

  1. Explicit list vs "*": "*" spawns the helper for every unresolved lookup (MCP ${VAR} expansion, doctor checks), so an explicit list may be the safer default.
  2. Name passing: argument, env var, or a {name} placeholder in args (e.g. args: ["kv", "get", "secret/{name}"]).
  3. Keep one credential_helper block, or add a separate one (e.g. secret_helper) so the Docker-token helper and an API-key helper can coexist?

Alternatives

Related issues

Activity

  1. added
    area/configFor configuration parsing, YAML, environment variables
    status/needs-designRequires architectural discussion or design review
    kind/featPR adds a new feature (maps to feat:). Use on PRs only.
    area/securityAuthentication, authorization, secrets, vulnerabilities
    area/mcpMCP protocol, MCP tool servers, integration
    area/providersFor features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.)
    on Oct 22, 2026
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

    area/configFor configuration parsing, YAML, environment variablesarea/mcpMCP protocol, MCP tool servers, integrationarea/providersFor features/issues/fixes related to LLM providers (Bedrock, LiteLLM, Qwen, custom, etc.)area/securityAuthentication, authorization, secrets, vulnerabilitieskind/featPR adds a new feature (maps to feat:). Use on PRs only.status/needs-designRequires architectural discussion or design review

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions