All posts
Written by Sujith Quintelier May 3, 2026

🔑 Easier BYOK for GitHub Copilot CLI

Use the gh-copilot-byok .NET tool to switch between BYOK model profiles in GitHub Copilot CLI without juggling environment variables.
May 3, 2026

GitHub Copilot CLI supports Bring Your Own Key (BYOK), letting you point the CLI at any OpenAI-compatible endpoint, Azure OpenAI, or Anthropic instead of the default Copilot service. The capability is powerful, but the raw workflow requires you to export several environment variables every time you switch providers. This post walks through the manual approach first, shows why it becomes cumbersome, and then introduces gh-copilot-byok, a .NET global tool that wraps the whole flow with a polished interactive interface.

Prerequisites

  • GitHub Copilot CLI installed (gh extension install github/gh-copilot or the standalone copilot binary).
  • A Copilot subscription (Free, Pro, Business, or Enterprise).
  • .NET 10 SDK or later (for the tool install).
  • An API key from Azure OpenAI, OpenAI, or Anthropic, or a local Ollama instance. For Azure Foundry deployments with API keys disabled by policy, Azure CLI (az) installed and logged in is sufficient.

The manual BYOK approach

GitHub Copilot CLI exposes four environment variables for BYOK configuration:

VariableRequiredDescription
COPILOT_PROVIDER_BASE_URLYesBase URL of the model provider API
COPILOT_PROVIDER_TYPENoopenai (default), azure, or anthropic
COPILOT_PROVIDER_API_KEYNoAPI key (omit for unauthenticated local endpoints)
COPILOT_MODELYesModel identifier or deployment name

To use a model, export the variables and then start the CLI:

# Azure OpenAI
export COPILOT_PROVIDER_BASE_URL=https://my-resource.openai.azure.com/openai/deployments/gpt-4o
export COPILOT_PROVIDER_TYPE=azure
export COPILOT_PROVIDER_API_KEY=YOUR-AZURE-API-KEY
export COPILOT_MODEL=gpt-4o
copilot
# Anthropic
export COPILOT_PROVIDER_TYPE=anthropic
export COPILOT_PROVIDER_BASE_URL=https://api.anthropic.com
export COPILOT_PROVIDER_API_KEY=YOUR-ANTHROPIC-API-KEY
export COPILOT_MODEL=claude-opus-4-5
copilot
# Local Ollama (no API key needed)
export COPILOT_PROVIDER_BASE_URL=http://localhost:11434
export COPILOT_MODEL=llama3.2
copilot

To switch back to the default Copilot service, unset all four variables:

unset COPILOT_PROVIDER_BASE_URL COPILOT_PROVIDER_TYPE COPILOT_PROVIDER_API_KEY COPILOT_MODEL
copilot

Where the friction builds

This approach works for a single provider. Once you start switching between multiple endpoints - say, Azure OpenAI for code review, Ollama for offline work, and default Copilot for general tasks - the workflow gets tedious:

  • You must remember (or look up) the correct base URL and model name for each provider.
  • API keys cannot live in shell history for security reasons, so you end up sourcing separate env files or using a password manager to paste them in.
  • Switching mid-session requires unsetting every variable before setting the new ones. Miss one and the CLI either errors or silently uses a stale value.
  • There is no profile concept, so nothing persists between terminal sessions.
  • Multi-machine or team setups have no portable config story.
  • In enterprise environments, API keys for Azure OpenAI / Foundry hosted models may be disabled by policy (RBAC-only). In those cases COPILOT_PROVIDER_API_KEY simply does not work, and you need a short-lived bearer token instead - which adds yet another manual step to every session.

The bearer token problem: API keys disabled by policy

Many enterprise Azure OpenAI and Azure AI Foundry deployments are configured with RBAC-only access, meaning API keys are disabled at the resource level. This is a deliberate security control enforced by platform teams, not a configuration mistake. When it applies, setting COPILOT_PROVIDER_API_KEY returns a 401 error and there is no way around it using standard key-based auth.

The alternative is a short-lived bearer token obtained from Azure CLI:

# Fetch a bearer token from Azure CLI
TOKEN=$(az account get-access-token \
  --scope https://cognitiveservices.azure.com/.default \
  --query accessToken -o tsv)

export COPILOT_PROVIDER_BASE_URL=https://my-resource.openai.azure.com/openai/deployments/gpt-4o
export COPILOT_PROVIDER_TYPE=azure
export COPILOT_PROVIDER_BEARER_TOKEN=$TOKEN
unset COPILOT_PROVIDER_API_KEY
export COPILOT_MODEL=gpt-4o
copilot

There are two problems with this manual approach:

  • Azure bearer tokens expire (typically after one hour). Every new session requires a fresh az account get-access-token call.
  • You must remember to unset COPILOT_PROVIDER_API_KEY. If a stale key value is present alongside a bearer token, the auth mode is ambiguous and the request may fail.

This is where gh-copilot-byok adds the most value for Azure Foundry users.

Introducing gh-copilot-byok

gh-copilot-byok is a .NET global tool that adds a persistent profile layer on top of the raw environment variables. Profiles are stored in ~/.gh-copilot-byok/config.json and the tool sets the correct variables automatically when you activate one. It uses Spectre.Console for a clean terminal UI with coloured tables and interactive selection menus.

Installation

Install directly from Nuget:

dotnet tool install --global gh-copilot-byok

Or build from source:

git clone https://github.com/sujithq/gh-copilot-cli-model-switcher.git
cd gh-copilot-cli-model-switcher/dotnet/CopilotX
dotnet pack
dotnet tool install --global --add-source ./nupkg gh-copilot-byok

Verify the install:

gh-copilot-byok help

To update later:

dotnet tool update --global gh-copilot-byok \
  --add-source "https://nuget.pkg.github.com/sujithq/index.json"

Adding profiles

Run the interactive wizard to add your first profile:

gh-copilot-byok add

The wizard walks you through the following steps:

  1. Profile name: a short slug you will use in use commands (e.g. azure-gpt).
  2. Profile type: byok for API-key or bearer token endpoints, copilot for the default service.
  3. Provider type: openai, azure, or anthropic.
  4. Base URL: the full endpoint URL (e.g. https://my-resource.openai.azure.com/openai/deployments/gpt-4o).
  5. Model: the deployment or model identifier (e.g. gpt-4o).
  6. Auth method: API key entered via a secure password prompt, an environment variable name (apiKeyEnv), or Azure CLI bearer token (azureCliToken).

If you add a profile with identical settings to an existing one, the tool updates the existing profile rather than creating a duplicate.

Adding an Azure OpenAI profile with an API key environment variable

When you choose the apiKeyEnv option during the wizard, the key is read from the named environment variable at runtime instead of being stored in the config file:

# Set the key in your shell profile (e.g. ~/.bashrc)
export AZURE_OPENAI_KEY="sk-..."

# Then add the profile: enter "apiKeyEnv" as auth method and "AZURE_OPENAI_KEY" as the variable name
gh-copilot-byok add

Adding a Foundry profile with bearer token auth (API keys disabled by policy)

When prompted for the auth method choose azureCliToken. The tool will automatically call az account get-access-token before each session:

# Ensure you are logged in first
az login

gh-copilot-byok add
# provider type: azure
# base URL:      https://my-foundry.openai.azure.com/openai/deployments/gpt-4o
# model:         gpt-4o
# auth method:   azureCliToken

Listing profiles

gh-copilot-byok list

Renders a formatted table of all profiles. The last-used profile is marked with * so you always know your current context. The active config file path is shown below the table.

 Name             Type     Provider   Model      Auth
 ──────────────── ──────── ────────── ────────── ────────────────
 default *        copilot             auto
 azure-gpt        byok     azure      gpt-4o     apiKeyEnv
 foundry-rbac     byok     azure      gpt-4o     azureCliToken
 anthropic-opus   byok     anthropic  claude...  apiKey
 ollama-local     byok     openai     llama3.2

Switching models

To activate a profile interactively (launches gh copilot in interactive mode):

gh-copilot-byok use azure-gpt

This sets the environment variables, then hands off to gh copilot. You can also pass a prompt directly:

gh-copilot-byok use azure-gpt -p "refactor this function for clarity"

Using a Foundry RBAC profile (bearer token)

For profiles with azureCliToken: "auto", the tool fetches a fresh token before each invocation, so no manual az account get-access-token call is required.

# Interactive mode
gh-copilot-byok use foundry-rbac

# Non-interactive with a prompt
gh-copilot-byok use foundry-rbac -p "explain this Bicep template"

Allowing tools and controlling MCP servers

Any flag that gh copilot accepts can be forwarded after the profile name:

FlagDescription
-p / --prompt <text>Run non-interactively with a prompt
--allow-all-toolsAllow all tools
--allow-all / --yoloAllow all tools and operations
--allow-tool <name>Allow a specific tool
--deny-tool <name>Deny a specific tool
--disable-mcp-server <name>Disable a named MCP server
--disable-builtin-mcpsDisable all built-in MCP servers
# Allow all tools (useful in scripted pipelines)
gh-copilot-byok use azure-gpt --allow-all-tools

# YOLO mode: allow all tools and operations
gh-copilot-byok use azure-gpt --yolo -p "rewrite all tests to use xUnit"

# Deny a specific tool
gh-copilot-byok use azure-gpt --deny-tool shell_exec -p "review this PR diff"

# Disable one MCP server for this invocation only
gh-copilot-byok use foundry-rbac \
  --disable-mcp-server foundry-mcp \
  -p "generate a Terraform module for AKS"

# Disable all built-in MCP servers
gh-copilot-byok use ollama-local --disable-builtin-mcps

When -p is passed, --allow-all-tools is injected automatically unless you already specified one of the permission flags above.

To jump back to the default Copilot service:

gh-copilot-byok default

# Also works non-interactively
gh-copilot-byok default -p "what does this script do?"

To reuse the last activated profile without typing its name:

# Interactive mode
gh-copilot-byok last

# Non-interactive
gh-copilot-byok last -p "explain this error"

Interactive management

The manage command provides a single interactive flow for all profile operations:

gh-copilot-byok manage

From here you can use, remove, add, import, configure MCP compatibility servers, or exit, all from a single menu without remembering sub-command names.

? What do you want to do?
❯ Use a profile
  Add a profile
  Remove profiles
  Import from Foundry
  Set MCP compatibility servers
  Exit

Importing from Azure Foundry

If you have Azure OpenAI / Azure AI Foundry deployments, the tool can discover and import them automatically using the Azure CLI:

# Discover all accounts, prompt per deployment (interactive)
gh-copilot-byok import-foundry

# Explicit per-deployment prompt mode
gh-copilot-byok import-foundry --mode each

# Import all deployments without prompts
gh-copilot-byok import-foundry --all

# Scope to one account and resource group, add all without prompts
gh-copilot-byok import-foundry \
  --account myfoundry \
  --resource-group my-rg \
  --all

# Limit discovery to a specific subscription
gh-copilot-byok import-foundry \
  --subscription 00000000-0000-0000-0000-000000000000 \
  --all

# Combine subscription and account filters
gh-copilot-byok import-foundry \
  --subscription my-sub-name \
  --account myfoundry \
  --resource-group my-rg \
  --all

Only chat-capable deployments are imported (embeddings are skipped). Re-running the command deduplicates profiles automatically, so it is safe to run after new deployments are created.

Crucially, every profile created by import-foundry uses bearer token auth by default (azureCliToken: "auto"), not API keys. This is the correct behaviour for Foundry-hosted models where API keys are disabled by policy. The tool calls az account get-access-token automatically before each session and sets COPILOT_PROVIDER_BEARER_TOKEN, so you never need to handle token acquisition manually.

MCP server compatibility

Some BYOK or proxy profiles may conflict with certain MCP servers that expect the default Copilot service. The mcp-compat command lets you specify which MCP servers the tool should disable automatically when a given profile is activated:

# Interactively select which servers to disable for a profile
gh-copilot-byok mcp-compat my-azure-profile

# Same as above but explicitly invoke the selection prompt
gh-copilot-byok mcp-compat my-azure-profile --action set

# Disable all candidate servers automatically (no prompt)
gh-copilot-byok mcp-compat my-azure-profile --action all

# Disable none of the candidate servers
gh-copilot-byok mcp-compat my-azure-profile --action none

# Reset the saved selection: you will be prompted again on the next interactive use
gh-copilot-byok mcp-compat my-azure-profile --action reset

The default candidate server list is: foundry-mcp, context7, msx-mcp, azure, workiq, powerbi-remote.

? Select MCP servers to disable for profile "foundry-rbac"
  (Use space to select, enter to confirm)
❯ ◉ foundry-mcp
  ◉ context7
  ◯ msx-mcp
  ◯ azure
  ◯ workiq
  ◯ powerbi-remote

Your selection is saved to the profile under mcpCompatServers and reused on every subsequent run. To disable the entire compat mode for a session, set CBMS_DISABLE_MCP_COMPAT=off before running the tool.

Configuration

Profiles are stored in ~/.gh-copilot-byok/. The active config file depends on the COPILOT_BYOK_MODEL_SWITCHER_CONFIG_SCOPE environment variable:

ValueBehaviour
auto (default)Azure user-scoped config if az account show is available, otherwise global
azure-userAlways use Azure user-scoped config
globalAlways use ~/.gh-copilot-byok/config.json

In Azure user-scoped mode the filename includes the tenant ID and username: config.<tenantId>__<userName>.json. This means each Azure identity gets an isolated profile set on the same machine.

An example config file showing all three authentication patterns:

{
  "profiles": [
    {
      "name": "default",
      "type": "copilot",
      "model": "auto"
    },
    {
      "name": "azure-gpt",
      "type": "byok",
      "baseUrl": "https://my-resource.openai.azure.com/openai/deployments/gpt-4o",
      "apiKeyEnv": "AZURE_OPENAI_KEY",
      "model": "gpt-4o"
    },
    {
      "name": "foundry-rbac",
      "type": "byok",
      "baseUrl": "https://my-resource.openai.azure.com/openai/deployments/gpt-4o",
      "model": "gpt-4o",
      "providerType": "azure",
      "azureCliToken": "auto",
      "tokenScope": "https://cognitiveservices.azure.com/.default"
    },
    {
      "name": "ollama-local",
      "type": "byok",
      "baseUrl": "http://localhost:11434",
      "model": "llama3.2"
    }
  ]
}

The three authentication patterns in use above are:

  • apiKeyEnv: points to an environment variable holding the key, keeping secrets out of the config file. Used when API keys are enabled on the resource.
  • azureCliToken: "auto": used when API keys are disabled by policy. The tool runs az account get-access-token before each session and sets COPILOT_PROVIDER_BEARER_TOKEN automatically. COPILOT_PROVIDER_API_KEY is cleared to avoid auth-mode ambiguity. Set tokenScope to the Cognitive Services default scope (https://cognitiveservices.azure.com/.default) for Azure OpenAI endpoints.
  • No auth fields: for local endpoints like Ollama that do not require authentication.

Removing profiles

# Interactive multi-select removal
gh-copilot-byok remove

# Remove a single profile by name
gh-copilot-byok remove azure-gpt

# Remove multiple profiles in one command
gh-copilot-byok remove azure-gpt ollama-local
? Select profiles to remove (Space to select, Enter to confirm)
  ◯ azure-gpt
  ◉ foundry-rbac
  ◉ ollama-local

The default profile is protected and cannot be removed.

Why this matters now

The GitHub Changelog announced on 22 April 2026 that BYOK for Copilot is now available in VS Code. The CLI BYOK feature follows the same model: bring your own provider key, point the CLI at any OpenAI-compatible endpoint, and keep the Copilot interface you already know. gh-copilot-byok makes the CLI side of that story practical for developers who work with more than one provider.

Troubleshooting

Profile not found: run gh-copilot-byok list to see available profiles, or gh-copilot-byok add to create one.

Error executing gh copilot: ensure Copilot CLI is installed:

gh extension install github/gh-copilot

API key not found for apiKeyEnv: export the environment variable before running the tool:

export AZURE_OPENAI_KEY="your-key-here"

401 Unauthorized when using an API key against a Foundry endpoint: the Azure resource likely has API keys disabled by policy. Use a bearer token profile instead (azureCliToken: "auto"). Ensure you are logged in with az login and that your identity has the Cognitive Services OpenAI User or Contributor role on the resource.

Model does not support tool calling: Copilot CLI requires a model that supports tool/function calling and streaming. Check your provider’s documentation to confirm the model supports both. A context window of at least 128k tokens is recommended for best results.

References

Sponsored by GitAds
comments powered by Disqus