Use your own model provider API keys instead of GitHub Copilot authentication. You control the identity layer, the model provider, and the billing — the SDK provides the agent runtime.
Best for: Apps where users don't have GitHub accounts, enterprise deployments with existing model provider contracts, apps needing full control over identity and billing.
With BYOK, the SDK uses the Copilot CLI as an agent runtime only — it doesn't call GitHub's Copilot API. Instead, model requests go directly to your configured provider (OpenAI, Azure AI Foundry, Anthropic, etc.).
flowchart LR
subgraph App["Your Application"]
SDK["SDK Client"]
IdP["Your Identity<br/>Provider"]
end
subgraph CLI["Copilot CLI"]
Runtime["Agent Runtime"]
end
subgraph Provider["Your Model Provider"]
API["OpenAI / Azure /<br/>Anthropic / Ollama"]
end
IdP -.->|"authenticates<br/>users"| SDK
SDK --> Runtime
Runtime -- "API key" --> API
style App fill:#0d1117,stroke:#58a6ff,color:#c9d1d9
style CLI fill:#0d1117,stroke:#3fb950,color:#c9d1d9
style Provider fill:#161b22,stroke:#f0883e,color:#c9d1d9
Key characteristics:
flowchart TB
subgraph GitHub["GitHub Auth Path"]
direction LR
G1["User"] --> G2["GitHub OAuth"]
G2 --> G3["SDK + CLI"]
G3 --> G4["☁️ Copilot API"]
end
subgraph BYOK["BYOK Path"]
direction LR
B1["User"] --> B2["Your Auth"]
B2 --> B3["SDK + CLI"]
B3 --> B4["☁️ Your Provider"]
end
style GitHub fill:#161b22,stroke:#8b949e,color:#c9d1d9
style BYOK fill:#0d1117,stroke:#3fb950,color:#c9d1d9
import { CopilotClient } from "copilot-sdk-supercharged";
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-4.1",
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY,
},
});
const response = await session.sendAndWait({ prompt: "Hello!" });
console.log(response?.data.content);
await client.stop();
import os
from copilot import CopilotClient
client = CopilotClient()
await client.start()
session = await client.create_session({
"model": "gpt-4.1",
"provider": {
"type": "openai",
"base_url": "https://api.openai.com/v1",
"api_key": os.environ["OPENAI_API_KEY"],
},
})
response = await session.send_and_wait({"prompt": "Hello!"})
print(response.data.content)
await client.stop()
client := copilot.NewClient(nil)
client.Start(ctx)
defer client.Stop()
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
Model: "gpt-4.1",
Provider: &copilot.ProviderConfig{
Type: "openai",
BaseURL: "https://api.openai.com/v1",
APIKey: os.Getenv("OPENAI_API_KEY"),
},
})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"})
fmt.Println(*response.Data.Content)
await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-4.1",
Provider = new ProviderConfig
{
Type = "openai",
BaseUrl = "https://api.openai.com/v1",
ApiKey = Environment.GetEnvironmentVariable("OPENAI_API_KEY"),
},
});
var response = await session.SendAndWaitAsync(
new MessageOptions { Prompt = "Hello!" });
Console.WriteLine(response?.Data.Content);
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY,
}
provider: {
type: "openai",
baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
apiKey: process.env.FOUNDRY_API_KEY,
wireApi: "responses", // For GPT-5 series models
}
provider: {
type: "azure",
baseUrl: "https://your-resource.openai.azure.com",
apiKey: process.env.AZURE_OPENAI_KEY,
azure: { apiVersion: "2024-10-21" },
}
provider: {
type: "anthropic",
baseUrl: "https://api.anthropic.com",
apiKey: process.env.ANTHROPIC_API_KEY,
}
provider: {
type: "openai",
baseUrl: "http://localhost:11434/v1",
// No API key needed for local Ollama
}
With BYOK, you're responsible for authentication. Here are common patterns:
sequenceDiagram
participant User
participant App as Your App
participant IdP as Your Identity Provider
participant SDK as SDK + CLI
participant LLM as Model Provider
User->>App: Login
App->>IdP: Authenticate user
IdP-->>App: User identity + permissions
App->>App: Look up API key for user's tier
App->>SDK: Create session (with provider config)
SDK->>LLM: Model request (your API key)
LLM-->>SDK: Response
SDK-->>App: Result
App-->>User: Display
// Your app handles auth, then creates sessions with your API key
app.post("/chat", authMiddleware, async (req, res) => {
const user = req.user; // From your auth middleware
// Use your API key — not the user's
const session = await getOrCreateSession(user.id, {
model: getModelForTier(user.tier), // "gpt-4.1" for pro, etc.
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY, // Your key, your billing
},
});
const response = await session.sendAndWait({ prompt: req.body.message });
res.json({ content: response?.data.content });
});
For B2B apps where each customer brings their own model provider keys:
flowchart TB
subgraph Customers
C1["Customer A<br/>(OpenAI key)"]
C2["Customer B<br/>(Azure key)"]
C3["Customer C<br/>(Anthropic key)"]
end
subgraph App["Your App"]
Router["Request Router"]
KS["Key Store<br/>(encrypted)"]
end
C1 --> Router
C2 --> Router
C3 --> Router
Router --> KS
KS --> SDK1["SDK → OpenAI"]
KS --> SDK2["SDK → Azure"]
KS --> SDK3["SDK → Anthropic"]
style App fill:#0d1117,stroke:#58a6ff,color:#c9d1d9
async function createSessionForCustomer(customerId: string) {
const config = await keyStore.getProviderConfig(customerId);
return client.createSession({
sessionId: `customer-${customerId}-${Date.now()}`,
model: config.model,
provider: {
type: config.providerType,
baseUrl: config.baseUrl,
apiKey: config.apiKey,
},
});
}
When resuming BYOK sessions, you must re-provide the provider configuration. API keys are never persisted to disk for security.
// Create session
const session = await client.createSession({
sessionId: "task-123",
model: "gpt-4.1",
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY,
},
});
// Resume later — must re-provide provider config
const resumed = await client.resumeSession("task-123", {
provider: {
type: "openai",
baseUrl: "https://api.openai.com/v1",
apiKey: process.env.OPENAI_API_KEY, // Required again
},
});
| Limitation | Details |
|---|---|
| Static credentials only | API keys or bearer tokens — no Entra ID, OIDC, or managed identities |
| No auto-refresh | If a bearer token expires, you must create a new session |
| Your billing | All model usage is billed to your provider account |
| Model availability | Limited to what your provider offers |
| Keys not persisted | Must re-provide on session resume |
For the full BYOK reference, see the BYOK documentation.
| Need | Next Guide |
|---|---|
| Run the SDK on a server | Backend Services |
| Multiple users with GitHub accounts | GitHub OAuth |
| Handle many concurrent users | Scaling & Multi-Tenancy |
Can you improve this documentation? These fine people already did:
Jeremiah Isaacson & Patrick NikoletichEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |