# BYOK (apportez votre propre clé)

BYOK vous permet d’utiliser le kit de développement logiciel (SDK) Copilot avec vos propres clés API auprès de fournisseurs de modèles, en contournant l’authentification GitHub Copilot. Cela est utile pour les déploiements d’entreprise, l’hébergement de modèles personnalisés ou lorsque vous souhaitez une facturation directe avec votre fournisseur de modèles.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

## Fournisseurs pris en charge

| Provider                         | Type de valeur                                                                                          | Remarques                                                                         |
| -------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| OpenAI                           | `"openai"`                                                                                              | API OpenAI et points de terminaison compatibles OpenAI                            |
| Microsoft Foundry / Azure OpenAI |                                                                                                         |                                                                                   |
| `"openai"` ou `"azure"`          | Utilisez `/openai/v1/` pour `"azure"` ; utilisez `"openai"` pour les points de terminaison Azure natifs |                                                                                   |
| Anthropic                        | `"anthropic"`                                                                                           | Modèles Claude                                                                    |
| Ollama                           | `"openai"`                                                                                              | Modèles locaux via l’API compatible OpenAI                                        |
| Microsoft Foundry Local          | `"openai"`                                                                                              | Exécuter des modèles IA localement sur votre appareil via l’API compatible OpenAI |
| Autres compatibles avec OpenAI   | `"openai"`                                                                                              | vLLM, LiteLLM, etc.                                                               |

## Démarrage rapide : Microsoft Foundry

Microsoft Foundry est une cible de déploiement BYOK commune pour les entreprises. Voici un exemple complet :

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
import asyncio
import os
from copilot import CopilotClient
from copilot.session import PermissionHandler

FOUNDRY_MODEL_URL = "https://<resource-name>.openai.azure.com/openai/v1/"
# Set FOUNDRY_API_KEY environment variable

async def main():
    client = CopilotClient()
    await client.start()

    session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-5.2-codex", provider={
        "type": "openai",
        "base_url": FOUNDRY_MODEL_URL,
        "wire_api": "responses",  # Use "completions" for older models
        "api_key": os.environ["FOUNDRY_API_KEY"],
    })

    done = asyncio.Event()

    def on_event(event):
        if event.type.value == "assistant.message":
            print(event.data.content)
        elif event.type.value == "session.idle":
            done.set()

    session.on(on_event)
    await session.send("What is 2+2?")
    await done.wait()

    await session.disconnect()
    await client.stop()

asyncio.run(main())
```

</div>

<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
import { CopilotClient } from "@github/copilot-sdk";

const FOUNDRY_MODEL_URL = "https://<resource-name>.openai.azure.com/openai/v1/";

const client = new CopilotClient();
const session = await client.createSession({
    model: "gpt-5.2-codex",  // Your deployment name
    provider: {
        type: "openai",
        baseUrl: FOUNDRY_MODEL_URL,
        wireApi: "responses",  // Use "completions" for older models
        apiKey: process.env.FOUNDRY_API_KEY,
    },
});

session.on("assistant.message", (event) => {
    console.log(event.data.content);
});

await session.sendAndWait({ prompt: "What is 2+2?" });
await client.stop();
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
package main

import (
    "context"
    "fmt"
    "os"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    ctx := context.Background()
    client := copilot.NewClient(nil)
    if err := client.Start(ctx); err != nil {
        panic(err)
    }
    defer client.Stop()

    session, err := client.CreateSession(ctx, &copilot.SessionConfig{
        Model: "gpt-5.2-codex",  // Your deployment name
        Provider: &copilot.ProviderConfig{
            Type:    "openai",
            BaseURL: "https://<resource-name>.openai.azure.com/openai/v1/",
            WireAPI: "responses",  // Use "completions" for older models
            APIKey:  os.Getenv("FOUNDRY_API_KEY"),
        },
    })
    if err != nil {
        panic(err)
    }

    response, err := session.SendAndWait(ctx, copilot.MessageOptions{
        Prompt: "What is 2+2?",
    })
    if err != nil {
        panic(err)
    }

    if d, ok := response.Data.(*copilot.AssistantMessageData); ok {
        fmt.Println(d.Content)
    }
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
using GitHub.Copilot;

await using var client = new CopilotClient();
await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-5.2-codex",  // Your deployment name
    Provider = new ProviderConfig
    {
        Type = "openai",
        BaseUrl = "https://<resource-name>.openai.azure.com/openai/v1/",
        WireApi = "responses",  // Use "completions" for older models
        ApiKey = Environment.GetEnvironmentVariable("FOUNDRY_API_KEY"),
    },
});

var response = await session.SendAndWaitAsync(new MessageOptions
{
    Prompt = "What is 2+2?",
});
Console.WriteLine(response?.Data.Content);
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;

var client = new CopilotClient();
client.start().get();

var session = client.createSession(new SessionConfig()
    .setModel("gpt-5.2-codex")  // Your deployment name
    .setOnPermissionRequest(PermissionHandler.APPROVE_ALL)
    .setProvider(new ProviderConfig()
        .setType("openai")
        .setBaseUrl("https://<resource-name>.openai.azure.com/openai/v1/")
        .setWireApi("responses")  // Use "completions" for older models
        .setApiKey(System.getenv("FOUNDRY_API_KEY")))
).get();

var response = session.sendAndWait(new MessageOptions()
    .setPrompt("What is 2+2?")).get();
System.out.println(response.getData().content());

client.stop().get();
```

</div>

</div>

## Informations de référence sur la configuration du fournisseur

### Les champs "ProviderConfig"

| Champ                                                                                                                                                                                                                                                                                                                                                                        | Type   | Description                                                                                                                                                                            |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type`                                                                                                                                                                                                                                                                                                                                                                       |        |                                                                                                                                                                                        |
| `"openai"`                                                                                                                                                                                                                                                                                                                                                                   |        |                                                                                                                                                                                        |
| \|                                                                                                                                                                                                                                                                                                                                                                           |        |                                                                                                                                                                                        |
| `"azure"`                                                                                                                                                                                                                                                                                                                                                                    |        |                                                                                                                                                                                        |
| \|                                                                                                                                                                                                                                                                                                                                                                           |        |                                                                                                                                                                                        |
| `"anthropic"`                                                                                                                                                                                                                                                                                                                                                                |        |                                                                                                                                                                                        |
| Type de fournisseur (valeur par défaut : `"openai"`)                                                                                                                                                                                                                                                                                                                         |        |                                                                                                                                                                                        |
| `baseUrl` / `base_url`                                                                                                                                                                                                                                                                                                                                                       | string |                                                                                                                                                                                        |
| **Obligatoire.** URL du point de terminaison d’API                                                                                                                                                                                                                                                                                                                           |        |                                                                                                                                                                                        |
| `apiKey` / `api_key`                                                                                                                                                                                                                                                                                                                                                         | string | Clé API (facultative pour les fournisseurs locaux comme Ollama)                                                                                                                        |
| `bearerToken` / `bearer_token`                                                                                                                                                                                                                                                                                                                                               | string | Authentification par jeton Bearer (prend le pas sur apiKey)                                                                                                                            |
| `bearerTokenProvider` / `bearer_token_provider`                                                                                                                                                                                                                                                                                                                              | rappel | Renvoie un jeton Bearer à la demande (a priorité sur `apiKey` et `bearerToken`)                                                                                                        |
| `wireApi` / `wire_api`                                                                                                                                                                                                                                                                                                                                                       |        |                                                                                                                                                                                        |
| `"completions"`                                                                                                                                                                                                                                                                                                                                                              |        |                                                                                                                                                                                        |
| \|                                                                                                                                                                                                                                                                                                                                                                           |        |                                                                                                                                                                                        |
| `"responses"`                                                                                                                                                                                                                                                                                                                                                                |        |                                                                                                                                                                                        |
| Sélectionnez `"completions"` pour une compatibilité étendue avec les modèles (l’API Chat Completions) ; sélectionnez `"responses"` pour la gestion de l’état des conversations à plusieurs tours, l’espacement des noms des outils et la prise en charge du raisonnement (l’API Responses). Anthropic modèles utilisent toujours l’API Messages, quel que soit ce paramètre. |        |                                                                                                                                                                                        |
| `azure.apiVersion` / `azure.api_version`                                                                                                                                                                                                                                                                                                                                     | string | Version de l’API Azure. Lorsqu’il est défini, l’environnement d’exécution utilise la route de déploiement versionnée ; lorsqu’il est omis, il utilise la route GA non versionnée `v1`. |

### Format de l’API Wire

Le `wireApi` paramètre détermine le format d’API OpenAI à utiliser :

* **`"completions"`** (par défaut) - API Chat Completions (`/chat/completions`) pour une large compatibilité des modèles.
* **`"responses"`** - API Responses pour la gestion de l’état sur plusieurs tours, l’espace de noms des outils et la prise en charge du raisonnement.

Anthropic modèles utilisent toujours l’API messages Anthropic quel que soit ce paramètre.

### Notes spécifiques au type

**OpenAI (`type: "openai"`)**

* Fonctionne avec l’API OpenAI et tout point de terminaison compatible OpenAI
* `baseUrl` doit inclure le chemin complet (par exemple, `https://api.openai.com/v1`)

**Azure (`type: "azure"`)**

* Utilisez pour les points de terminaison natifs Azure OpenAI
* `baseUrl` doit être juste l’hôte (par exemple, `https://my-resource.openai.azure.com`)
* Ne pas inclure `/openai/v1` dans l’URL : le KIT de développement logiciel gère la construction du chemin d’accès

**Anthropic (`type: "anthropic"`)**

* Pour l’accès direct à l’API Anthropic
* Utilise le format d’API spécifique à Claude

## Exemples de configurations

### OpenAI direct

```typescript
provider: {
    type: "openai",
    baseUrl: "https://api.openai.com/v1",
    apiKey: process.env.OPENAI_API_KEY,
}
```

### Azure OpenAI (point de terminaison Azure natif)

Utiliser `type: "azure"` pour les points de terminaison à l’adresse `*.openai.azure.com`:

```typescript
provider: {
    type: "azure",
    baseUrl: "https://my-resource.openai.azure.com",  // Just the host
    apiKey: process.env.AZURE_OPENAI_KEY,
    azure: {
        apiVersion: "2024-10-21",
    },
}
```

### Microsoft Foundry (point de terminaison compatible OpenAI)

Pour les déploiements Microsoft Foundry avec des points de terminaison `/openai/v1/`, utilisez `type: "openai"` :

```typescript
provider: {
    type: "openai",
    baseUrl: "https://<resource-name>.openai.azure.com/openai/v1/",
    apiKey: process.env.FOUNDRY_API_KEY,
    wireApi: "responses",  // For GPT-5 series models
}
```

### Ollama (local)

```typescript
provider: {
    type: "openai",
    baseUrl: "http://localhost:11434/v1",
    // No apiKey needed for local Ollama
}
```

### Microsoft Foundry Local

[Microsoft Foundry Local](https://foundrylocal.ai) vous permet d’exécuter des modèles IA localement sur votre propre appareil avec une API compatible OpenAI. Installez-le via l’interface CLI locale Foundry, puis pointez le SDK sur votre point de terminaison local :

```typescript
provider: {
    type: "openai",
    baseUrl: "http://localhost:<PORT>/v1",
    // No apiKey needed for local Foundry Local
}
```

> \[!NOTE]
> Foundry Local démarre sur un **port dynamique** — le port n’est pas fixe. Utilisez `foundry service status` pour confirmer le port sur lequel le service écoute actuellement, puis utilisez ce port dans votre `baseUrl`.

Pour bien démarrer avec Foundry Local :

```bash
# Windows: Install Foundry Local CLI (requires winget)
winget install Microsoft.FoundryLocal

# macOS / Linux: see https://foundrylocal.ai for installation instructions
# List available models
foundry model list

# Run a model (starts the local server automatically)
foundry model run phi-4-mini

# Check the port the service is running on
foundry service status
```

### Anthropic

```typescript
provider: {
    type: "anthropic",
    baseUrl: "https://api.anthropic.com",
    apiKey: process.env.ANTHROPIC_API_KEY,
}
```

### Authentification par jeton porteur

Certains fournisseurs nécessitent une authentification par jeton du porteur au lieu de clés API. Fournissez un jeton statique avec `bearerToken`, ou fournissez une fonction de rappel `bearerTokenProvider` que le runtime du SDK GitHub Copilot invoque avant les requêtes sortantes adressées au fournisseur. La bibliothèque de rappel ou d’identité qu’elle encapsule gère la mise en cache et l’actualisation des jetons.

Utilisez `bearerToken` quand votre application a déjà un jeton :

```typescript
provider: {
    type: "openai",
    baseUrl: "https://<resource-name>.openai.azure.com/openai/v1/",
    bearerToken: process.env.MY_BEARER_TOKEN,  // Sets Authorization header
}
```

> \[!NOTE]
> L’option `bearerToken` accepte uniquement une **chaîne de jeton statique** . Le Kit de développement logiciel (SDK) n’actualise pas automatiquement ce jeton. Si votre jeton expire, les demandes échouent et vous devez créer une session avec un nouveau jeton.

Utilisez `bearerTokenProvider` pour obtenir des jetons à la demande :

<!-- docs-validate: skip -->

```typescript
provider: {
    type: "openai",
    baseUrl: "https://my-custom-endpoint.example.com/v1",
    bearerTokenProvider: async () => {
        return await acquireBearerToken();
    },
}
```

Pour plus d’informations sur l’acquisition et le renouvellement des jetons de support Microsoft Entra, consultez [Identité gérée Azure avec BYOK](/fr/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/setup/azure-managed-identity).

## Liste de modèles personnalisées

Lorsque vous utilisez BYOK, le serveur CLI peut ne pas connaître les modèles pris en charge par votre fournisseur. Vous pouvez fournir un gestionnaire personnalisé `onListModels` au niveau du client afin de renvoyer `client.listModels()` les modèles de votre fournisseur au format standard `ModelInfo` . Cela permet aux consommateurs en aval de découvrir des modèles disponibles sans interroger l’interface CLI.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
import { CopilotClient } from "@github/copilot-sdk";
import type { ModelInfo } from "@github/copilot-sdk";

const client = new CopilotClient({
    onListModels: () => [
        {
            id: "my-custom-model",
            name: "My Custom Model",
            capabilities: {
                supports: { vision: false, reasoningEffort: false },
                limits: { max_context_window_tokens: 128000 },
            },
        },
    ],
});
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
from copilot import CopilotClient
from copilot.client import ModelInfo, ModelCapabilities, ModelSupports, ModelLimits

client = CopilotClient(
    on_list_models=lambda: [
        ModelInfo(
            id="my-custom-model",
            name="My Custom Model",
            capabilities=ModelCapabilities(
                supports=ModelSupports(vision=False, reasoning_effort=False),
                limits=ModelLimits(max_context_window_tokens=128000),
            ),
        )
    ],
)
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
package main

import (
    "context"
    copilot "github.com/github/copilot-sdk/go"
)

func main() {
    client := copilot.NewClient(&copilot.ClientOptions{
        OnListModels: func(ctx context.Context) ([]copilot.ModelInfo, error) {
            return []copilot.ModelInfo{
                {
                    ID:   "my-custom-model",
                    Name: "My Custom Model",
                    Capabilities: copilot.ModelCapabilities{
                        Supports: copilot.ModelSupports{Vision: false, ReasoningEffort: false},
                        Limits:   copilot.ModelLimits{MaxContextWindowTokens: copilot.Int(128000)},
                    },
                },
            }, nil
        },
    })
    _ = client
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
using GitHub.Copilot;

var client = new CopilotClient(new CopilotClientOptions
{
    OnListModels = (ct) => Task.FromResult<IList<ModelInfo>>(new List<ModelInfo>
    {
        new()
        {
            Id = "my-custom-model",
            Name = "My Custom Model",
            Capabilities = new ModelCapabilities
            {
                Supports = new ModelSupports { Vision = false, ReasoningEffort = false },
                Limits = new ModelLimits { MaxContextWindowTokens = 128000 }
            }
        }
    })
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

```java
import com.github.copilot.CopilotClient;
import com.github.copilot.rpc.*;
import java.util.List;
import java.util.concurrent.CompletableFuture;

var client = new CopilotClient(new CopilotClientOptions()
    .setOnListModels(() -> CompletableFuture.completedFuture(List.of(
        new ModelInfo()
            .setId("my-custom-model")
            .setName("My Custom Model")
            .setCapabilities(new ModelCapabilities()
                .setSupports(new ModelSupports().setVision(false).setReasoningEffort(false))
                .setLimits(new ModelLimits().setMaxContextWindowTokens(128000)))
    )))
);
```

</div>

</div>

Les résultats sont mis en cache après le premier appel, tout comme le comportement par défaut. Le gestionnaire remplace complètement le RPC de l’interface en ligne de commande (CLI), sans recours au serveur.

## Limitations

### Limitations des fonctionnalités

Certaines fonctionnalités Copilot peuvent se comporter différemment avec BYOK :

* **Disponibilité** des modèles - Seuls les modèles pris en charge par votre fournisseur sont disponibles
* **Limitation du taux de requêtes** - Soumis aux limites de taux de requêtes de votre fournisseur, et non à celles de Copilot
* **Usage tracking** : l’utilisation est suivie par votre fournisseur, et non GitHub Copilot
* **Requêtes Premium** - Ne sont pas décomptées des quotas de requêtes Premium de Copilot

### Limitations spécifiques au fournisseur

| Provider                                           | Limitations                                                                                             |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| [Microsoft Foundry Local](https://foundrylocal.ai) | Local uniquement ; la disponibilité du modèle dépend du matériel de l’appareil ; aucune clé API requise |
| Ollama                                             | Aucune clé API ; local uniquement ; La prise en charge des modèles varie                                |
| OpenAI                                             | Soumis aux limitations de débit et aux quotas d’OpenAI                                                  |

## Résolution des problèmes

### Erreur « Modèle non spécifié »

Lorsque vous utilisez BYOK, le `model` paramètre est **requis** :

```typescript
// ❌ Error: Model required with custom provider
const session = await client.createSession({
    provider: { type: "openai", baseUrl: "..." },
});

// ✅ Correct: Model specified
const session = await client.createSession({
    model: "gpt-4",  // Required!
    provider: { type: "openai", baseUrl: "..." },
});
```

### Confusion du type de point de terminaison Azure

Pour Azure points de terminaison OpenAI (`*.openai.azure.com`), utilisez le type correct :

```typescript
// ❌ Wrong: Using "openai" type with native Azure endpoint
provider: {
    type: "openai",  // This won't work correctly
    baseUrl: "https://my-resource.openai.azure.com",
}

// ✅ Correct: Using "azure" type
provider: {
    type: "azure",
    baseUrl: "https://my-resource.openai.azure.com",
}
```

Toutefois, si votre déploiement Microsoft Foundry fournit un chemin de point de terminaison compatible OpenAI (par exemple, `/openai/v1/`), utilisez `type: "openai"`:

```typescript
// ✅ Correct: OpenAI-compatible Microsoft Foundry endpoint
provider: {
    type: "openai",
    baseUrl: "https://your-resource.openai.azure.com/openai/v1/",
}
```

### Connexion refusée (Ollama)

Vérifiez que Ollama est en cours d’exécution et accessible :

```bash
# Check Ollama is running
curl http://localhost:11434/v1/models

# Start Ollama if not running
ollama serve
```

### Connexion refusée (Foundry Local)

Foundry Local utilise un port dynamique qui peut changer entre les redémarrages. Confirmez le port actif :

```bash
# Check the service status and port
foundry service status
```

Mettez à jour votre `baseUrl` pour qu’il corresponde au port affiché dans le résultat. Si le service n’est pas en cours d’exécution, démarrez un modèle pour le lancer :

```bash
foundry model run phi-4-mini
```

### Échec de l’authentification

1. Vérifiez que votre clé API est correcte et non expirée
2. Vérifiez que le `baseUrl` correspond au format attendu par votre fournisseur
3. Pour les jetons de porteur, assurez-vous que le jeton complet est fourni (et non pas seulement un préfixe)

## Étapes suivantes

* [Authentification](/fr/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/auth) - En savoir plus sur toutes les méthodes d’authentification
* [Créez votre première application avec Copilot](/fr/enterprise-cloud@latest/copilot/how-tos/copilot-sdk/getting-started) - Créez votre première application basée sur Copilot