Raised: $0
0% of monthly goal Help us cross the finish line!
Goal: $12,000
Raised: $0 Goal: $12,000
0% of monthly goal Help us cross the finish line!
Sponsor DDEV

If you find this add-on useful, please star it on GitHub — stars show appreciation and help maintainers know their work matters.

add-on registry tests last commit release

DDEV GitHub Copilot CLI

Overview

This DDEV add-on installs GitHub Copilot CLI inside the DDEV web container and automatically shares your host GitHub CLI and Copilot configuration — including authentication and Copilot settings — with no additional setup required.

Once installed, running copilot inside ddev ssh or ddev exec uses a writable copy of your host configuration and a token derived from your host gh authentication.

Requirements

Installation

ddev add-on get e0ipso/ddev-assistant-copilot
ddev restart

After installation, commit the .ddev directory to version control.

What it does

How authentication forwarding works

GitHub CLI stores your token in the OS keychain by default — macOS Keychain, GNOME Keyring (Secret Service) on Linux, Windows Credential Manager. It writes a plaintext oauth_token: into ~/.config/gh/hosts.yml only as a silent fallback when no keychain is reachable, such as on a headless server or WSL.

A container cannot reach the host keychain. So copying ~/.config/gh/ into the container and running gh auth token there only ever works on hosts that took the plaintext fallback. That is why forwarding used to succeed on headless Linux and fail on macOS and Linux desktops, and why selecting an account with DDEV_ASSISTANT_COPILOT_GH_USER could not help: the token was not in the file at all.

This add-on resolves the token on the host instead:

  1. A pre-start hook runs gh auth token on the host, honouring the configured hostname and user, and writes the result to ~/.ddev-assistant-copilot/<project>/token with mode 600.
  2. That directory is bind-mounted read-only into the container at ~/.cred-seed/auth/.
  3. Shell startup resolves a token in this order:
    1. COPILOT_GITHUB_TOKEN already present in the container environment
    2. the host-resolved token from the seed mount
    3. in-container gh auth token — still correct for hosts that legitimately use plaintext storage

The token is refreshed on every ddev start, so a rotated or revoked token is picked up by a restart.

Where the token does and does not go

The token is deliberately kept out of DDEV’s environment plumbing:

Note that inside the web container, PHP runs as the same user as copilot, so anything reachable by Copilot CLI is reachable by your application code. The practical benefit over an environment variable is that a file is not dumped by phpinfo(), Xdebug stack traces, or a Symfony/Whoops error page. If that residual exposure matters for your project, use ephemeral mode below.

Ephemeral tokens

To keep no token at rest at all, set this in .ddev/config.assistant-copilot.yaml:

web_environment:
  - DDEV_ASSISTANT_COPILOT_EPHEMERAL_TOKEN=true

ddev start then stages no token. Instead, run Copilot through the host command:

ddev copilot

This resolves a fresh token from the host keychain for that invocation and removes it when the session exits. The trade-off is that plain copilot inside ddev ssh is left unauthenticated and will prompt you to log in.

ddev copilot works in the default mode too, where it simply refreshes the token before starting the session.

Multi-account configuration

The add-on ships with this non-secret default:

web_environment:
  - DDEV_ASSISTANT_COPILOT_GH_HOSTNAME=github.com
  # - DDEV_ASSISTANT_COPILOT_GH_USER=your-github-username

Use this when you have multiple GitHub accounts, such as a personal account and a work account, authenticated for the same host. Uncomment and set DDEV_ASSISTANT_COPILOT_GH_USER in your installed .ddev/config.assistant-copilot.yaml to tell the add-on which account should provide COPILOT_GITHUB_TOKEN.

If either variable is empty or removed, the add-on does not pass that option to gh auth token, allowing GitHub CLI’s default account/host selection to apply.

Usage

# Run Copilot CLI with a token resolved fresh from the host keychain
ddev copilot

# Open a shell with Copilot CLI available
ddev ssh
copilot

# Run Copilot CLI non-interactively
ddev exec copilot --version

# GitHub CLI is also available, and authenticated
ddev exec gh auth status

Why not manual setup?

You can install Copilot CLI and gh inside a DDEV container yourself. This add-on automates the parts that are easy to get wrong or forget:

  This add-on Manual setup
GitHub CLI Installed in the image layer via official apt repo; on $PATH for every shell Must install and re-install after image rebuilds
Copilot CLI npm install -g @github/copilot on every start into ~/.local/bin Must run npm install manually; easy to lose on restart
Config approach Seeds writable container ~/.config/gh/ and ~/.copilot/ from your host config on restart — zero setup if you already use gh and Copilot on the host Must copy or symlink config by hand; stale container files persist
Authentication Token resolved on the host, so it works whether or not gh used the OS keychain; exported as COPILOT_GITHUB_TOKEN and GH_TOKEN without writing literal tokens into shell startup files, web_environment, or the project directory Copying ~/.config/gh only works on hosts without a keychain; otherwise you must export a token manually in every shell type
Non-interactive shells BASH_ENV=/etc/bash.env ensures ddev exec gets PATH and token ddev exec often misses PATH and env vars
Mount safety Pre-start hook ensures host config directories exist before Docker bind-mounts them Bind-mount fails silently or blocks start if dirs are missing
Tests / CI BATS integration tests, GitHub Actions CI matrix (DDEV stable + HEAD), daily scheduled runs No automated verification

This add-on does one thing: install GitHub Copilot CLI into your DDEV container and share your existing host configuration. Nothing else.

Credits

Contributed and maintained by @e0ipso

If you find this add-on useful, please star it on GitHub — stars show appreciation and help maintainers know their work matters.