Ce guide explique comment utiliser les API du SDK Azure Identity pour s’authentifier auprès des modèles Microsoft Foundry via le SDK GitHub Copilot. La plupart des langues utilisent DefaultAzureCredential; Rust utilise DeveloperToolsCredential localement et ManagedIdentityCredential dans Azure.
Fonctionnement
Le point de terminaison de Microsoft Foundry compatible avec OpenAI (https://<resource-name>.openai.azure.com/openai/v1/) accepte des jetons de porteur de Microsoft Entra ID à la place de clés d’API statiques. Ce guide utilise un rappel de fournisseur de jetons afin que le runtime du KIT de développement logiciel (SDK) GitHub Copilot puisse demander de nouveaux jetons à la demande.
À l’aide de Python comme exemple, le flux est le suivant :
- Configurez
DefaultAzureCredentialpour votre environnement. - Transmettez un rappel, dans
bearer_token_providerla configuration du fournisseur BYOK, qui utiliseDefaultAzureCredentialpour obtenir un jeton pour l’étenduehttps://ai.azure.com/.default. - Autorisez le SDK GitHub Copilot à demander de nouveaux jetons d’authentification lorsque nécessaire via cette fonction de rappel.

Exemples de code
Prerequisites
Installez les packages Azure Identity et GitHub Copilot SDK pour votre langue :
dotnet add package GitHub.Copilot.SDK
dotnet add package Azure.Core
go get github.com/github/copilot-sdk/go
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity
<dependency>
<groupId>com.github</groupId>
<artifactId>copilot-sdk-java</artifactId>
<version>${copilot.sdk.version}</version>
</dependency>
<dependency>
<groupId>com.azure</groupId>
<artifactId>azure-identity</artifactId>
<version>${azure.identity.version}</version>
</dependency>
pip install github-copilot-sdk azure-identity
cargo add github-copilot-sdk azure_identity azure_core
cargo add tokio --features macros,rt-multi-thread
npm install @github/copilot-sdk @azure/identity
Utiliser un rappel de fournisseur de jetons
Utilisez cette approche lorsque vous souhaitez que le runtime du KIT de développement logiciel (SDK) GitHub Copilot demande de nouveaux jetons à la demande via un rappel que vous fournissez. Le sdk Azure Identity gère la mise en cache des jetons et le minutage d’actualisation.
Voici les implémentations spécifiques au langage :
using Azure.Core;
using Azure.Identity;
using GitHub.Copilot;
DefaultAzureCredential credential = new(
DefaultAzureCredential.DefaultEnvironmentVariableName);
await using CopilotClient client = new();
string foundryUrl = Environment.GetEnvironmentVariable("FOUNDRY_RESOURCE_URL")!;
await using CopilotSession session = await client.CreateSessionAsync(new SessionConfig
{
Model = "gpt-5.5",
Provider = new ProviderConfig
{
Type = "openai",
BaseUrl = $"{foundryUrl}/openai/v1/",
BearerTokenProvider = async _ =>
{
AccessToken token = await credential.GetTokenAsync(
new TokenRequestContext(["https://ai.azure.com/.default"]));
return token.Token;
},
WireApi = "responses",
},
});
AssistantMessageEvent? response = await session.SendAndWaitAsync(
new MessageOptions { Prompt = "Hello from Managed Identity!" });
Console.WriteLine(response?.Data.Content);
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
copilot "github.com/github/copilot-sdk/go"
)
func main() {
opts := azidentity.DefaultAzureCredentialOptions{RequireAzureTokenCredentials: true}
credential, err := azidentity.NewDefaultAzureCredential(&opts)
if err != nil {
log.Fatal(err)
}
getBearerToken := func(args copilot.ProviderTokenArgs) (string, error) {
token, err := credential.GetToken(context.Background(), policy.TokenRequestOptions{
Scopes: []string{"https://ai.azure.com/.default"},
})
if err != nil {
return "", err
}
return token.Token, nil
}
client := copilot.NewClient(nil)
if err := client.Start(context.Background()); err != nil {
log.Fatal(err)
}
defer client.Stop()
foundryURL := os.Getenv("FOUNDRY_RESOURCE_URL")
session, err := client.CreateSession(context.Background(), &copilot.SessionConfig{
Model: "gpt-5.5",
Provider: &copilot.ProviderConfig{
Type: "openai",
BaseURL: fmt.Sprintf("%s/openai/v1/", foundryURL),
BearerTokenProvider: getBearerToken,
WireAPI: "responses",
},
})
if err != nil {
log.Fatal(err)
}
defer session.Disconnect()
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
response, err := session.SendAndWait(ctx, copilot.MessageOptions{
Prompt: "Hello from Managed Identity!",
})
if err != nil {
log.Fatal(err)
}
if response != nil {
if data, ok := response.Data.(*copilot.AssistantMessageData); ok {
fmt.Println(data.Content)
}
}
}
import com.azure.core.credential.TokenRequestContext;
import com.azure.identity.AzureIdentityEnvVars;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.github.copilot.CopilotClient;
import com.github.copilot.generated.AssistantMessageEvent;
import com.github.copilot.rpc.BearerTokenProvider;
import com.github.copilot.rpc.MessageOptions;
import com.github.copilot.rpc.ProviderConfig;
import com.github.copilot.rpc.SessionConfig;
public class ManagedIdentityExample {
public static void main(String[] args) throws Exception {
var credential = new DefaultAzureCredentialBuilder()
.requireEnvVars(AzureIdentityEnvVars.AZURE_TOKEN_CREDENTIALS)
.build();
BearerTokenProvider tokenProvider = providerArgs ->
credential
.getToken(new TokenRequestContext().addScopes("https://ai.azure.com/.default"))
.map(accessToken -> accessToken.getToken())
.toFuture();
String foundryUrl = System.getenv("FOUNDRY_RESOURCE_URL");
try (var client = new CopilotClient()) {
client.start().get();
var session = client.createSession(new SessionConfig()
.setModel("gpt-5.5")
.setProvider(new ProviderConfig()
.setType("openai")
.setBaseUrl(foundryUrl + "/openai/v1/")
.setBearerTokenProvider(tokenProvider)
.setWireApi("responses")))
.get();
AssistantMessageEvent response = session
.sendAndWait(new MessageOptions().setPrompt("Hello from Managed Identity!"))
.get();
System.out.println(response.getData().content());
session.disconnect().get();
}
}
}
import asyncio
import os
from azure.identity.aio import DefaultAzureCredential
from copilot import CopilotClient
from copilot.session import PermissionHandler, ProviderConfig
async def main():
credential = DefaultAzureCredential(require_envvar=True)
async def get_bearer_token(_args) -> str:
token = await credential.get_token("https://ai.azure.com/.default")
return token.token
foundry_url = os.environ["FOUNDRY_RESOURCE_URL"]
client = CopilotClient()
await client.start()
session = await client.create_session(
on_permission_request=PermissionHandler.approve_all,
model="gpt-5.5",
provider=ProviderConfig(
type="openai",
base_url=f"{foundry_url.rstrip('/')}/openai/v1/",
bearer_token_provider=get_bearer_token,
wire_api="responses",
),
)
response = await session.send_and_wait("Hello from Managed Identity!")
print(response.data.content)
await client.stop()
await credential.close()
asyncio.run(main())
use std::sync::Arc;
use azure_core::credentials::TokenCredential;
use azure_identity::{DeveloperToolsCredential, ManagedIdentityCredential};
use github_copilot_sdk::{BearerTokenError, Client, ClientOptions, MessageOptions, ProviderTokenArgs};
use github_copilot_sdk::types::{ProviderConfig, SessionConfig};
fn credential_for_environment() -> azure_core::Result<Arc<dyn TokenCredential>> {
match std::env::var("AZURE_TOKEN_CREDENTIALS").as_deref() {
Ok("ManagedIdentityCredential") => Ok(ManagedIdentityCredential::new(None)?),
_ => Ok(DeveloperToolsCredential::new(None)?),
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let credential = credential_for_environment()?;
let foundry_url = std::env::var("FOUNDRY_RESOURCE_URL")?;
let get_bearer_token = {
let credential = credential.clone();
move |_args: ProviderTokenArgs| {
let credential = credential.clone();
async move {
let token = credential
.get_token(&["https://ai.azure.com/.default"], None)
.await
.map_err(|err| BearerTokenError::message(err.to_string()))?;
Ok(token.token.secret().to_string())
}
}
};
let mut provider = ProviderConfig::default();
provider.provider_type = Some("openai".to_string());
provider.base_url = format!("{}/openai/v1/", foundry_url.trim_end_matches('/'));
provider.bearer_token_provider = Some(Arc::new(get_bearer_token));
provider.wire_api = Some("responses".to_string());
let mut config = SessionConfig::default();
config.model = Some("gpt-5.5".to_string());
config.provider = Some(provider);
let client = Client::start(ClientOptions::default()).await?;
let session = client.create_session(config).await?;
session
.send_and_wait(MessageOptions::new("Hello from Managed Identity!"))
.await?;
session.disconnect().await?;
client.stop().await?;
Ok(())
}
import { DefaultAzureCredential } from "@azure/identity";
import { CopilotClient } from "@github/copilot-sdk";
const credential = new DefaultAzureCredential({
requiredEnvVars: ["AZURE_TOKEN_CREDENTIALS"],
});
const getBearerToken = async () => {
const tokenResponse = await credential.getToken("https://ai.azure.com/.default");
return tokenResponse.token;
};
const client = new CopilotClient();
const session = await client.createSession({
model: "gpt-5.5",
provider: {
type: "openai",
baseUrl: `${process.env.FOUNDRY_RESOURCE_URL}/openai/v1/`,
bearerTokenProvider: getBearerToken,
wireApi: "responses",
},
});
const response = await session.sendAndWait({ prompt: "Hello from Managed Identity!" });
console.log(response?.data.content);
await client.stop();
Configuration de l’environnement
| Variable | Description | Example |
|---|---|---|
AZURE_TOKEN_CREDENTIALS | Lors de l’exécution dans Azure, définissez cette valeur sur Managed. Lors de l’exécution en local, définissez-le sur soit dev, soit le nom d’un identifiant d’outil de développement, tel que Azure. | Managed |
AZURE_CLIENT_ID | ||
Facultatif. Lors de l’exécution dans Azure, définissez cette valeur sur l’ID client d’une identité managée attribuée par l’utilisateur lors de l’utilisation de Managed. S’il n’est pas défini, Azure utilise l’identité managée affectée par le système. | 11111111-2222-3333-4444-555555555555 | |
FOUNDRY_RESOURCE_ | URL de votre ressource Microsoft Foundry | https:/ |
Aucune variable d’environnement de clé API n’est nécessaire : l’authentification est gérée par les informations d’identification d’identité Azure. Dans .NET, Go, Java, Python et TypeScript prennent DefaultAzureCredential automatiquement en charge :
- Identité managée (affectée par le système ou affectée par l’utilisateur) : pour les applications hébergées par Azure
- Azure CLI (
az login) : pour le développement local - Variables d’environnement (
AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_CLIENT_SECRET) : pour les entités de service. - Identité de la charge de travail : pour Kubernetes
Dans .NET, Go, Java, Python et TypeScript, ManagedIdentityCredential lit AZURE_CLIENT_ID pour sélectionner une identité managée affectée par l’utilisateur. Rust est une exception dans ce guide.
Dans Rust, utilisez-le DeveloperToolsCredential pour le développement local et ManagedIdentityCredential lors de l’exécution dans Azure. Pour les autres langues, consultez la documentation DefaultAzureCredential de la chaîne complète d’identifiants :
Quand utiliser ce modèle
| Scénario | Recommandation |
|---|---|
| Application hébergée par Azure avec l’identité managée | |
| ✅ Utiliser ce modèle | |
| Application avec un principal de service Microsoft Entra existant | |
| ✅ Utiliser ce modèle | |
Développement local avec az login | |
| ✅ Utiliser ce modèle | |
| Environnement non-Azure avec clé API statique | Utiliser BYOK (apportez votre propre clé) |
| abonnement GitHub Copilot disponible | Utiliser configuration de GitHub OAuth |
Voir aussi
- BYOK (apportez votre propre clé) : Configuration de la clé API statique
- Configuration des services principaux : Déploiement côté serveur