Thanks to visit codestin.com
Credit goes to docs.github.com

Skip to main content

支持 BYOK(自带密钥)的 Azure 托管标识

Copilot SDK 的 BYOK (自带密钥)接受静态 API 密钥,但Azure部署通常使用 Managed Identity(Entra ID)而不是长期密钥。 由于 SDK 本身不支持Entra ID身份验证,因此可以通过 bearer_token 提供程序配置字段使用生存期较短的持有者令牌。

本指南介绍如何通过 Copilot SDK 使用 DefaultAzureCredential 库中的 向 Azure AI Foundry 模型进行身份验证。

工作原理

Azure AI Foundry 的 OpenAI 兼容终结点接受来自 Entra ID 的持有者令牌,以取代静态 API 密钥。 模式为:

  1. 使用DefaultAzureCredential获取https://cognitiveservices.azure.com/.default作用域的令牌
  2. 将该令牌作为 BYOK 提供程序配置中的 bearer_token 传递
  3. 在令牌过期之前刷新令牌(令牌通常有效约 1 小时)

关系图:显示描述的过程的序列图。

Python示例

先决条件

pip install github-copilot-sdk azure-identity

基本用法

import asyncio
import os

from azure.identity import DefaultAzureCredential
from copilot import CopilotClient
from copilot.session import PermissionHandler, ProviderConfig

COGNITIVE_SERVICES_SCOPE = "https://cognitiveservices.azure.com/.default"

async def main():
    # Get a token using Managed Identity, Azure CLI, or other credential chain
    credential = DefaultAzureCredential()
    token = credential.get_token(COGNITIVE_SERVICES_SCOPE).token

    foundry_url = os.environ["AZURE_AI_FOUNDRY_RESOURCE_URL"]

    client = CopilotClient()
    await client.start()

    session = await client.create_session(
        on_permission_request=PermissionHandler.approve_all,
        model="gpt-4.1",
        provider=ProviderConfig(
            type="openai",
            base_url=f"{foundry_url.rstrip('/')}/openai/v1/",
            bearer_token=token,  # Short-lived bearer token
            wire_api="responses",
        ),
    )

    response = await session.send_and_wait("Hello from Managed Identity!")
    print(response.data.content)

    await client.stop()

asyncio.run(main())

长时间运行应用程序的令牌刷新

持有者令牌过期(通常在大约 1 小时后)。 对于服务器或长时间运行的代理,请在创建每个会话之前刷新令牌:

from azure.identity import DefaultAzureCredential
from copilot import CopilotClient
from copilot.session import PermissionHandler, ProviderConfig

COGNITIVE_SERVICES_SCOPE = "https://cognitiveservices.azure.com/.default"

class ManagedIdentityCopilotAgent:
    """Copilot agent that refreshes Entra ID tokens for Azure AI Foundry."""

    def __init__(self, foundry_url: str, model: str = "gpt-4.1"):
        self.foundry_url = foundry_url.rstrip("/")
        self.model = model
        self.credential = DefaultAzureCredential()
        self.client = CopilotClient()

    def _get_provider_config(self) -> ProviderConfig:
        """Build a ProviderConfig with a fresh bearer token."""
        token = self.credential.get_token(COGNITIVE_SERVICES_SCOPE).token
        return ProviderConfig(
            type="openai",
            base_url=f"{self.foundry_url}/openai/v1/",
            bearer_token=token,
            wire_api="responses",
        )

    async def chat(self, prompt: str) -> str:
        """Send a prompt and return the response text."""
        # Fresh token for each session
        session = await self.client.create_session(
            on_permission_request=PermissionHandler.approve_all,
            model=self.model,
            provider=self._get_provider_config(),
        )

        response = await session.send_and_wait(prompt)
        await session.disconnect()

        return response.data.content if response else ""

Node.js/TypeScript 示例

import { DefaultAzureCredential } from "@azure/identity";
import { CopilotClient } from "@github/copilot-sdk";

const credential = new DefaultAzureCredential();
const tokenResponse = await credential.getToken(
  "https://cognitiveservices.azure.com/.default"
);

const client = new CopilotClient();

const session = await client.createSession({
  model: "gpt-4.1",
  provider: {
    type: "openai",
    baseUrl: `${process.env.AZURE_AI_FOUNDRY_RESOURCE_URL}/openai/v1/`,
    bearerToken: tokenResponse.token,
    wireApi: "responses",
  },
});

const response = await session.sendAndWait({ prompt: "Hello!" });
console.log(response?.data.content);

await client.stop();

.NET 示例

using Azure.Identity;
using GitHub.Copilot;

var credential = new DefaultAzureCredential();
var token = await credential.GetTokenAsync(
    new Azure.Core.TokenRequestContext(
        new[] { "https://cognitiveservices.azure.com/.default" }));

await using var client = new CopilotClient();
var foundryUrl = Environment.GetEnvironmentVariable("AZURE_AI_FOUNDRY_RESOURCE_URL");

await using var session = await client.CreateSessionAsync(new SessionConfig
{
    Model = "gpt-4.1",
    Provider = new ProviderConfig
    {
        Type = "openai",
        BaseUrl = $"{foundryUrl!.TrimEnd('/')}/openai/v1/",
        BearerToken = token.Token,
        WireApi = "responses",
    },
});

var response = await session.SendAndWaitAsync(
    new MessageOptions { Prompt = "Hello from Managed Identity!" });
Console.WriteLine(response?.Data.Content);

环境配置

VariableDescription示例
AZURE_AI_FOUNDRY_RESOURCE_URL您的 Azure AI Foundry 资源网址https://myresource.openai.azure.com

不需要 API 密钥环境变量——身份验证由 DefaultAzureCredential 处理,并自动支持:

  • Managed Identity(系统分配或用户分配):适用于Azure托管的应用
  • Azure CLIaz login):用于本地开发
  • 环境变量AZURE_CLIENT_IDAZURE_TENANT_IDAZURE_CLIENT_SECRET):用于服务主体
  • 工作负荷标识:适用于 Kubernetes

有关完整凭据链,请参阅 DefaultAzureCredential 文档

何时使用此模式

情景Recommendation
使用托管标识的 Azure 应用程序
✅ 使用此模式
具有现有 Azure AD 服务主体的应用
✅ 使用此模式
使用 az login 进行本地开发
✅ 使用此模式
具有静态 API 密钥的非 Azure 环境使用 BYOK (自带密钥)
GitHub Copilot订阅可用使用 GitHub OAuth 设置

另见