# What Authentication Methods Are Supported for GitHub Copilot CLI in Subscription Mode

> Discover the 7 authentication methods for GitHub Copilot CLI subscription mode, including API tokens, PATs, GitHub CLI tokens, and more. Learn how Headroom validates your credentials.

- Repository: [Tejas Chopra/headroom](https://github.com/chopratejas/headroom)
- Tags: api-reference
- Published: 2026-06-07

---

**Headroom supports seven prioritized authentication sources for GitHub Copilot CLI subscription mode—including explicit API tokens, Copilot-specific and generic GitHub PATs, GitHub CLI tokens, OS credential stores, and Copilot config files—each validated against GitHub's Copilot user-info endpoint before use.**

Understanding what authentication methods are supported for GitHub Copilot CLI in subscription mode is essential for securely running `headroom wrap copilot --subscription`. The open-source `chopratejas/headroom` project centralizes all token discovery logic in [`headroom/copilot_auth.py`](https://github.com/chopratejas/headroom/blob/main/headroom/copilot_auth.py), where the `resolve_subscription_bearer_token()` function performs a prioritized search across environment variables, system credential stores, and JSON configuration files.

## How Subscription Token Discovery Works

In [`headroom/copilot_auth.py`](https://github.com/chopratejas/headroom/blob/main/headroom/copilot_auth.py), the `resolve_subscription_bearer_token()` function implements a two-phase lookup. It first scans environment variables designated for explicit API tokens, then iterates over OAuth-style candidates gathered from environment variables, the GitHub CLI, OS-specific credential managers, and Copilot config files.

```python

# headroom/copilot_auth.py

def resolve_subscription_bearer_token() -> str | None:
    """Return the first discovered token that GitHub accepts for Copilot
    subscription APIs."""
    for env_var in _API_TOKEN_ENV_VARS:                      # explicit token

        token = os.environ.get(env_var, "").strip()
        if token and _fetch_copilot_user_info(token) is not None:
            return token

    for candidate in iter_oauth_token_candidates():          # OAuth candidates

        if not candidate.validate_for_subscription:
            continue
        if _fetch_copilot_user_info(candidate.token) is not None:
            return candidate.token
    return None

```

Each candidate is deduplicated via `_dedupe_token_candidates()` and validated by calling `_fetch_copilot_user_info()`. Only a token that GitHub accepts for Copilot subscription APIs is returned. If no token passes, the routine returns `None` and the CLI surface emits an informative error.

## Authentication Methods Supported for GitHub Copilot CLI in Subscription Mode

The following sources are checked in strict priority order as implemented in [`headroom/copilot_auth.py`](https://github.com/chopratejas/headroom/blob/main/headroom/copilot_auth.py).

### Explicit API Tokens via Environment Variables

Headroom checks `_API_TOKEN_ENV_VARS` first:

- `GITHUB_COPILOT_API_TOKEN`
- `COPILOT_PROVIDER_BEARER_TOKEN`

When set, the token is validated via `_fetch_copilot_user_info()` and returned immediately if accepted, bypassing the broader OAuth candidate iteration.

### Copilot-Specific OAuth Environment Variables

Next, Headroom searches for reusable OAuth tokens in Copilot-specific variables:

- `GITHUB_COPILOT_GITHUB_TOKEN`
- `GITHUB_COPILOT_TOKEN`
- `COPILOT_GITHUB_TOKEN`

These are validated against the Copilot user-info endpoint (`/_copilot_internal/user`).

### Generic GitHub Personal Access Tokens

Standard GitHub PATs are also supported through `_GENERIC_GITHUB_TOKEN_ENV_VARS`:

- `GH_TOKEN`
- `GITHUB_TOKEN`

These are treated as OAuth candidates and must pass validation via `_fetch_copilot_user_info()`.

### GitHub CLI Token

If no environment token is found, Headroom invokes the GitHub CLI via `_read_gh_cli_oauth_token()`:

```bash
gh auth token

```

The resulting token is validated the same way before use.

### OS Credential Stores

Headroom reads from platform-specific secure storage:

- **Windows:** Credential Manager entry `copilot-cli/<host>`
- **macOS:** Keychain entry `copilot-cli`
- **Linux:** Secret Service entry `copilot-cli`

These lookups are handled by dedicated helpers such as `_read_windows_copilot_cli_oauth_token()`.

### Copilot Configuration Files

Finally, Headroom parses JSON configuration files under the user's Copilot config directory:

- `~/.config/github-copilot/apps.json` and [`hosts.json`](https://github.com/chopratejas/headroom/blob/main/hosts.json) (Unix-like)
- `%LOCALAPPDATA%\github-copilot\apps.json` and [`hosts.json`](https://github.com/chopratejas/headroom/blob/main/hosts.json) (Windows)

The `_read_file_oauth_token_candidates()` helper extracts an OAuth token matching the current host.

### Fallback on Failure

If none of the above sources yield a usable token, the command fails with the error:

```

subscription mode requires a reusable GitHub/Copilot bearer token

```

This behavior is asserted in [`tests/test_cli/test_wrap_copilot.py`](https://github.com/chopratejas/headroom/blob/main/tests/test_cli/test_wrap_copilot.py).

## Practical Code Examples

### Using an Explicit API Token

Set the variable and run the wrapper:

```bash
export GITHUB_COPILOT_API_TOKEN=ghp_your_token_here
headroom wrap copilot --subscription

```

Headroom discovers the token via `_API_TOKEN_ENV_VARS` and validates it directly.

### Using a Generic GitHub PAT

Use a standard GitHub token:

```bash
export GH_TOKEN=ghp_your_pat_here
headroom wrap copilot --subscription

```

Headroom discovers the token via `_GENERIC_GITHUB_TOKEN_ENV_VARS` and validates it.

### Using the GitHub CLI

Ensure you are logged in:

```bash
gh auth login
headroom wrap copilot --subscription

```

Headroom calls `gh auth token` internally through `_read_gh_cli_oauth_token()` and validates the output.

### Relying on OS Credentials and Config Files

Run without environment variables to rely on automatic discovery:

```bash
headroom wrap copilot --subscription

```

Headroom checks OS credential stores and Copilot config files through `iter_oauth_token_candidates()`.

## Summary

- Headroom supports **seven prioritized methods** to obtain a bearer token for Copilot CLI subscription mode.
- The entry point `resolve_subscription_bearer_token()` in [`headroom/copilot_auth.py`](https://github.com/chopratejas/headroom/blob/main/headroom/copilot_auth.py) drives all discovery.
- **Explicit API variables** (`GITHUB_COPILOT_API_TOKEN`, `COPILOT_PROVIDER_BEARER_TOKEN`) are checked first.
- **OAuth and generic PATs**, **GitHub CLI tokens**, **OS credential stores**, and **Copilot config files** serve as secondary sources.
- Every candidate is **validated** via `_fetch_copilot_user_info()`; subscription mode aborts if no token passes.

## Frequently Asked Questions

### Can I use a standard GitHub personal access token for Copilot subscription mode?

Yes. Headroom accepts generic PATs from `GH_TOKEN` or `GITHUB_TOKEN`. As implemented in [`headroom/copilot_auth.py`](https://github.com/chopratejas/headroom/blob/main/headroom/copilot_auth.py), these are validated against the Copilot user-info endpoint before being used for Copilot subscription API calls.

### What happens if multiple authentication sources are configured?

Headroom deduplicates candidates with `_dedupe_token_candidates()` and evaluates them in priority order. The first token that succeeds against `_fetch_copilot_user_info()` is returned by `resolve_subscription_bearer_token()`; remaining candidates are ignored.

### How does Headroom access my GitHub CLI authentication?

It runs `gh auth token` via `subprocess` in `_read_gh_cli_oauth_token()`. The returned token is then treated like any other OAuth candidate and validated against GitHub's Copilot user-info endpoint.

### Where does Headroom look for Copilot configuration files?

It reads [`apps.json`](https://github.com/chopratejas/headroom/blob/main/apps.json) and [`hosts.json`](https://github.com/chopratejas/headroom/blob/main/hosts.json) from `~/.config/github-copilot` on macOS and Linux, or `%LOCALAPPDATA%\github-copilot` on Windows. The `_read_file_oauth_token_candidates()` helper parses these files for a host-matching OAuth token.