Best for: aplicativos multiusuários, ferramentas internas com controle de acesso da organização, produtos SaaS, aplicativos em que os usuários têm contas GitHub.
Como funciona
Você cria um aplicativo OAuth GitHub (ou GitHub App), os usuários o autorizam e transmitem o token de acesso para o SDK. As solicitações do Copilot são feitas em nome de cada usuário autenticado, usando sua assinatura do Copilot.

Principais características:
- Cada usuário autentica com sua própria conta de GitHub
- O uso do Copilot é cobrado na assinatura de cada usuário
- Oferece suporte a organizações do GitHub e contas empresariais
- Seu aplicativo nunca lida com chaves de API de modelo — GitHub gerencia tudo
Architecture

Etapa 1: criar um aplicativo OAuth GitHub
-
Acesse GitHub Configurações → Configurações do Desenvolvedor → Aplicativos OAuth → Novo Aplicativo OAuth (ou para organizações: configurações de Organização → configurações do desenvolvedor)
-
Preencha:
- Nome do aplicativo: nome do seu aplicativo
- URL da home page: URL do aplicativo
- URL de callback de autorização: Seu endpoint de callback do OAuth (por exemplo,
https://yourapp.com/auth/callback)
-
Anote a ID do cliente e gere um segredo do cliente
GitHub App vs OAuth App: Ambos funcionam. os aplicativos GitHub oferecem permissões mais refinadas e são recomendados para novos projetos. Os Aplicativos OAuth são mais simples de configurar. O fluxo de token é o mesmo da perspectiva do SDK.
Etapa 2: implementar o fluxo OAuth
Seu aplicativo lida com o fluxo OAuth de GitHub padrão. Aqui está a troca de tokens do lado do servidor:
// 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
}
Etapa 3: passar o token para o SDK
Crie um cliente SDK para cada usuário autenticado, passando seu token:
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();
}
Acesso empresarial e organizacional
GitHub OAuth naturalmente dá suporte a cenários empresariais. Quando os usuários se autenticam com o GitHub, seus vínculos com organizações e empresas também são trazidos junto.

Verificar a associação à organização
Após o OAuth, verifique se o usuário pertence à sua organização:
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);
Usuários corporativos gerenciados (EMU)
Para Usuários Gerenciados do GitHub Enterprise, o fluxo é idêntico: os usuários do EMU se autenticam via GitHub OAuth como qualquer outro usuário. Suas políticas corporativas (restrições de IP, SSO do SAML) são impostas por GitHub automaticamente.
// 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,
});
Tipos de token com suporte
| Prefixo de token | Fonte | Funciona? |
|---|---|---|
gho_ | Token de acesso do usuário OAuth | ✅ |
ghu_ | token de acesso do usuário do aplicativo GitHub | ✅ |
github_pat_ | Token de acesso pessoal refinado | ✅ |
ghp_ | Token de acesso pessoal clássico | |
| ❌ (preterido) |
Ciclo de vida do token

Importante: Seu aplicativo é responsável pelo armazenamento de tokens, atualização e tratamento de expiração. O SDK usa qualquer token fornecido, ele não gerencia o ciclo de vida do OAuth.
Padrão de atualização de token
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");
}
Padrões de vários usuários
Um cliente por usuário (recomendado)
Cada usuário obtém seu próprio cliente SDK com seu próprio token. Isso fornece o isolamento mais forte.
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 compartilhada com tokens por solicitação
Para um menor consumo de recursos, você pode executar um único servidor CLI externo e fornecer tokens por sessão. Consulte Configuração de serviços de back-end para esse padrão.
Limitações
| Limitation | Detalhes |
|---|---|
| Assinatura do Copilot necessária | Cada usuário precisa de uma assinatura de Copilot ativa |
| O gerenciamento de tokens é sua responsabilidade | Armazenar, renovar e gerenciar a expiração |
| GitHub conta necessária | Os usuários devem ter contas GitHub |
| Limites de taxa por usuário | Sujeito aos limites de uso do Copilot de cada usuário |
Quando seguir em frente
| Necessidade | Próximo Guia |
|---|---|
| Usuários sem contas de GitHub | |
| BYOK (bring your own key) | |
| Executar o SDK em servidores | |
| Configuração de serviços de back-end | |
| Manipular muitos usuários simultâneos | |
| Escalabilidade e multitenância |
Próximas Etapas
- Autenticação: Referência completa do método de autenticação
- Configuração de serviços de back-end: Executar o SDK no servidor
- Escalabilidade e multitenância: Lidar com muitos usuários em grande escala