Skip to content

注册 Microsoft Graph 应用程序

hermes agent 注册 Microsoft Graph 应用程序

Teams 会议流水线会使用 Microsoft Graph 读取会议转录、录制文件和相关 artifacts,并采用 app-only(daemon)认证 —— 不需要用户登录,也不需要每次会议进行交互式授权。这需要一个 Azure AD 应用注册,并授予已由管理员同意的 application permissions。

本指南将介绍:

  1. 创建 app registration
  2. 创建 client secret
  3. 授予流水线所需的 Graph API permissions
  4. 对这些 permissions 进行管理员同意
  5. (可选)使用 Application Access Policy 将 app 限定到特定用户

你需要 tenant admin 权限(或由管理员代表你授予同意)才能完成这一步。请保存你收集到的值 —— 它们最终会写入 ~/.hermes/.env

  • 一个 Microsoft 365 tenant,并且拥有会生成会议转录和录制文件的 Teams Premium 或 Teams licenses
  • 拥有 Azure portal(entra.microsoft.com)的管理员访问权限
  • 一个公网可访问的 HTTPS endpoint,用于 Graph change notifications(稍后会在 webhook listener 步骤中设置)
  1. 以 tenant admin 身份登录 entra.microsoft.com

  2. 导航到 Identity → Applications → App registrations。

  3. 点击 New registration。

  4. 填写:

    • Name:Hermes Teams Meeting Pipeline(或任何你能识别的名称)。
    • Supported account types:Accounts in this organizational directory only(Single tenant)。
    • Redirect URI:留空 —— app-only auth 不需要它。
  5. 点击 Register。

你会进入该 app 的 overview 页面。复制两个值:

  • Application(client)ID → MSGRAPH_CLIENT_ID
  • Directory(tenant)ID → MSGRAPH_TENANT_ID
  1. 在左侧导航中打开 Certificates & secrets。
  2. 点击 New client secret。
  3. Description:hermes-graph-secret。Expires:选择符合你轮换策略的值(通常为 6–24 个月)。
  4. 点击 Add。
  5. 立即复制 Value 列 —— 它只会显示一次。这个值就是 MSGRAPH_CLIENT_SECRET

Secret ID 列不是 secret。你需要的是 Value 列。

该 pipeline 使用一组最小可行的 application permissions。只添加你需要的权限;每增加一个权限,都会扩大该 app 可在整个 tenant 范围内读取的内容。

  1. 在左侧导航中打开 API permissions。
  2. 点击 Add a permission → Microsoft Graph → Application permissions。
  3. 根据你希望 pipeline 执行的操作,添加下表中的相应 permissions。
  4. 添加后,点击 Grant admin consent for <your tenant>。每个 permission 的 Status 列都应该变成绿色勾选状态。

用于 transcript-first summaries 的必需权限

Section titled “用于 transcript-first summaries 的必需权限”
Permission它允许 app 做什么
OnlineMeetings.Read.All读取 Teams online meeting metadata(主题、参与者、join URL)。
OnlineMeetingTranscript.Read.All读取 Teams 生成的 meeting transcripts。

用于 recording fallback 的必需权限(当 transcript 不可用时)

Section titled “用于 recording fallback 的必需权限(当 transcript 不可用时)”
Permission它允许 app 做什么
OnlineMeetingRecording.Read.All下载 Teams meeting recordings,用于离线 STT 处理。
CallRecords.Read.All当只知道 join URL 时,通过 call records 解析 meetings。

用于 outbound summary delivery 的必需权限(仅 Graph 模式)

Section titled “用于 outbound summary delivery 的必需权限(仅 Graph 模式)”

如果 platforms.teams.extra.delivery_modegraph,pipeline 会通过 Graph API 将 summaries 发布到 Teams channel 或 chat 中。如果你使用 incoming_webhook delivery mode,请跳过这些权限。

Permission它允许 app 做什么
ChannelMessage.Send代表 app 向 Teams channels 发布消息。
Chat.ReadWrite.All向 1:1 和 group chats 发布消息(仅当你将 chat_id 设置为 delivery target 时)。
  • OnlineMeetings.ReadWrite.All / Chat.ReadWrite without .All —— 比 pipeline 需要的权限更宽泛。
  • Delegated permissions —— pipeline 使用 app-only(client-credentials)flow;delegated permissions 如果没有用户登录将无法工作。

步骤 4:(推荐)使用 Application Access Policy 限定 App 范围

Section titled “步骤 4:(推荐)使用 Application Access Policy 限定 App 范围”

默认情况下,像 OnlineMeetings.Read.All 这样的 application permissions 会授予 app 访问 tenant 中每个会议的权限。对于合作伙伴演示和开发 tenant 来说,这没问题;但对于生产环境,你几乎肯定会希望限制该 app 可以读取哪些用户的会议。

Microsoft 为 Teams 提供了 Application Access Policies,正是用于这个场景。该 policy 只能通过 PowerShell 管理;portal 中没有 UI。

在已安装并连接 MicrosoftTeams module 的管理员 PowerShell 中执行(Connect-MicrosoftTeams):

Terminal window
# Create a policy scoped to the Hermes app
New-CsApplicationAccessPolicy `
-Identity "Hermes-Meeting-Pipeline-Policy" `
-AppIds "<MSGRAPH_CLIENT_ID>" `
-Description "Restrict Hermes meeting pipeline to allow-listed users"
# Grant the policy to specific users whose meetings the pipeline may read
Grant-CsApplicationAccessPolicy `
-PolicyName "Hermes-Meeting-Pipeline-Policy" `
-Identity "alice@example.com"
Grant-CsApplicationAccessPolicy `
-PolicyName "Hermes-Meeting-Pipeline-Policy" `
-Identity "bob@example.com"

授予后,传播可能最多需要 30 分钟。使用以下命令验证:

Terminal window
Test-CsApplicationAccessPolicy -Identity "alice@example.com" -AppId "<MSGRAPH_CLIENT_ID>"

如果没有该 policy,任何用户的会议都可以被读取 —— 这正是该 permission 在技术上授予的权限。生产 tenant 中不要跳过这一步。

步骤 5:将凭证写入你的 Env 文件

Section titled “步骤 5:将凭证写入你的 Env 文件”

将你收集到的三个值放入 ~/.hermes/.env

Terminal window
MSGRAPH_TENANT_ID=<directory-tenant-id>
MSGRAPH_CLIENT_ID=<application-client-id>
MSGRAPH_CLIENT_SECRET=<client-secret-value>

设置文件权限,确保只有你能读取 secret:

Terminal window
chmod 600 ~/.hermes/.env

Hermes 随附了一个 Graph auth smoke-test。在你的 Hermes 安装环境中运行:

Terminal window
python -c "
import asyncio
from tools.microsoft_graph_auth import MicrosoftGraphTokenProvider
provider = MicrosoftGraphTokenProvider.from_env()
token = asyncio.run(provider.get_access_token())
print('Token acquired, length:', len(token))
print(provider.inspect_token_health())
"

成功运行会打印一个很长的 token 字符串,以及一个 health dict,其中显示 cached: True,并且 expires_in_seconds 值接近 3600。失败时会产生 MicrosoftGraphTokenError,其中包含 Azure error code —— 最常见的是:

Azure error含义修复
AADSTS7000215: Invalid client secretSecret value 不匹配或已过期。在步骤 2 中生成新的 secret;更新 .env
AADSTS700016: Application not foundMSGRAPH_CLIENT_ID 错误或 tenant 错误。仔细检查步骤 1 中的值是否来自同一个 app。
AADSTS90002: Tenant not foundMSGRAPH_TENANT_ID 有拼写错误。从 app overview 重新复制 Directory(tenant)ID。
call time 出现 insufficient_claims(不是 token time)Token 能获取,但 Graph 返回 401/403。你跳过了步骤 3 的 admin-consent,或者添加了 permissions 但没有重新 consent。回到 API permissions,并再次点击 Grant admin consent。

Azure client secrets 有硬性过期时间。在你的 secret 过期前:

  1. 创建第二个 client secret(步骤 2),不要删除第一个。
  2. 用新值更新 ~/.hermes/.env 中的 MSGRAPH_CLIENT_SECRET
  3. 重启 gateway,让新 secret 生效:hermes gateway restart
  4. 使用上面的 smoke test 进行验证。
  5. 从 Azure portal 删除旧 secret。

当凭证验证正常后,继续:

  • Webhook listener setup —— 启动接收 Graph change notifications 的 msgraph_webhook gateway platform。
  • Pipeline configuration —— 配置 Teams meeting pipeline runtime 和 operator CLI。
  • Outbound delivery —— 将 summaries 发回 Teams channel 或 chat。

这些页面会与添加对应 runtime 的 PR 一起发布。此凭证设置是一个独立前置条件,可以提前安全完成。

-
0:000:00