Skip to main content

Настройка GitHub OAuth

Позвольте пользователям аутентифицироваться через свои аккаунты GitHub, чтобы использовать Copilot через ваше приложение. Это поддерживает индивидуальные аккаунты, членства организаций и корпоративные идентичности.

Лучше всего для: Многопользовательских приложений, внутренних инструментов с управлением доступом к организации, SaaS-продуктов, приложений, где у пользователей есть GitHub аккаунты.

Принцип работы

Вы создаёте OAuth приложение GitHub (или приложение GitHub), пользователи его авторизуют, и вы передаёте их токен доступа SDK. Запросы на Copilot выполняются от имени каждого аутентифицированного пользователя с использованием их подписки Copilot.

Диаграмма: диаграмма последовательностей, показывающая описанный процесс.

Ключевые характеристики:

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

Architecture

Диаграмма: блок-схема, показывающая описанный процесс.

Шаг 1: создать приложение GitHub OAuth

  1. Перейдите в GitHub Настройки → Настройки разработчика → OAuth Apps → New OAuth App (или для организаций: Настройки организации → Настройки разработчика)

  2. Заполните:

    • Название приложения: Название вашего приложения
    • URL главной страницы: URL вашего приложения
    • URL обратного вызова авторизации: ваша конечная точка обратного вызова OAuth (например, https://yourapp.com/auth/callback)
  3. Запишите свой клиентский идентификатор и сгенерируйте секрет клиента

**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-клиент для каждого аутентифицированного пользователя, передавая их токен:

TypeScript
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!" });
Python
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!")
Go
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!"})
.NET
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!" });
Java
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-сервер и передавать токены за сессию. См. Настройка серверных сервисов для этой схемы.

Ограничения

LimitationDetails
Copilot требуется подпискаКаждому пользователю нужна активная подписка на Copilot
Управление токенами — ваша ответственностьХраните, обновляйте и обрабатывайте истечение срока действия
GitHub требуется аккаунтПользователи должны иметь аккаунты GitHub
Ограничения по скорости на пользователяС учётом лимитов Copilot каждого пользователя

Когда двигаться дальше

НеобходимостьСледующее руководство
Пользователи без аккаунтов GitHub
BYOK (bring your own key)
Запускайте SDK на серверах
Настройка серверных сервисов
Работа с множеством одновременных пользователей
Масштабирование и многоарендность

Дальнейшие действия