Skip to main content

Configuración de OAuth de GitHub

Permitir que los usuarios se autentiquen con sus cuentas de GitHub para usar Copilot a través de la aplicación. Esto admite cuentas individuales, pertenencias a la organización e identidades empresariales.

Best for: aplicaciones multiusuario, herramientas internas con control de acceso de la organización, productos SaaS, aplicaciones donde los usuarios tienen cuentas de GitHub.

Cómo funciona

Creas una aplicación OAuth de GitHub (o una GitHub App), los usuarios la autorizan y pasas su token de acceso al SDK. Las solicitudes de Copilot se realizan en nombre de cada usuario autenticado, usando su suscripción de Copilot.

Diagrama: diagrama de secuencia que muestra el proceso descrito.

Características principales:

  • Cada usuario se autentica con su propia cuenta de GitHub
  • El uso de Copilot se factura a la suscripción de cada usuario.
  • Admite organizaciones de GitHub y cuentas Enterprise
  • La aplicación nunca controla las claves de API del modelo, GitHub administra todo

Architecture

Diagrama: Diagrama de flujo que muestra el proceso descrito.

Paso 1: crear una aplicación de GitHub OAuth

  1. Vaya a GitHub Configuración → Configuración del desarrollador → Aplicaciones de OAuth → Nueva aplicación de OAuth (o para organizaciones: Configuración de organización → Configuración del desarrollador)

  2. Rellene:

    • Nombre de la aplicación: nombre de la aplicación
    • Dirección URL de la página principal: dirección URL de la aplicación
    • URL de callback de autorización: Su endpoint de callback de OAuth (p. ej., https://yourapp.com/auth/callback)
  3. Anote el identificador de cliente y genere un secreto de cliente.

GitHub App vs OAuth App: Ambos funcionan. GitHub Apps ofrecen permisos más específicos y se recomiendan para los nuevos proyectos. Las aplicaciones de OAuth son más sencillas de configurar. El flujo de tokens es el mismo desde la perspectiva del SDK.

Paso 2: implementar el flujo de OAuth

La aplicación controla el flujo estándar de GitHub OAuth. Este es el intercambio de tokens del lado 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
}

Paso 3: pasar el token al SDK

Cree un cliente del SDK para cada usuario autenticado y pase su token:

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();
}

Acceso empresarial y organizacional

GitHub OAuth admite naturalmente escenarios empresariales. Cuando los usuarios se autentican con GitHub, sus pertenencias a la organización y las asociaciones empresariales se unen.

Diagrama: Diagrama de flujo que muestra el proceso descrito.

Comprobación de la pertenencia a la organización

Después de OAuth, compruebe que el usuario pertenece a su organización:

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);

Usuarios administrados por la empresa (EMU)

Para los Enterprise Managed Users de GitHub, el flujo es idéntico: los usuarios de EMU se autentican mediante GitHub OAuth como cualquier otro usuario. GitHub aplica automáticamente sus políticas empresariales (restricciones de IP, inicio de sesión único mediante SAML).

// 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 admitidos

Prefijo de tokenSource¿Trabajas?
gho_Token de acceso de usuario de OAuth
ghu_token de acceso de usuario de GitHub app
github_pat_Token de acceso personal específico
ghp_Token de acceso personal clásico
❌ (en desuso)

Ciclo de vida de los tokens

Diagrama: Diagrama de flujo que muestra el proceso descrito.

Importante: La aplicación es responsable del almacenamiento de tokens, la actualización y el control de expiración. El SDK usa el token que proporcione: no administra el ciclo de vida de OAuth.

Patrón de actualización de tokens

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");
}

Patrones multiusuario

Cada usuario obtiene su propio cliente del SDK con su propio token. Esto proporciona el aislamiento más fuerte.

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 compartida con tokens por solicitud

Para un menor consumo de recursos, puede ejecutar un único servidor CLI externo y pasar tokens en cada sesión. Consulte Configuración de servicios back-end para obtener este patrón.

Limitaciones

LimitaciónDetalles
Se requiere una suscripción a CopilotCada usuario necesita una suscripción de Copilot activa
La administración de tokens es su responsabilidadAlmacenar, actualizar y controlar la expiración
GitHub cuenta necesariaLos usuarios deben tener cuentas de GitHub
Límites de velocidad por usuarioSujeto a los límites de velocidad de Copilot de cada usuario

Cuándo seguir adelante

RequisitoGuía siguiente
Usuarios sin cuentas de GitHub
BYOK (bring your own key)
Ejecución del SDK en servidores
Configuración de servicios back-end
Control de muchos usuarios simultáneos
Escalabilidad y multitenencia

Pasos siguientes