最适合: 多用户应用、具有组织级访问控制的内部工具、SaaS 产品、用户拥有 GitHub 账户的应用。
工作原理
创建GitHub OAuth 应用(或GitHub应用),用户对其进行授权,并将其访问令牌传递给 SDK。 Copilot 请求会代表每位经过身份验证的用户发出,并使用其 Copilot 订阅。

主要特征:
- 每个用户使用自己的GitHub帐户进行身份验证
- Copilot 使用费用将计入每个用户的订阅
- 支持GitHub组织和企业帐户
- 你的应用永远不会处理模型 API 密钥 - GitHub管理所有内容
Architecture

步骤 1:创建GitHub OAuth 应用
-
转到GitHub设置→开发人员设置→ OAuth 应用→新 OAuth 应用(或适用于组织:组织设置→开发人员设置)
-
填写:
- 应用程序名称:应用的名称
- 主页 URL:应用的 URL
- 授权回调 URL:您的 OAuth 回调端点(例如
https://yourapp.com/auth/callback)
-
记下 客户端 ID 并生成 客户端密码
GitHub 应用与 OAuth 应用: 两者都可以。 GitHub应用提供精细的权限,建议用于新项目。 OAuth 应用设置更简单。 从 SDK 的角度来看,令牌流是相同的。
步骤 2:实现 OAuth 流
应用程序处理标准GitHub OAuth 流。 下面是服务器端令牌交换:
// Server-side: Exchange authorization code for user token
async function handleOAuthCallback(code: string): Promise<string> {
const response = await fetch("https://github.com/login/oauth/access_token", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify({
client_id: process.env.GITHUB_CLIENT_ID,
client_secret: process.env.GITHUB_CLIENT_SECRET,
code,
}),
});
const data = await response.json();
return data.access_token; // gho_xxxx or ghu_xxxx
}
步骤 3:将令牌传递给 SDK
为每个经过身份验证的用户创建 SDK 客户端,并传递其令牌:
import { CopilotClient } from "@github/copilot-sdk";
// Create a client for an authenticated user
function createClientForUser(userToken: string): CopilotClient {
return new CopilotClient({
gitHubToken: userToken,
useLoggedInUser: false, // Don't fall back to CLI login
});
}
// Usage
const client = createClientForUser("gho_user_access_token");
const session = await client.createSession({
sessionId: `user-${userId}-session`,
model: "gpt-4.1",
});
const response = await session.sendAndWait({ prompt: "Hello!" });
from copilot import CopilotClient
from copilot.session import PermissionHandler
def create_client_for_user(user_token: str) -> CopilotClient:
return CopilotClient({
"github_token": user_token,
"use_logged_in_user": False,
})
# Usage
client = create_client_for_user("gho_user_access_token")
await client.start()
session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-4.1", session_id=f"user-{user_id}-session")
response = await session.send_and_wait("Hello!")
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
)
func createClientForUser(userToken string) *copilot.Client {
return copilot.NewClient(&copilot.ClientOptions{
GitHubToken: userToken,
UseLoggedInUser: copilot.Bool(false),
})
}
func main() {
ctx := context.Background()
userID := "user1"
client := createClientForUser("gho_user_access_token")
client.Start(ctx)
defer client.Stop()
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-session", userID),
Model: "gpt-4.1",
})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"})
_ = response
}
func createClientForUser(userToken string) *copilot.Client {
return copilot.NewClient(&copilot.ClientOptions{
GithubToken: userToken,
UseLoggedInUser: copilot.Bool(false),
})
}
// Usage
client := createClientForUser("gho_user_access_token")
client.Start(ctx)
defer client.Stop()
session, _ := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-session", userID),
Model: "gpt-4.1",
})
response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"})
using GitHub.Copilot;
CopilotClient CreateClientForUser(string userToken) =>
new CopilotClient(new CopilotClientOptions
{
GitHubToken = userToken,
UseLoggedInUser = false,
});
var userId = "user1";
await using var client = CreateClientForUser("gho_user_access_token");
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{userId}-session",
Model = "gpt-4.1",
});
var response = await session.SendAndWaitAsync(
new MessageOptions { Prompt = "Hello!" });
CopilotClient CreateClientForUser(string userToken) =>
new CopilotClient(new CopilotClientOptions
{
GitHubToken = userToken,
UseLoggedInUser = false,
});
// Usage
await using var client = CreateClientForUser("gho_user_access_token");
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{userId}-session",
Model = "gpt-4.1",
});
var response = await session.SendAndWaitAsync(
new MessageOptions { Prompt = "Hello!" });
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.*;
import com.github.copilot.sdk.json.*;
CopilotClient createClientForUser(String userToken) throws Exception {
var client = new CopilotClient(new CopilotClientOptions()
.setGitHubToken(userToken)
.setUseLoggedInUser(false)
);
client.start().get();
return client;
}
// Usage — use try-with-resources to ensure cleanup
var userId = "user1";
try (var client = createClientForUser("gho_user_access_token")) {
var session = client.createSession(new SessionConfig()
.setSessionId(String.format("user-%s-session", userId))
.setModel("gpt-4.1")
.setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
).get();
var response = session.sendAndWait(new MessageOptions()
.setPrompt("Hello!")).get();
}
企业和组织访问权限
GitHub OAuth 自然支持企业方案。 当用户使用GitHub进行身份验证时,其组织成员资格和企业关联也随之而来。

验证组织成员身份
OAuth 后,检查用户是否属于组织:
async function verifyOrgMembership(
token: string,
requiredOrg: string
): Promise<boolean> {
const response = await fetch("https://api.github.com/user/orgs", {
headers: { Authorization: `Bearer ${token}` },
});
const orgs = await response.json();
return orgs.some((org: any) => org.login === requiredOrg);
}
// In your auth flow
const token = await handleOAuthCallback(code);
if (!await verifyOrgMembership(token, "my-company")) {
throw new Error("User is not a member of the required organization");
}
const client = createClientForUser(token);
企业托管用户(EMU)
对于GitHub企业托管用户,流是相同的 — EMU 用户像任何其他用户一样通过 GitHub OAuth 进行身份验证。 其企业策略(IP 限制、SAML SSO)由 GitHub 自动强制执行。
// No special SDK configuration needed for EMU
// Enterprise policies are enforced server-side by GitHub
const client = new CopilotClient({
gitHubToken: emuUserToken, // Works the same as regular tokens
useLoggedInUser: false,
});
支持的令牌类型
| 令牌前缀 | 来源 | 可以用吗? |
|---|---|---|
gho_ | OAuth 用户访问令牌 | ✅ |
ghu_ | GitHub应用用户访问令牌 | ✅ |
github_pat_ | 细粒度的个人访问令牌 | ✅ |
ghp_ | 经典个人访问令牌 | |
| ❌(已弃用) |
令牌生命周期

重要: 应用程序负责令牌存储、刷新和过期处理。 SDK 使用你提供的任何令牌 -- 它不管理 OAuth 生命周期。
令牌刷新模式
async function getOrRefreshToken(userId: string): Promise<string> {
const stored = await tokenStore.get(userId);
if (stored && !isExpired(stored)) {
return stored.accessToken;
}
if (stored?.refreshToken) {
const refreshed = await refreshGitHubToken(stored.refreshToken);
await tokenStore.set(userId, refreshed);
return refreshed.accessToken;
}
throw new Error("User must re-authenticate");
}
多用户模式
每个用户一个客户端(建议)
每个用户使用自己的令牌获取自己的 SDK 客户端。 这提供最强的隔离。
const clients = new Map<string, CopilotClient>();
function getClientForUser(userId: string, token: string): CopilotClient {
if (!clients.has(userId)) {
clients.set(userId, new CopilotClient({
gitHubToken: token,
useLoggedInUser: false,
}));
}
return clients.get(userId)!;
}
使用按请求分配令牌的共享 CLI
对于较轻的资源占用情况,可以运行单个外部 CLI 服务器并为每个会话传递令牌。 有关此模式,请参阅 后端服务设置 。
局限性
| Limitation | 详细信息 |
|---|---|
| 需要 Copilot 订阅 | 每个用户都需要一个有效的 Copilot 订阅 |
| 令牌管理是你的责任 | 存储、刷新和处理过期 |
| 需要GitHub帐户 | 用户必须具有GitHub帐户 |
| 每个用户的速率限制 | 取决于各用户的 Copilot 速率限制 |
何时继续
| 需要 | 下一篇指南 |
|---|---|
| 没有GitHub帐户的用户 | |
| BYOK (bring your own key) | |
| 在服务器上运行 SDK | |
| 后端服务设置 | |
| 处理多个并发用户 | |
| 可扩展性和多租户 |
后续步骤
- Authentication:完整身份验证方法参考
- 后端服务设置:在服务器端运行 SDK
- 可扩展性和多租户:大规模处理许多用户