Skip to content

Feature: Agent-managed auto-refreshing environment variables for External Auth tokens #24003

@blinkagent

Description

@blinkagent

Problem

Coder's External Auth system has two mechanisms for providing tokens to workspaces:

  1. GIT_ASKPASS — The agent intercepts git credential requests and fetches a fresh token from coderd on every operation. This auto-refreshes seamlessly.
  2. data.coder_external_auth.*.access_token in Terraform — The token is resolved once at workspace build time and injected as a static environment variable (e.g., GITHUB_TOKEN). This does not auto-refresh.

Many non-git tools depend on environment variables like GITHUB_TOKEN, GH_TOKEN, etc. to authenticate. Examples include:

  • gh CLI
  • terraform (for GitHub provider)
  • kubectl plugins
  • Custom CI/CD scripts
  • Language-specific package managers that pull from private registries
  • AI coding agents that interact with GitHub APIs

Once the static token expires, all of these tools break within the running workspace until the user rebuilds or manually intervenes.

Current workarounds

  1. Per-tool wrapper scripts — Write a shell wrapper for each tool that calls coder external-auth access-token <provider> before invoking the real binary (this is what the Coder dogfood template does for gh). This doesn't scale — every tool needs its own wrapper.
  2. PROMPT_COMMAND shell hook — Refresh the env var before every interactive command. Adds latency and doesn't cover non-interactive/background processes.
  3. Background cron/loop — Periodically write a fresh token to a file or env var. Existing shells don't pick up the new value without re-sourcing.
  4. direnv — Dynamic .envrc evaluation, but only triggers on directory changes.

None of these are seamless or scalable.

Proposed Solution

The Coder agent should natively manage a set of environment variables that are kept fresh via the coderd External Auth API. Possible approaches:

  1. Agent-managed env vars — The agent periodically refreshes external auth tokens and updates environment variables in all child processes (shells, IDE terminals, etc.). This could be configured in the template, e.g.:

    resource "coder_external_auth_env" "github" {
      agent_id    = coder_agent.dev.id
      provider_id = "github"
      env_name    = "GITHUB_TOKEN"
    }
  2. Local token proxy/socket — Similar to SSH agent forwarding, provide a local endpoint (Unix socket or localhost HTTP) that tools can query for fresh tokens. This would require tool-side support but is the most robust approach.

  3. Token file with inotify — The agent writes fresh tokens to a well-known file path, and a thin shim or shell integration sources it. Less invasive than modifying running process environments.

Approach (1) feels most natural since it mirrors how GIT_ASKPASS already works — the agent acts as a transparent credential broker — but extended to arbitrary environment variables.

Impact

  • Any workspace using external auth with expiring tokens (GitHub Apps with 8h expiry, Azure/Entra ID with 1h expiry, GitLab, Gitea, etc.) is affected
  • The current guidance to use wrapper scripts per-tool is not scalable for teams with diverse toolchains
  • This gap is especially painful for AI coding agents and automation that run non-interactively inside workspaces

Created on behalf of @jatcod3r

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions