# BYOK Authentication in Copilot SDK: A Complete Guide to Bring Your Own Key

> Learn about BYOK authentication in Copilot SDK. Connect directly to your model provider using your own managed static API credentials, bypassing GitHub OAuth.

- Repository: [GitHub/copilot-sdk](https://github.com/github/copilot-sdk)
- Tags: how-to-guide
- Published: 2026-06-05

---

**BYOK authentication in the Copilot SDK allows you to bypass GitHub's OAuth flow and connect directly to your own model provider using static API credentials you manage.**

BYOK (Bring Your Own Key) is an authentication mode in the `github/copilot-sdk` that gives enterprises and developers full control over their model provider connections. Instead of routing requests through GitHub Copilot's infrastructure, the SDK sends inference requests directly to your chosen provider—whether that's OpenAI, Azure OpenAI, Anthropic, or a local Ollama instance. This guide explains the architecture, implementation patterns, and limitations of BYOK authentication based on the official source code.

## How BYOK Authentication Works in Copilot SDK

When you configure BYOK authentication, the SDK switches from GitHub-OAuth mode to direct provider communication. According to the source code in [`go/types.go`](https://github.com/github/copilot-sdk/blob/main/go/types.go), the runtime treats a non-nil `Provider` field in `SessionConfig` as the trigger for BYOK mode.

The core data structure is `ProviderConfig`, defined in [`go/types.go`](https://github.com/github/copilot-sdk/blob/main/go/types.go)【L1474-L1499】, which captures:

- **Type**: The provider identifier (e.g., `"openai"`, `"anthropic"`, `"ollama"`)
- **BaseURL**: The endpoint for your model provider
- **APIKey/BearerToken**: Static credentials for authentication
- **WireAPI**: The API specification to use (e.g., `"responses"`)

When creating a session, you pass a `SessionConfig` struct containing a `Provider *ProviderConfig` field【L974-L979】. If this field is populated, the SDK disables internal telemetry automatically【L777-L785】 and expects you to provide a concrete `model` string, since the runtime cannot discover available models from an unknown provider.

## Supported Model Providers

The Copilot SDK supports BYOK authentication for multiple provider types:

- **OpenAI** – Direct connection to OpenAI's API
- **Azure OpenAI / Azure AI Foundry** – Enterprise Microsoft deployments
- **Anthropic** – Claude model family access
- **Ollama** – Local inference for development environments
- **Microsoft Foundry Local** – On-premises model hosting
- **OpenAI-compatible endpoints** – Any provider implementing the OpenAI API specification

## Implementing BYOK Authentication

To implement BYOK authentication, you must supply a provider configuration when creating a session. Unlike the standard OAuth flow, BYOK requires **static credentials only**—the SDK does not refresh tokens automatically, and you must recreate the session when credentials expire.

### Python Implementation

```python
import asyncio
import os
from copilot import CopilotClient
from copilot.session import PermissionHandler

FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/"

async def main():
    client = CopilotClient()
    await client.start()

    session = await client.create_session(
        on_permission_request=PermissionHandler.approve_all,
        model="gpt-5.2-codex",
        provider={
            "type": "openai",
            "base_url": FOUNDRY_MODEL_URL,
            "wire_api": "responses",
            "api_key": os.environ["FOUNDRY_API_KEY"],
        },
    )

    await session.send("What is 2+2?")
    await client.stop()

asyncio.run(main())

```

*Source*: Python snippet in the BYOK docs【L20-L58】.

### Node.js / TypeScript Implementation

```typescript
import { CopilotClient } from "@github/copilot-sdk";

const FOUNDRY_MODEL_URL = "https://your-resource.openai.azure.com/openai/v1/";

const client = new CopilotClient();
const session = await client.createSession({
  model: "gpt-5.2-codex",
  provider: {
    type: "openai",
    baseUrl: FOUNDRY_MODEL_URL,
    wireApi: "responses",
    apiKey: process.env.FOUNDRY_API_KEY,
  },
});

session.on("assistant.message", ev => console.log(ev.data.content));
await session.sendAndWait({ prompt: "What is 2+2?" });
await client.stop();

```

*Source*: Node.js snippet in the BYOK docs【L63-L88】.

### Go Implementation

```go
package main

import (
	"context"
	"fmt"
	"os"

	copilot "github.com/github/copilot-sdk/go"
)

func main() {
	ctx := context.Background()
	client := copilot.NewClient(nil)

	if err := client.Start(ctx); err != nil { panic(err) }
	defer client.Stop()

	session, err := client.CreateSession(ctx, &copilot.SessionConfig{
		Model: "gpt-5.2-codex",
		Provider: &copilot.ProviderConfig{
			Type:    "openai",
			BaseURL: "https://your-resource.openai.azure.com/openai/v1/",
			WireAPI: "responses",
			APIKey:  os.Getenv("FOUNDRY_API_KEY"),
		},
	})
	if err != nil { panic(err) }

	resp, err := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "What is 2+2?"})
	if err != nil { panic(err) }
	fmt.Println(resp.Data.(*copilot.AssistantMessageData).Content)
}

```

*Source*: Go snippet in the BYOK docs【L92-L138】.

### .NET (C#) Implementation

```csharp
using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig {
    Model = "gpt-5.2-codex",
    Provider = new ProviderConfig {
        Type = "openai",
        BaseUrl = "https://your-resource.openai.azure.com/openai/v1/",
        WireApi = "responses",
        ApiKey = Environment.GetEnvironmentVariable("FOUNDRY_API_KEY"),
    },
});

var response = await session.SendAndWaitAsync(new MessageOptions { Prompt = "What is 2+2?" });
Console.WriteLine(response?.Data.Content);

```

*Source*: .NET snippet in the BYOK docs【L140-L168】.

### Java Implementation

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

var client = new CopilotClient();
client.start().get();

var session = client.createSession(new SessionConfig()
    .setModel("gpt-5.2-codex")
    .setProvider(new ProviderConfig()
        .setType("openai")
        .setBaseUrl("https://your-resource.openai.azure.com/openai/v1/")
        .setWireApi("responses")
        .setApiKey(System.getenv("FOUNDRY_API_KEY"))
    )
).get();

var response = session.sendAndWait(new MessageOptions().setPrompt("What is 2+2?")).get();
System.out.println(response.getData().content());

client.stop().get();

```

*Source*: Java snippet in the BYOK docs【L170-L194】.

## Limitations and Architectural Considerations

Before implementing BYOK authentication in production, consider these constraints defined in the `github/copilot-sdk` source code:

- **No automatic token refresh**: BYOK only accepts static secrets. When your API key expires, you must recreate the session with fresh credentials.
- **Telemetry disabled**: When a custom provider is configured in `SessionConfig`, the SDK automatically disables internal session telemetry (`EnableSessionTelemetry` is ignored)【L777-L785】.
- **Manual model specification**: You must provide a concrete `model` string in the configuration because the runtime cannot query an unknown provider for available models.
- **Provider-governed limits**: Rate limits, usage tracking, and billing are handled entirely by your model provider, not by GitHub. Some premium-request accounting features do not apply in BYOK mode.

## Summary

- **BYOK authentication** in the Copilot SDK enables direct connections to model providers using static credentials you provide, bypassing GitHub's OAuth flow.
- **Core configuration** happens through the `ProviderConfig` struct in [`go/types.go`](https://github.com/github/copilot-sdk/blob/main/go/types.go)【L1474-L1499】, which you attach to `SessionConfig`【L974-L979】 when creating sessions.
- **Supported providers** include OpenAI, Azure OpenAI, Anthropic, Ollama, and any OpenAI-compatible endpoint.
- **Static credentials only**: The SDK does not manage token refresh—you must handle credential rotation manually.
- **Telemetry disabled**: Using a custom provider automatically disables internal telemetry gathering.
- **Concrete model required**: You must specify the exact model identifier since the SDK cannot discover models from custom endpoints.

## Frequently Asked Questions

### Does BYOK authentication support automatic token rotation?

No. BYOK authentication only accepts static credentials—either an API key or bearer token that you manage yourself. The Copilot SDK does not implement automatic token refresh for BYOK sessions. When your credentials expire, you must recreate the session with new credentials. This is enforced in the `ProviderConfig` structure defined in [`go/types.go`](https://github.com/github/copilot-sdk/blob/main/go/types.go)【L1474-L1499】.

### Why is telemetry disabled when using BYOK authentication?

When you configure a custom provider in `SessionConfig`, the Copilot SDK runtime automatically disables internal session telemetry by ignoring the `EnableSessionTelemetry` setting【L777-L785】. This ensures that inference requests and responses to your private model provider remain outside of GitHub's telemetry pipeline, keeping your data within your own infrastructure.

### Can I use BYOK authentication with local models like Ollama?

Yes. The Copilot SDK supports Ollama and Microsoft Foundry Local as BYOK providers. You configure these by setting the provider `type` to `"ollama"` and specifying the local endpoint URL in the `baseUrl` field of your `ProviderConfig`. This is useful for air-gapped environments or development scenarios requiring local inference.

### What happens if I don't specify a model when using BYOK authentication?

The SDK will require a concrete model identifier because it cannot discover available models from an unknown provider. Unlike the standard GitHub Copilot flow, which can query available models through GitHub's API, BYOK connections lack a discovery mechanism. You must explicitly set the `model` field in your `SessionConfig` when using BYOK authentication.