English
主导航

旧版 API

为 Microsoft Azure 配置工作负载身份联合

在以下任一场景中,将 Microsoft Azure 用作工作负载身份提供者:

  • Azure 托管标识: 将为托管标识颁发的 Microsoft Entra ID 访问令牌交换为短期 OpenAI 访问令牌。
  • AKS: 将投影的 Azure Kubernetes Service (AKS) 服务账号令牌交换为短期 OpenAI 访问令牌。

Azure 托管标识

Azure 托管标识允许 Azure 托管的工作负载请求 Microsoft Entra 令牌,而无需存储长期有效的机密。在 OpenAI 工作负载身份联合中,托管标识令牌是 OpenAI 在颁发 OpenAI 访问令牌之前验证的主体令牌。

设置 Azure 托管标识

创建或使用一个 Microsoft Entra 应用注册,以表示 OpenAI 应信任的令牌受众。将其 应用程序 ID URI;此 URI 是该 resource 值配置为您的工作负载从 Azure 实例元数据服务 (IMDS) 请求的值,该值将显示为颁发的令牌中的 aud 声明。有关 Microsoft 设置步骤,请参阅 Microsoft Entra 指南,了解如何 创建新的 Entra ID 应用程序和服务主体.

在 Microsoft Entra ID 中配置的 Application ID URI、IMDS resource 参数、生成令牌的 aud 声明以及 OpenAI 工作负载身份提供者的受众必须全部匹配。

创建 a managed identity, then 分配 该托管标识到运行您的应用程序的 Azure 资源(例如虚拟机)。该资源必须在运行时能够调用 IMDS。有关 Azure 设置的详细信息,请参阅 Microsoft 的 托管标识概述 以及用于分配标识的相关 Azure 资源文档。

获取 Azure 托管标识令牌

从分配了托管标识的 Azure 资源中,使用 Application ID URI 作为 resource 参数从 IMDS 请求令牌。此令牌是 OpenAI 用于交换 OpenAI 颁发的访问令牌的主体令牌。

1
2
3
4
5
6
7
APPLICATION_ID_URI="api://<application-client-id>"

TOKEN=$(curl -sS -G -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token" \
  --data-urlencode "api-version=2018-02-01" \
  --data-urlencode "resource=${APPLICATION_ID_URI}" \
  | jq -r .access_token)

如果资源具有多个用户分配的托管标识,请为您要使用的托管标识添加 client_id, object_id, or msi_res_id 查询参数。Microsoft 在中记录了 IMDS 令牌请求参数 使用虚拟机上的托管标识获取访问令牌.

验证令牌

在配置工作负载身份联合之前,请在本地解码一个示例令牌并检查其声明:

1
2
3
4
5
6
7
8
9
TOKEN="$TOKEN" python3 - <<'PY'
import base64
import json
import os

payload = os.environ["TOKEN"].split(".")[1]
payload += "=" * (-len(payload) % 4)
print(json.dumps(json.loads(base64.urlsafe_b64decode(payload)), indent=2))
PY

解码后的 AWS 颁发 OIDC 令牌类似于:

解码后的 Microsoft Entra ID 托管标识令牌类似于:

1
2
3
4
5
6
7
8
9
10
11
{
  "iss": "https://login.microsoftonline.com/11111111-2222-3333-4444-555555555555/v2.0",
  "aud": "api://00000000-1111-2222-3333-444444444444",
  "tid": "11111111-2222-3333-4444-555555555555",
  "appid": "22222222-3333-4444-5555-666666666666",
  "oid": "33333333-4444-5555-6666-777777777777",
  "sub": "33333333-4444-5555-6666-777777777777",
  "xms_mirid": "/subscriptions/<subscription-id>/resourcegroups/my-resource-group/providers/Microsoft.Compute/virtualMachines/openai-wif-vm",
  "iat": 1716235422,
  "exp": 1716239022
}

受众以及 OpenAI 工作负载身份提供商的受众。

  • iss: 使用令牌中的确切颁发者值。颁发者可能是 https://login.microsoftonline.com/<tenant-id>/v2.0, 但不要假定存在该后缀。
  • aud: 必须与“应用程序 ID URI”、IMDS 的 resource 参数,以及 OpenAI 工作负载身份提供商的受众。
  • tid: Microsoft Entra 租户 ID。
  • appid: 托管标识的应用程序/客户端 ID(如果存在)。

托管标识令牌还可以包含如下声明: azp, oid, sub, or xms_mirid. 请使用解码后的令牌作为事实来源,并选择能够标识您所信任的确切托管标识和资源边界的声明。

声明中显现。 iss, aud, tid, 并在交换令牌之前检查托管标识声明,

在 OpenAI 中为 AWS 账户颁发者创建工作负载身份提供商,然后添加与 AWS 颁发令牌中的稳定声明相匹配的服务账户映射。

在 OpenAI 中为 Microsoft Entra ID 颁发者创建一个工作负载身份提供商,然后添加一个与托管标识令牌中的稳定声明相匹配的服务账号映射。

设置工作负载身份提供商

创建工作负载身份提供商。

  1. 为一个唯一的值,例如 设置 名称 设置颁发者和受众。 azure-managed-identity-prod值。使用 描述,例如 Production Azure managed identity workloads,以帮助管理员识别该提供商。

  2. OIDC 颁发者 URL 设置 设置为启用出站身份联合时返回的 AWS 特定于账户的颁发者 URL。此值必须与令牌的 到令牌的 iss 声明的确切值。首先获取一个示例托管标识令牌并检查其声明。例如,颁发者可能是 https://login.microsoftonline.com/<tenant-id>/v2.0。将 为传递给 到你配置的 Microsoft Entra 应用程序 ID URI,例如 api://<application-client-id>。此值必须与令牌的 aud claim.

  3. 使用 Microsoft Entra 令牌验证。 保持禁用 使用上传的 JWKS 进行令牌验证 已禁用。OpenAI 使用 Microsoft Entra 颁发者元数据和 JWKS 来验证托管标识令牌。

  4. 如果需要派生映射属性,请添加属性转换。 For example, enter managed_identity_client_id with expression assertion.appid to create openai.managed_identity_client_id 来自托管标识应用程序/客户端 ID 声明。仪表板会将 openai. 前缀。对于已经以以下内容开头的原始令牌声明: openai. 映射键,已以 openai. 开头的原始令牌声明将被忽略,除非配置了匹配的转换。

设置服务账户映射

  1. 创建服务账户映射。 设置 名称 设置为在该工作负载身份提供商内唯一的值,例如 vm-openai-wif值。使用 描述,例如 Production VM Azure managed identity workload,以说明哪个工作负载可以使用此映射。

  2. 匹配稳定的托管标识声明。 为每个必须匹配的 GitHub 声明添加一行 and 行,用于每个必须匹配的声明。如果令牌包含 appid,请设置 to appid and 到托管标识客户端 ID。 appid 声明标识了托管标识的应用程序/客户端 ID,并且通常是将映射绑定到特定托管标识的最稳定声明。如果你的令牌不包含 appid, 请使用解码后令牌中的其他稳定声明,例如 azp, oid, sub, or xms_mirid. 要将映射绑定到单个租户,还需设置 to tid and 到 Microsoft Entra 租户 ID。从 IMDS 解码一个样本令牌,并使用对于您信任的托管标识和资源而言稳定的声明。

  3. 选择 OpenAI 目标。 设置 项目 指向拥有目标服务账户的 OpenAI 项目。将 服务账户 到 Azure 工作负载可以使用的 OpenAI 服务账户,例如 azure-managed-identity-prod-openai-wif.

  4. 根据需要缩小 API 权限范围。 选择适当的 权限 例如 api.model.request and api.vector_store.read 以进一步限制从此映射生成的访问令牌。将权限留空可避免添加特定于 WIF 的范围限制;该令牌仍会以映射的服务账户身份进行授权。

在代码中使用令牌

配置您的 OpenAI SDK 客户端,以从 IMDS 请求 Azure 托管标识令牌,并将其换取 OpenAI 颁发的访问令牌。

设置 OPENAI_WIF_AUDIENCE 到配置为 Workload Identity Provider 受众的 Microsoft Entra 应用程序 ID URI。SDK 会请求该受众的托管标识令牌,将其换取 OpenAI 颁发的访问令牌,并使用该 OpenAI 令牌对 API 请求进行身份验证。

使用 Azure 托管标识令牌进行身份验证
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import OpenAI from "openai";
import type { SubjectTokenProvider } from "openai/auth";

const imdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token";

const identityProviderId = process.env.OPENAI_IDENTITY_PROVIDER_ID;
const serviceAccountId = process.env.OPENAI_SERVICE_ACCOUNT_ID;
const audience = process.env.OPENAI_WIF_AUDIENCE;

if (!identityProviderId || !serviceAccountId || !audience) {
  throw new Error(
    "Set OPENAI_IDENTITY_PROVIDER_ID, OPENAI_SERVICE_ACCOUNT_ID, and OPENAI_WIF_AUDIENCE"
  );
}

function azureManagedIdentityTokenProvider(resource: string): SubjectTokenProvider {
  return {
    tokenType: "jwt",
    getToken: async () => {
      const url = new URL(imdsEndpoint);
      url.searchParams.set("api-version", "2018-02-01");
      url.searchParams.set("resource", resource);

      const clientId = process.env.AZURE_CLIENT_ID;
      if (clientId) {
        url.searchParams.set("client_id", clientId);
      }

      const response = await fetch(url, {
        headers: { Metadata: "true" },
      });

      if (!response.ok) {
        throw new Error(
          `Azure IMDS token request failed with status ${response.status}.`
        );
      }

      const body = (await response.json()) as { access_token?: string };
      if (!body.access_token) {
        throw new Error("Azure IMDS did not return an access token.");
      }

      return body.access_token;
    },
  };
}

const client = new OpenAI({
  workloadIdentity: {
    identityProviderId,
    serviceAccountId,
    provider: azureManagedIdentityTokenProvider(audience),
  },
});

const response = await client.responses.create({
  model: "gpt-4.1-mini",
  input: "Say hello from Azure managed identity workload identity federation.",
});

console.log(response.output_text);

Microsoft Azure 最佳实践

  • 尽可能使用托管标识。与手动分发凭据相比,托管标识提供了更简单、更安全的身份验证模型。
  • 为不同的应用程序和环境使用独立的托管标识、Microsoft Entra 应用程序和 OpenAI 映射。避免在开发、预发布和生产工作负载之间共享同一身份。
  • 限制接受的受众。仅配置 OpenAI 工作负载身份联合所需的受众。
  • 为安全边界使用专用的 Microsoft Entra ID 应用程序。独立的应用程序可提供更清晰的所有权、审计和访问管理。
  • 优先使用特定于工作负载的映射。根据特定于工作负载的声明进行匹配,而不是宽泛的租户级属性。
  • 定期审查联合凭据配置。过时的联合凭据可能会在工作负载退役后很久仍无意中继续授予访问权限。
  • 区分生产与非生产身份。生产工作负载应通过独立的联合身份和 OpenAI 服务账号进行身份验证。