Este guia mostra como usar APIs do SDK de Identidade do Azure para autenticar com modelos do Microsoft Foundry por meio do SDK do GitHub Copilot. A maioria dos idiomas usa DefaultAzureCredential; O Rust usa DeveloperToolsCredential localmente e ManagedIdentityCredential em Azure.
Como funciona
O ponto de extremidade do Microsoft Foundry compatível com OpenAI (https://<resource-name>.openai.azure.com/openai/v1/) aceita tokens bearer do Microsoft Entra ID em vez de chaves de API estáticas. Este guia usa uma função de callback do provedor de tokens para que o runtime do SDK do GitHub Copilot possa solicitar novos tokens sob demanda.
Usando Python como exemplo, o fluxo é:
- Configure
DefaultAzureCredentialpara seu ambiente. - Passe uma função de callback, em
bearer_token_providerda configuração do provedor BYOK, que usaDefaultAzureCredentialpara obter um token para o escopohttps://ai.azure.com/.default. - Permita que o SDK do GitHub Copilot solicite tokens novos sob demanda por meio desse callback.

Exemplos de código
Pré-requisitos
Instale os pacotes do SDK do Azure Identity e GitHub Copilot para seu 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
Use uma função de callback do provedor de token
Use esta abordagem quando você quiser que o runtime do SDK do GitHub Copilot solicite novos tokens sob demanda por meio de uma função de callback fornecida. O SDK de Identidade do Azure manipula o cache de token e o tempo de atualização.
Aqui estão implementações específicas do idioma:
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();
Configuração do ambiente
| Variable | Description | Example |
|---|---|---|
AZURE_TOKEN_CREDENTIALS | Ao executar em Azure, defina-o como Managed. Ao executar localmente, configure-o para usar dev ou um nome de credencial de ferramenta de desenvolvedor, como Azure. | Managed |
AZURE_CLIENT_ID | ||
Opcional. Ao executar em Azure, defina-a como a ID do cliente de uma Identidade Gerenciada atribuída pelo usuário ao usar Managed. Se não estiver definido, Azure usará a Identidade Gerenciada atribuída pelo sistema. | 11111111-2222-3333-4444-555555555555 | |
FOUNDRY_RESOURCE_ | A URL do recurso Microsoft Foundry | https:/ |
Nenhuma variável de ambiente de chave de API é necessária– a autenticação é tratada por credenciais de identidade Azure. Em .NET, Go, Java, Python e TypeScript, DefaultAzureCredential oferece suporte automático a:
- Identidade Gerenciada (atribuída pelo sistema ou atribuída pelo usuário): para aplicativos hospedados Azure
- CLI do Azure (
az login): para desenvolvimento local - Variáveis de ambiente (
AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_CLIENT_SECRET): para entidades de serviço - Identidade da carga de trabalho: para Kubernetes
Em .NET, Go, Java, Python e TypeScript, ManagedIdentityCredential lê AZURE_CLIENT_ID para selecionar uma Identidade Gerenciada atribuída pelo usuário. Rust é uma exceção neste guia.
No Rust, use DeveloperToolsCredential para desenvolvimento local e ManagedIdentityCredential ao executar em Azure. Para outros idiomas, consulte a documentação em DefaultAzureCredential sobre a cadeia completa de credenciais:
Quando usar esse padrão
| Scenario | Recomendação |
|---|---|
| Aplicativo hospedado no Azure com Identidade Gerenciada | |
| ✅ Usar esse padrão | |
| Aplicativo com entidade de serviço Microsoft Entra existente | |
| ✅ Usar esse padrão | |
Desenvolvimento local com az login | |
| ✅ Usar esse padrão | |
| Ambiente não Azure com chave de API estática | Usar BYOK (Bring Your Own Key - traga sua própria chave) |
| GitHub Copilot assinatura disponível | Usar Configuração do OAuth do GitHub |
Consulte também
- BYOK (Bring Your Own Key - traga sua própria chave): Configuração de chave de API estática
- Configuração de serviços de back-end: Implantação do lado do servidor