In diesem Handbuch wird gezeigt, wie Sie Azure Identity SDK-APIs zum Authentifizieren mit Microsoft Foundry-Modellen über das GitHub Copilot SDK verwenden. Die meisten Sprachen verwenden DefaultAzureCredential; Rost verwendet DeveloperToolsCredential lokal und ManagedIdentityCredential in Azure.
So funktioniert es
Der OpenAI-kompatible Endpunkt von Microsoft Foundry (https://<resource-name>.openai.azure.com/openai/v1/) akzeptiert Bearer-Token von Microsoft Entra ID anstelle statischer API-Schlüssel. In diesem Handbuch wird ein Tokenanbieterrückruf verwendet, sodass die GitHub Copilot SDK-Laufzeit frische Token bei Bedarf anfordern kann.
Am Beispiel von Python ergibt sich folgender Ablauf:
- Konfigurieren Sie
DefaultAzureCredentialfür Ihre Umgebung. - Übergeben Sie in
bearer_token_providerder BYOK-Anbieterkonfiguration einen Callback, derDefaultAzureCredentialverwendet, um ein Token für den Scopehttps://ai.azure.com/.defaultabzurufen. - Lassen Sie das GitHub Copilot SDK bei Bedarf über diesen Callback neue Tokens anfordern.

Codebeispiele
Voraussetzungen
Installieren Sie die Azure Identity- und GitHub Copilot SDK-Pakete für Ihre Sprache:
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
Verwenden Sie die Rückruffunktion eines Tokenanbieters
Verwenden Sie diesen Ansatz, wenn die GitHub Copilot SDK-Laufzeit frische Token bei Bedarf über einen von Ihnen bereitgestellten Rückruf anfordern soll. Das Azure Identity SDK übernimmt die Zwischenspeicherung von Token und die Aktualisierungszeitpunkte.
Hier sind sprachspezifische Implementierungen:
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();
Umgebungskonfiguration
| Variable | Description | Example |
|---|---|---|
AZURE_TOKEN_CREDENTIALS | Wenn sie in Azure ausgeführt wird, legen Sie sie auf Managed. Wenn es lokal ausgeführt wird, setzen Sie es entweder auf dev oder auf den Anmeldeinformationsnamen eines Entwicklertools, z. B. Azure. | Managed |
AZURE_CLIENT_ID | ||
Optional. Wenn sie in Azure ausgeführt wird, legen Sie dies auf die Client-ID einer vom Benutzer zugewiesenen verwalteten Identität bei Verwendung Managedfest. Wenn nicht festgelegt, verwendet Azure die vom System zugewiesene verwaltete Identität. | 11111111-2222-3333-4444-555555555555 | |
FOUNDRY_RESOURCE_ | URL Ihrer Microsoft Foundry-Ressource | https:/ |
Es ist keine API-Schlüsselumgebungsvariable erforderlich – die Authentifizierung wird von Azure Identitätsanmeldeinformationen behandelt. In .NET unterstützt Go, Java, Python und TypeScript DefaultAzureCredential automatisch Folgendes:
- Verwaltete Identität (vom System zugewiesen oder vom Benutzer zugewiesen): für Azure gehostete Apps
- Azure CLI (
az login): für die lokale Entwicklung - Umgebungsvariablen (
AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_CLIENT_SECRET): für Dienstprinzipale - Workload-Identität: für Kubernetes
In .NET, Go, Java, Python und TypeScript liest ManagedIdentityCredential``AZURE_CLIENT_ID, um eine benutzerzugewiesene verwaltete Identität auszuwählen. Rost ist eine Ausnahme in dieser Anleitung.
Verwenden Sie DeveloperToolsCredential in Rust für die lokale Entwicklung und ManagedIdentityCredential bei der Ausführung in Azure. Für andere Sprachen finden Sie in der DefaultAzureCredential Dokumentation die vollständige Kette der Anmeldeinformationen:
Wann dieses Muster verwenden
| Szenario | Recommendation |
|---|---|
| Von Azure gehostete App mit verwalteter Identität | |
| ✅ Verwenden Sie dieses Muster. | |
| App mit einem vorhandenen Microsoft Entra-Dienstprinzipal | |
| ✅ Verwenden Sie dieses Muster. | |
Lokale Entwicklung mit az login | |
| ✅ Verwenden Sie dieses Muster. | |
| Nicht-Azure-Umgebung mit statischem API-Schlüssel | Verwenden von BYOK (Bring Your Own Key) |
| GitHub Copilot Abonnement verfügbar | Verwenden von Einrichtung von GitHub OAuth |
Siehe auch
- BYOK (Bring Your Own Key): Konfiguration des statischen API-Schlüssels
- Einrichtung von Back-End-Diensten: Serverseitige Bereitstellung