Problem
The current configurator only creates a GitHub Device Flow token with read:user scope.
This token is written to the cloud-init as GITHUB_TOKEN and is sufficient for AI agents (Copilot, OpenCode, Codex CLI) to authenticate against GitHub.
However, Coder's native GitHub integration (called external_auth) is never set up.
Without it, workspace users cannot:
- Authenticate with GitHub to
git clone private repos
- Push commits / create PRs from within the workspace
- Have Coder's UI show a "Connect GitHub" button that auto-provisions per-user GitHub tokens via OAuth
Because the deployed environment was configured this way, there is currently no way to connect GitHub at the Coder level — users land in a workspace with no git credentials for private repos.
Root cause
The configurator flows in cli.py / oauth.py only handle the AI-agent token path:
oauth.py — _GH_DEFAULT_SCOPE = "read:user" (line ~176)
cli.py — _ask_github_token_oauth() requests only this narrow scope; the resulting token is stored as GITHUB_TOKEN for agent use only
generator.py / main.tf — no CODER_EXTERNAL_AUTH_* variables are generated or injected into the Coder systemd unit
Desired behaviour
The configurator should offer a second, optional step after the agent-token step:
"Do you want to enable full GitHub OAuth for your Coder workspaces (allows git clone/push from workspaces)?"
If the user says yes:
- Prompt for a GitHub OAuth App Client ID and Client Secret with the required scopes (
repo, read:user, read:org).
Display a link + instructions to register the app at https://github.com/settings/applications/new with:
- Homepage URL:
https://<coder-url> (or the server IP for IP-only deployments)
- Callback URL:
https://<coder-url>/external-auth/github/callback
- Validate that Client ID / Secret are non-empty (and optionally test the app exists).
- Write the following into the generated config and cloud-init:
CODER_EXTERNAL_AUTH_0_TYPE=github
CODER_EXTERNAL_AUTH_0_CLIENT_ID=<client_id>
CODER_EXTERNAL_AUTH_0_CLIENT_SECRET=<client_secret>
CODER_EXTERNAL_AUTH_0_SCOPES=repo read:user read:org
- Inject those env vars into the Coder systemd unit in
setup.sh / main.tf (alongside the existing CODER_ACCESS_URL, GITHUB_TOKEN, etc.).
Affected files
dev-server-provision/configurator/oauth.py — document that Device Flow only covers agent auth; add helpers for validating OAuth App credentials
dev-server-provision/configurator/cli.py — add optional "full GitHub OAuth" step after agent-token step
dev-server-provision/configurator/generator.py — add github_oauth_client_id / github_oauth_client_secret fields to default_config(), key-order, and cloud-init template
dev-server-provision/configurator/validators.py — add validate_github_oauth_client_id / validate_github_oauth_client_secret
dev-server-provision/setup.sh — inject CODER_EXTERNAL_AUTH_* env vars into Coder systemd unit when present
dev-server-provision/coder/main.tf — expose CODER_EXTERNAL_AUTH_* in startup script environment block
dev-server-provision/docs/deployment.md — document the GitHub OAuth App registration steps
Acceptance criteria
Problem
The current configurator only creates a GitHub Device Flow token with
read:userscope.This token is written to the cloud-init as
GITHUB_TOKENand is sufficient for AI agents (Copilot, OpenCode, Codex CLI) to authenticate against GitHub.However, Coder's native GitHub integration (called
external_auth) is never set up.Without it, workspace users cannot:
git cloneprivate reposBecause the deployed environment was configured this way, there is currently no way to connect GitHub at the Coder level — users land in a workspace with no git credentials for private repos.
Root cause
The configurator flows in
cli.py/oauth.pyonly handle the AI-agent token path:oauth.py—_GH_DEFAULT_SCOPE = "read:user"(line ~176)cli.py—_ask_github_token_oauth()requests only this narrow scope; the resulting token is stored asGITHUB_TOKENfor agent use onlygenerator.py/main.tf— noCODER_EXTERNAL_AUTH_*variables are generated or injected into the Coder systemd unitDesired behaviour
The configurator should offer a second, optional step after the agent-token step:
If the user says yes:
repo,read:user,read:org).Display a link + instructions to register the app at
https://github.com/settings/applications/newwith:https://<coder-url>(or the server IP for IP-only deployments)https://<coder-url>/external-auth/github/callbacksetup.sh/main.tf(alongside the existingCODER_ACCESS_URL,GITHUB_TOKEN, etc.).Affected files
dev-server-provision/configurator/oauth.py— document that Device Flow only covers agent auth; add helpers for validating OAuth App credentialsdev-server-provision/configurator/cli.py— add optional "full GitHub OAuth" step after agent-token stepdev-server-provision/configurator/generator.py— addgithub_oauth_client_id/github_oauth_client_secretfields todefault_config(), key-order, and cloud-init templatedev-server-provision/configurator/validators.py— addvalidate_github_oauth_client_id/validate_github_oauth_client_secretdev-server-provision/setup.sh— injectCODER_EXTERNAL_AUTH_*env vars into Coder systemd unit when presentdev-server-provision/coder/main.tf— exposeCODER_EXTERNAL_AUTH_*in startup script environment blockdev-server-provision/docs/deployment.md— document the GitHub OAuth App registration stepsAcceptance criteria
RVSconfig.ymland cloud-init contain theCODER_EXTERNAL_AUTH_*variablesGITHUB_TOKENis set)