Лучше всего для: Многопользовательских приложений, внутренних инструментов с управлением доступом к организации, SaaS-продуктов, приложений, где у пользователей есть GitHub аккаунты.
Принцип работы
Вы создаёте OAuth приложение GitHub (или приложение GitHub), пользователи его авторизуют, и вы передаёте их токен доступа SDK. Запросы на Copilot выполняются от имени каждого аутентифицированного пользователя с использованием их подписки Copilot.

Ключевые характеристики:
- Каждый пользователь аутентифицируется со своей собственной учетной записью GitHub
- Использование Copilot оплачивается по подписке каждого пользователя
- Поддерживает организации GitHub и корпоративные аккаунты
- Ваше приложение никогда не обрабатывает ключи API моделей — GitHub управляет всем
Architecture

Шаг 1: создать приложение GitHub OAuth
-
Перейдите в GitHub Настройки → Настройки разработчика → OAuth Apps → New OAuth App (или для организаций: Настройки организации → Настройки разработчика)
-
Заполните:
- Название приложения: Название вашего приложения
- URL главной страницы: URL вашего приложения
- URL обратного вызова авторизации: ваша конечная точка обратного вызова OAuth (например,
https://yourapp.com/auth/callback)
-
Запишите свой клиентский идентификатор и сгенерируйте секрет клиента
**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 | Details |
|---|---|
| Copilot требуется подписка | Каждому пользователю нужна активная подписка на Copilot |
| Управление токенами — ваша ответственность | Храните, обновляйте и обрабатывайте истечение срока действия |
| GitHub требуется аккаунт | Пользователи должны иметь аккаунты GitHub |
| Ограничения по скорости на пользователя | С учётом лимитов Copilot каждого пользователя |
Когда двигаться дальше
| Необходимость | Следующее руководство |
|---|---|
| Пользователи без аккаунтов GitHub | |
| BYOK (bring your own key) | |
| Запускайте SDK на серверах | |
| Настройка серверных сервисов | |
| Работа с множеством одновременных пользователей | |
| Масштабирование и многоарендность |
Дальнейшие действия
- АВТОТИТР: Полная ссылка на метод аутентификации
- Настройка серверных сервисов: Запустите SDK-сервер
- Масштабирование и многоарендность: Обрабатывайте множество пользователей в масштабах