En esta guía se muestra cómo usar las API del SDK de Azure Identity para autenticarse con modelos de Microsoft Foundry a través del SDK de GitHub Copilot. La mayoría de los idiomas usan DefaultAzureCredential; Rust usa DeveloperToolsCredential localmente y ManagedIdentityCredential en Azure.
Cómo funciona
El punto de conexión compatible con OpenAI de Microsoft Foundry (https://<resource-name>.openai.azure.com/openai/v1/) acepta tokens de portador de Microsoft Entra ID en lugar de usar claves de API estáticas. Esta guía usa una función callback del proveedor de tokens para que el runtime del SDK de GitHub Copilot pueda solicitar tokens actualizados cuando sea necesario.
Con Python como ejemplo, el flujo es:
- Configura
DefaultAzureCredentialpara tu entorno. - Pase una devolución de llamada, en
bearer_token_providerde la configuración del proveedor BYOK, que usaDefaultAzureCredentialpara obtener un token para elhttps://ai.azure.com/.defaultámbito. - Deje que el SDK de GitHub Copilot solicite nuevos tokens cuando sea necesario mediante esa función de callback.

Ejemplos de código
Prerequisites
Instale los paquetes Azure Identity y GitHub Copilot SDK para el idioma:
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
Uso de una devolución de llamada del proveedor de tokens
Use este enfoque cuando desee que el entorno de ejecución del SDK de GitHub Copilot solicite tokens nuevos a petición a través de una devolución de llamada que proporcione. El SDK de Azure Identity controla el almacenamiento en caché de tokens y el tiempo de actualización.
Estas son implementaciones específicas del lenguaje:
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();
Configuración de entorno
| Variable | Description | Example |
|---|---|---|
AZURE_TOKEN_CREDENTIALS | Cuando se ejecute en Azure, configúrelo como Managed. Al ejecutar localmente, configúrelo como dev o como un nombre de credencial de una herramienta de desarrollo, como Azure. | Managed |
AZURE_CLIENT_ID | ||
Opcional. Cuando se ejecuta en Azure, establézcalo en el identificador de cliente de una identidad administrada asignada por el usuario al usar Managed. Si no se establece, Azure usa la identidad administrada asignada por el sistema. | 11111111-2222-3333-4444-555555555555 | |
FOUNDRY_RESOURCE_ | Dirección URL del recurso Microsoft Foundry | https:/ |
No se necesita ninguna variable de entorno de clave de API: la autenticación se controla mediante Azure credenciales de identidad. En .NET, Go, Java, Python y TypeScript, DefaultAzureCredential admite automáticamente:
- Identidad administrada (asignada por el sistema o asignada por el usuario): para aplicaciones hospedadas Azure
- CLI de Azure (
az login): para el desarrollo local - Variables de entorno (
AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_CLIENT_SECRET): para entidades de servicio - Identidad de carga de trabajo: para Kubernetes
En .NET, Go, Java, Python y TypeScript, ManagedIdentityCredential lee AZURE_CLIENT_ID para seleccionar una identidad administrada asignada por el usuario. Rust es una excepción en esta guía.
En Rust, use DeveloperToolsCredential para el desarrollo local y ManagedIdentityCredential cuando se ejecute en Azure. Para otros idiomas, consulte la documentación de la cadena completa de credenciales en DefaultAzureCredential:
Cuándo usar este patrón
| Escenario | Recomendación |
|---|---|
| Aplicación hospedada en Azure con identidad administrada | |
| ✅ Usa este patrón | |
| Aplicación con una entidad de servicio existente de Microsoft Entra | |
| ✅ Usa este patrón | |
Desarrollo local con az login | |
| ✅ Usa este patrón | |
| Entorno que no es de Azure con clave de API estática | Usar BYOK (traiga su propia clave) |
| GitHub Copilot suscripción disponible | Usar Configuración de OAuth de GitHub |
Consulte también
- BYOK (traiga su propia clave): configuración de clave de API estática
- Configuración de servicios back-end: implementación del lado servidor