Meilleur pour : Produits SaaS, intégrations de partenaires, plateformes internes et services principaux qui gèrent les utilisateurs simultanés.
Utilisez ce guide quand
Utilisez ce guide lorsque vous créez :
- Un produit SaaS multi-utilisateur qui intègre des agents basés sur Copilot
- Un backend pour une intégration partenaire, comme un modèle de type Copilot Studio ou Fabric
- Tout serveur qui gère les utilisateurs, espaces de travail, locataires ou demandes simultanés
- Runtime partagé où plusieurs clients du KIT de développement logiciel (SDK) se connectent à un processus d’exécution Copilot
Ce guide est une sœur de Mise à l’échelle et multilocation. Utilisez ce guide pour la topologie, l’équilibrage de charge et les modèles de stockage. Utilisez ce guide pour les options au niveau du SDK et les choix d’isolation du runtime.
Options du Kit de développement logiciel (SDK) clés
| Option | Utilisez-le pour | Remarques |
|---|---|---|
mode: "empty" | Désactivation des outils de système d’exploitation ambiants et des paramètres CLI par défaut | Requis pour les scénarios multi-utilisateurs ou partagés. |
sessionIdleTimeoutSeconds | Nettoyage des sessions inactives | Définissez un délai d’expiration côté serveur pour les processus de longue durée. |
baseDirectory | Isolation par instance d’exécution COPILOT_HOME | Ignoré lors de la connexion à un runtime existant. |
sessionFs | Routage du stockage du système de fichiers de session hors disque local | Associer des fournisseurs de systèmes de fichiers propres à chaque session. |
RuntimeConnection.forUri(url) | Partage d’un runtime déjà en cours d’exécution | Les noms de langue varient ; consultez les exemples ci-dessous. |
Par session gitHubToken | Limiter l’authentification à l’utilisateur demandeur | Préférez cela à un seul jeton d’utilisateur partagé. |
mode: "empty"
mode: "empty" désactive le comportement facultatif Copilot CLI par défaut. En mode serveur multi-utilisateur, il s’agit de la base de référence sécurisée, car votre application doit décider explicitement quels outils, serveurs MCP, compétences et chemins d’accès à l’espace de travail qu’une session peut accéder.
N’utilisez pas la valeur par défaut mode: "copilot-cli" pour les serveurs partagés. Ce mode est destiné aux agents de codage de type CLI et peut exposer les fonctionnalités du système de fichiers hôte ambiant.
import { CopilotClient, RuntimeConnection } from "@github/copilot-sdk";
// baseDirectory and sessionIdleTimeoutSeconds apply when the SDK spawns the
// runtime. With RuntimeConnection.forUri(...) configure COPILOT_HOME and the
// idle timeout on the runtime process itself.
const client = new CopilotClient({
mode: "empty",
connection: RuntimeConnection.forUri(process.env.COPILOT_RUNTIME_URL!),
});
const session = await client.createSession({
sessionId: `user-${user.id}-${crypto.randomUUID()}`,
model: "gpt-4.1",
availableTools: ["custom:lookupOrder", "custom:createTicket"],
gitHubToken: user.githubToken,
});
from copilot import CopilotClient, RuntimeConnection
from copilot.session import PermissionHandler
client = CopilotClient(
mode="empty",
base_directory=f"/var/lib/my-app/copilot/{runtime_instance_id}",
session_idle_timeout_seconds=900,
connection=RuntimeConnection.for_uri(runtime_url),
)
await client.start()
session = await client.create_session(
session_id=f"user-{user.id}-{request_id}",
model="gpt-4.1",
available_tools=["custom:lookupOrder", "custom:createTicket"],
github_token=user.github_token,
on_permission_request=PermissionHandler.approve_all,
)
package main
import (
"context"
"fmt"
copilot "github.com/github/copilot-sdk/go"
)
type appUser struct {
ID string
GitHubToken string
}
func main() {
ctx := context.Background()
runtimeInstanceID := "instance-1"
runtimeURL := "http://127.0.0.1:8080"
requestID := "req-1"
user := appUser{ID: "alice", GitHubToken: "YOUR_GITHUB_TOKEN"}
client := copilot.NewClient(&copilot.ClientOptions{
Mode: copilot.ModeEmpty,
BaseDirectory: fmt.Sprintf("/var/lib/my-app/copilot/%s", runtimeInstanceID),
SessionIdleTimeoutSeconds: 900,
Connection: copilot.URIConnection{URL: runtimeURL},
})
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-%s", user.ID, requestID),
Model: "gpt-4.1",
AvailableTools: []string{"custom:lookupOrder", "custom:createTicket"},
GitHubToken: user.GitHubToken,
})
_ = session
_ = err
}
client := copilot.NewClient(&copilot.ClientOptions{
Mode: copilot.ModeEmpty,
BaseDirectory: fmt.Sprintf("/var/lib/my-app/copilot/%s", runtimeInstanceID),
SessionIdleTimeoutSeconds: 900,
Connection: copilot.URIConnection{URL: runtimeURL},
})
session, err := client.CreateSession(ctx, &copilot.SessionConfig{
SessionID: fmt.Sprintf("user-%s-%s", user.ID, requestID),
Model: "gpt-4.1",
AvailableTools: []string{"custom:lookupOrder", "custom:createTicket"},
GitHubToken: user.GitHubToken,
})
using GitHub.Copilot;
var runtimeInstanceId = "instance-1";
var runtimeUrl = "http://127.0.0.1:8080";
var requestId = "req-1";
var user = new { Id = "alice", GitHubToken = "YOUR_GITHUB_TOKEN" };
var client = new CopilotClient(new CopilotClientOptions
{
Mode = CopilotClientMode.Empty,
BaseDirectory = $"/var/lib/my-app/copilot/{runtimeInstanceId}",
SessionIdleTimeoutSeconds = 900,
Connection = RuntimeConnection.ForUri(runtimeUrl),
});
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{user.Id}-{requestId}",
Model = "gpt-4.1",
AvailableTools = ["custom:lookupOrder", "custom:createTicket"],
GitHubToken = user.GitHubToken,
});
var client = new CopilotClient(new CopilotClientOptions
{
Mode = CopilotClientMode.Empty,
BaseDirectory = $"/var/lib/my-app/copilot/{runtimeInstanceId}",
SessionIdleTimeoutSeconds = 900,
Connection = RuntimeConnection.ForUri(runtimeUrl),
});
await using var session = await client.CreateSessionAsync(new SessionConfig
{
SessionId = $"user-{user.Id}-{requestId}",
Model = "gpt-4.1",
AvailableTools = ["custom:lookupOrder", "custom:createTicket"],
GitHubToken = user.GitHubToken,
});
import java.util.List;
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.CopilotClientOptions;
import com.github.copilot.rpc.CopilotClientMode;
import com.github.copilot.rpc.SessionConfig;
public class MultiTenancyExample {
record User(String id, String gitHubToken) {}
public static void main(String[] args) throws Exception {
String runtimeUrl = "http://localhost:4321";
String requestId = "req-1";
User user = new User("u1", "ghu_token");
// setCopilotHome and setSessionIdleTimeoutSeconds are ignored when
// setCliUrl is used; configure those on the runtime process instead.
var client = new CopilotClient(new CopilotClientOptions()
.setMode(CopilotClientMode.EMPTY)
.setCliUrl(runtimeUrl)
);
var session = client.createSession(new SessionConfig()
.setSessionId("user-" + user.id() + "-" + requestId)
.setModel("gpt-4.1")
.setAvailableTools(List.of("custom:lookupOrder", "custom:createTicket"))
.setGitHubToken(user.gitHubToken())
).get();
}
}
// setCopilotHome and setSessionIdleTimeoutSeconds are ignored when
// setCliUrl is used; configure those on the runtime process instead.
var client = new CopilotClient(new CopilotClientOptions()
.setMode(CopilotClientMode.EMPTY)
.setCliUrl(runtimeUrl)
);
var session = client.createSession(new SessionConfig()
.setSessionId("user-" + user.id() + "-" + requestId)
.setModel("gpt-4.1")
.setAvailableTools(List.of("custom:lookupOrder", "custom:createTicket"))
.setGitHubToken(user.gitHubToken())
).get();
use std::path::PathBuf;
use github_copilot_sdk::{Client, ClientOptions, Transport};
use github_copilot_sdk::mode::ClientMode;
use github_copilot_sdk::types::SessionConfig;
let client = Client::start(
ClientOptions::new()
.with_mode(ClientMode::Empty)
.with_base_directory(PathBuf::from(format!(
"/var/lib/my-app/copilot/{runtime_instance_id}"
)))
.with_session_idle_timeout_seconds(900)
.with_transport(Transport::External {
host: runtime_host.to_string(),
port: runtime_port,
connection_token: None,
}),
).await?;
let session = client.create_session(
SessionConfig::default()
.with_session_id(format!("user-{}-{request_id}", user.id))
.with_model("gpt-4.1")
.with_available_tools(["custom:lookupOrder", "custom:createTicket"])
.with_github_token(user.github_token),
).await?;
sessionIdleTimeoutSeconds
Configurez sessionIdleTimeoutSeconds sur des serveurs afin que les sessions inactives soient nettoyées automatiquement. Cela empêche les sessions zombies dans les processus de longue durée et réduit la sollicitation de la mémoire et du système de fichiers.
| Language | Option publique |
|---|---|
| TypeScript | sessionIdleTimeoutSeconds |
| Python | session_idle_timeout_seconds |
| Go | SessionIdleTimeoutSeconds |
| .NET | SessionIdleTimeoutSeconds |
| Java | setSessionIdleTimeoutSeconds(...) |
| Rust | with_session_idle_timeout_seconds(...) |
Utilisez une valeur qui correspond à la durée de vie de la conversation de votre produit. Pour les back-ends de conversation, 15 à 30 minutes est généralement un bon point de départ. Pour les agents de flux de travail, utilisez un délai d’expiration plus long et une suppression explicite lorsque le flux de travail est terminé.
baseDirectory
baseDirectory définit COPILOT_HOME pour une instance d’exécution. Utilisez-le pour isoler l’état d’exécution, les informations d’authentification et les données de session pour chaque processus, pod, processus de travail ou périmètre du locataire.
const client = new CopilotClient({
mode: "empty",
baseDirectory: `/var/lib/my-app/copilot/runtime-${process.env.HOSTNAME}`,
sessionIdleTimeoutSeconds: 900,
});
Le runtime stocke l’état de session sous le fichier configuré COPILOT_HOME, y compris session-state/{sessionId}. Si votre application exécute plusieurs instances d’exécution, donnez à chaque instance un répertoire distinct, sauf si vous utilisez intentionnellement le stockage partagé.
Lorsque le SDK se connecte à un environnement d’exécution déjà en cours d’exécution avec RuntimeConnection.forUri(url), baseDirectory est ignoré par le client SDK. Configurez COPILOT_HOME plutôt sur le processus d’exécution.
sessionFs
sessionFs inscrit un fournisseur de système de fichiers de session personnalisé afin que les E/S de fichiers délimitées à la session puissent être routées via le stockage d’applications au lieu du disque local du runtime. Utilisez-le lorsque le disque local est éphémère, lorsque l’état de session doit être conservé dans un stockage objet, ou lorsqu’une plateforme doit imposer des chemins de stockage adaptés aux locataires.
const client = new CopilotClient({
mode: "empty",
sessionFs: {
initialCwd: "/workspace",
sessionStatePath: "/session-state",
conventions: "posix",
},
});
Pour les langues qui exposent un rappel de fournisseur, configurez sessionFs au niveau du client et fournissez un gestionnaire de système de fichiers par session lors de la création ou de la reprise d’une session. Consultez Reprise de session et persistance pour connaître les concepts de persistance et les compromis de stockage.
Surfaces du SDK public vérifiées :
| Language | Configuration au niveau du client | Fournisseur par session |
|---|---|---|
| TypeScript | sessionFs | |
createSessionFsAdapter / rappels de fournisseurs | ||
| Python | session_fs | create_session_fs_handler |
| Go | SessionFS | CreateSessionFSProvider |
| .NET | SessionFs | CreateSessionFsProvider |
| Rust | with_session_fs(...) | with_session_fs_provider(...) |
Java n’expose pas actuellement une option sessionFs publique vérifiée. Ce guide n’affiche donc pas d’exemple Java sessionFs.
RuntimeConnection.forUri(url)
Utilisez une connexion d’exécution externe lorsque plusieurs clients du KIT de développement logiciel (SDK) doivent partager un runtime déjà en cours d’exécution. Cela est courant dans les services principaux où le processus d’exécution est géré séparément des gestionnaires de requêtes.
| Language | Connexion au runtime externe |
|---|---|
| TypeScript | RuntimeConnection.forUri(url) |
| Python | RuntimeConnection.for_uri(url) |
| Go | copilot.URIConnection{URL: url} |
| .NET | RuntimeConnection.ForUri(url) |
| Java | setCliUrl(url) |
| Rust | Transport::External { host, port, connection_token } |
Les runtimes externes gèrent leur propre authentification et stockage au niveau du processus. Transmettez des jetons propres à chaque session sur createSession ou resumeSession si vous avez besoin d’une authentification propre à l’utilisateur.
Par session gitHubToken
Définissez gitHubToken pour chaque session afin de limiter l’authentification GitHub à l’utilisateur demandeur. Cela diffère d’un jeton au niveau du client, qui authentifie le processus d’exécution.
const session = await client.createSession({
sessionId: `user-${user.id}-support`,
model: "gpt-4.1",
availableTools: ["custom:*"],
gitHubToken: user.githubToken,
});
Utilisez des jetons de session pour l’exclusion de contenus, le routage du modèle, la vérification des quotas et l’accès à Copilot propre à l’utilisateur. Évitez de partager un jeton de service entre les utilisateurs, sauf si votre produit utilise intentionnellement la sémantique du compte de service.
ID d’intégration
Les partenaires qui créent des agents de marque peuvent définir un ID d’intégration pour les demandes Mission Control. Le runtime lit GITHUB_COPILOT_INTEGRATION_ID et le marque comme en-tête HTTP Copilot-Integration-Id sur chaque requête Mission Control.
GITHUB_COPILOT_INTEGRATION_ID=my-product-agent copilot --headless --port 4321
L’ID d’intégration par défaut est copilot-developer-cli. Utilisez une valeur stable telle que my-product-agent pour l’attribution et le routage. L’ID d’intégration est actuellement configuré par variable d’environnement uniquement ; il ne s’agit pas d’une option de KIT DE développement logiciel (SDK) de première classe.
Si le Kit de développement logiciel (SDK) génère le runtime, transmettez la variable d’environnement via l’option d’environnement client. Si vous vous connectez avec RuntimeConnection.forUri(url), définissez la variable d’environnement sur le processus d’exécution lui-même.
Garanties d’isolation au niveau de la session
L’isolation au niveau de la session signifie que le runtime conserve les informations de modèle et d’état spécifiques à l’utilisateur limitées à une session, et non dans un état partagé global.
| Surface | Comportement d’isolation |
|---|---|
| Cache de liste de modèles | Par session. La recherche de modèle utilise le cache de liste de modèles de la session. |
| État de session | Par identifiant de session sous COPILOT_HOME/session-state/{sessionId}. |
| identité GitHub | Par session lorsque gitHubToken est défini sur la session. |
| Tools | Explicite en mode: "empty"; ambiante dans mode: "copilot-cli". |
| Système de fichiers hôte | Partagé par le processus d’exécution si les outils hôtes sont disponibles. |
mode: "empty" est ce qui rend les modèles d’exécution partagés viables : aucun outil de système d’exploitation ambiant n’est exposé, sauf si votre application s’inscrit ou les autorise. Avec mode: "copilot-cli", l’accès au système de fichiers du système d’exploitation est partagé via le processus hôte. N’utilisez donc pas ce mode pour le mode serveur multi-utilisateur.
L’état de session est stocké sous COPILOT_HOME/session-state/{sessionId} , sauf si vous l’acheminez jusqu’à sessionFs. Utilisez des ID de session uniques qui incluent votre propre locataire ou limite utilisateur et appliquez le contrôle d’accès avant de reprendre ou de supprimer des sessions.
Comparaison des modèles
| Motif | À utiliser lorsque | Trade-offs |
|---|---|---|
| Modèle 1 : interface CLI isolée par utilisateur | Vous avez besoin de la limite d’isolation la plus forte ou d’informations d’identification de processus distinctes par utilisateur. | Isolation forte ; coût des ressources plus élevé. Consultez « Mise à l’échelle et multilocation ». |
Modèle 2 : interface CLI partagée avec mode: "empty" | Vous souhaitez qu’un runtime serve de nombreux utilisateurs pendant que votre application contrôle les outils, l’authentification et les ID de session. | Efficace; nécessite une inscription minutieuse des outils, des jetons par session et des vérifications d’accès au niveau de l’application. |
| Modèle 3 : hybride | Vous routez le travail lourd sur le calcul vers les sessions cloud et le travail léger vers les sessions locales. | Flexible; nécessite le routage des charges de travail et la gestion des stratégies. Consultez « Sessions dans le cloud ». |
Modèle 2 : interface CLI partagée avec mode: "empty"
Dans ce modèle, tous les utilisateurs se connectent via votre back-end à un pool d’exécution. L'application assure l'authentification des utilisateurs, choisit un identifiant de session, transmet le jeton GitHub de l'utilisateur dans la session et fournit une liste d'autorisation explicite d'outils.

Utilisez ces règles :
- Démarrez toujours le client ou le runtime dans
mode: "empty". - Utilisez des ID de session uniques et stockez les métadonnées de propriété dans votre base de données d’application.
- Vérifiez la propriété avant
resumeSession,deleteSessionou toute action d’interface utilisateur qui référence un ID de session. - Transmettez
gitHubTokenpar session lorsque les requêtes doivent être exécutées en tant qu’utilisateur. - Inscrivez uniquement les outils dont la session a besoin et préférez les listes d’autorisation qualifiées sources telles que
custom:*oumcp:search_docs. - Définissez et supprimez
sessionIdleTimeoutSecondsexplicitement les sessions de flux de travail terminées.
Pièges courants
- Oubli de
mode: "empty". Le mode par défautcopilot-cliexpose le comportement de style CLI et peut exposer le système de fichiers hôte via des outils ambiants. - Ne pas définir
sessionIdleTimeoutSeconds. Les serveurs de longue durée peuvent accumuler des sessions inactives s’ils ne les nettoient pas. - Partage d’un
gitHubTokenentre les utilisateurs au lieu de transmettre un jeton propre à chaque session. - Approbation des ID de session fournis par le client sans vérifier la propriété dans votre back-end.
- Définir
baseDirectorysur un client qui se connecte à un runtime existant en s’attendant à ce que cela déplace le stockage du runtime. Configurez plutôt le processus d’exécution. - Autoriser des modèles d’outils étendus tels que
builtin:*sans examiner si chaque outil est approprié pour vos utilisateurs.
Voir également :
- Mise à l’échelle et multilocation : topologies de déploiement, modèles de stockage et comparaisons d’isolation
- Configuration des services principaux : exécution du runtime en mode serveur sans tête
- BYOK (apportez votre propre clé) : utilisation de vos propres identifiants de fournisseur de modèle
- Sessions dans le cloud : routage sélectionné du travail vers des sessions cloud
- Reprise de session et persistance : gestion de l’état de session pouvant être repris
- Fonctionnalités : outils, événements, hooks et fonctionnalités avancées du Kit de développement logiciel (SDK)