Problem
Coder's External Auth system has two mechanisms for providing tokens to workspaces:
GIT_ASKPASS — The agent intercepts git credential requests and fetches a fresh token from coderd on every operation. This auto-refreshes seamlessly.
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
- 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.
PROMPT_COMMAND shell hook — Refresh the env var before every interactive command. Adds latency and doesn't cover non-interactive/background processes.
- 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.
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:
-
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"
}
-
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.
-
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
Problem
Coder's External Auth system has two mechanisms for providing tokens to workspaces:
GIT_ASKPASS— The agent intercepts git credential requests and fetches a fresh token from coderd on every operation. This auto-refreshes seamlessly.data.coder_external_auth.*.access_tokenin 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:ghCLIterraform(for GitHub provider)kubectlpluginsOnce the static token expires, all of these tools break within the running workspace until the user rebuilds or manually intervenes.
Current workarounds
coder external-auth access-token <provider>before invoking the real binary (this is what the Coder dogfood template does forgh). This doesn't scale — every tool needs its own wrapper.PROMPT_COMMANDshell hook — Refresh the env var before every interactive command. Adds latency and doesn't cover non-interactive/background processes.direnv— Dynamic.envrcevaluation, 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:
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.:
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.
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_ASKPASSalready works — the agent acts as a transparent credential broker — but extended to arbitrary environment variables.Impact
Created on behalf of @jatcod3r