Skip to main content

GitHub OAuth のセットアップ

ユーザーが自分のGitHub アカウントで認証を行い、アプリケーションでCopilotを使用できるようにします。 これにより、個々のアカウント、組織のメンバーシップ、およびエンタープライズ ID がサポートされます。

ベスト for: マルチユーザー アプリ、組織アクセス制御を備えた内部ツール、SaaS 製品、ユーザーがGitHubアカウントを持つアプリ。

どのように機能するのか

GitHub OAuth アプリ (または GitHub アプリ) を作成し、ユーザーがそれを承認し、アクセス トークンを SDK に渡します。 Copilot要求は、Copilot サブスクリプションを使用して、認証された各ユーザーに代わって行われます。

図: 説明されたプロセスを示すシーケンス図。

主な特性:

  • 各ユーザーは、独自のGitHub アカウントで認証します
  • Copilot使用量は各ユーザーのサブスクリプションに課金されます
  • GitHub の組織アカウントとエンタープライズ アカウントをサポート
  • アプリがモデル API キーを処理することはありません。GitHubはすべてを管理します

Architecture

図: 説明されたプロセスを示すフローチャート。

手順 1: GitHub OAuth アプリを作成する

  1. [GitHub Settings → Developer Settings → OAuth Apps → New OAuth App (または組織の場合: 開発者設定→開発者向け設定) に移動します。

  2. 次の項目を入力します。

    • アプリケーション名: アプリの名前
    • ホーム ページ URL: アプリの URL
    • 承認コールバック URL: OAuth コールバック エンドポイント (例: https://yourapp.com/auth/callback)
  3. クライアント ID をメモし、クライアント シークレットを生成する

GitHub アプリと OAuth アプリ: 両方とも機能します。 GitHub Apps では、よりきめ細かいアクセス許可が提供され、新しいプロジェクトに推奨されます。 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 Enterprise Managed Users、フローは同じです。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 App のユーザー アクセス トークン
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

リソース占有領域を軽くするために、1 つの外部 CLI サーバーを実行し、セッションごとにトークンを渡すことができます。 このパターンについては 、AUTOTITLE を参照してください。

制限事項

制限事項詳細情報
Copilot サブスクリプションが必要です各ユーザーにはアクティブなCopilot サブスクリプションが必要です
トークン管理はユーザーの責任です保存、更新、および有効期限の処理
GitHub アカウントが必要ですユーザーはGitHubアカウントを持っている必要があります
ユーザーあたりのレート制限各ユーザーのCopilotレート制限に従う

次に進むタイミング

必要次のガイドへ
GitHub アカウントを持たないユーザー
BYOK (bring your own key)
サーバーで SDK を実行する
バックエンド サービスのセットアップ
多数の同時実行ユーザーを処理する
スケーリングとマルチテナント

次のステップ