> 原始 Markdown 孪生体（构建期从源 Markdown 生成）。渲染页：https://docs.gatellm.io/zh-CN/howto/deploy-office-addin · 文档索引：https://docs.gatellm.io/zh-CN/llms.txt


# 部署 Office 加载项

加载项有两种部署形态：本地 sideload 只用于开发验证；生产走 M365 管理中心集中分发。背景与能力总览见 [Office / Microsoft 365 加载项](/zh-CN/usecases/office-m365-addin.md)。

## 前置准备

- **拿到部署包**：`gatellm-for-msft-365-localhost` 包由 GateLLM 向签约客户提供，**不公开下载**；尚未获取时先经[官网产品页](https://www.gatellm.io/office-addin)接洽。包是一个自包含目录，含 `start.sh` / `sideload.sh`（本地启动与安装）、`scripts/build-manifest.mjs`（manifest 生成）、`webroot/`（预打包的 scrubbed SPA）、`templates/`（manifest 模板）、`commands/`（全部操作手册：consent、Entra app、access_policies、排错等）。下文所有命令都在包目录内执行。
- **Node.js 18+**。
- **mkcert**（`brew install mkcert`）：签受信任的本地 TLS 证书；为什么不能用 openssl 自签见踩坑 1。
- **网关地址（公网域名 + 受信 HTTPS 证书）+ API key**：网关怎么跑起来见快速部署各页（如 [Docker 单机](/zh-CN/quickstart/docker-single-node.md)）。**注意：localhost 起的网关不能用于加载项**——网关必须部署在有公网域名 + 受信 CA 证书的地址上，见下方警告与踩坑 2。
- **（按需）你自己租户里注册的 Entra app**：用 `entra_scope` / `gateway_auth_source=entra`，或不用默认多租户 app 时需要，见下文「注册自己的 Entra app」。

::: warning localhost 网关不能用于加载项测试
本机起一个 HTTPS 网关（哪怕证书本地受信），Office WebView 也连不上——实测就是连不通。本地网关只能验证网关自身；加载项的端到端验证必须先把网关部署到**有公网域名 + 受信 CA 证书**的地址（staging 环境即可），再把 `GATEWAY_URL` 指向它。
:::

## 本地 sideload（开发验证）

1. 配置网关凭据：
   ```bash
   cp .env.example .env   # 填入 GATEWAY_URL（公网域名的 HTTPS 地址，不能是 localhost）与 GATEWAY_TOKEN
   ```
2. 启动并安装：
   ```bash
   ./start.sh            # 读 .env → 签证书 → 生成 manifest → 起 HTTPS 服务
   ./sideload.sh         # 装 office（TaskPane）manifest
   ./sideload.sh --outlook   # 或装 outlook（Mail）manifest
   ./sideload.sh --clear     # 卸载
   ```
3. **验收**：退出并重开 Excel / Word / PowerPoint → **Insert → My Add-ins** 里出现 Gatellm（验证装载成功；与模型的端到端对话还要求网关在公网域名上，见上方警告）。

> sideload 用自签证书，Office 对 `localhost` 较宽松；浏览器打开 `https://localhost:8443` 会有证书警告，正常。

## 生产：M365 管理中心集中分发

生产部署分两半：**SPA 上 CDN** 和 **manifest 上传 M365 管理中心**。

1. **托管 SPA**：把包内 `webroot/` 目录静态托管到你的 CDN（S3 + CloudFront、Azure Static Web Apps、nginx 等）。
2. **生成生产 manifest**（把 `taskpane_url` 指向 CDN origin）：
   ```bash
   node scripts/build-manifest.mjs office manifests/manifest-office.xml \
     taskpane_url=https://gatellm-addin.your-cdn.example \
     gateway_url=https://llm-gateway.your-org.example \
     entra_sso=1 graph_client_id=<guid> gateway_auth_source=entra
   ```
   两个宿主是**两个独立的加载项**（Office 版 TaskPaneApp / Outlook 版 MailApp，权限模型不同）：各自生成 manifest、各自上传、各自管版本。同时部署 Outlook 就用 `outlook` 再生成一份。
3. **校验 manifest**：
   ```bash
   npx --yes office-addin-manifest validate manifests/manifest-office.xml
   ```
4. **上传**：M365 Admin Center → Settings → **Integrated apps** → **Upload custom apps**。**验收**：用户在 Office 里打开加载项，能直接进入对话。

生产硬性要求：

- manifest 的 `<SourceLocation>` 必须**公网可达 HTTPS + 受信 CA 真证书**（不是自签）。
- 全程 HTTPS，SPA 里的 `.js` / `.mjs` 必须以 `text/javascript` MIME 提供。

## Outlook / Entra 管理员同意

有两类同意，互相独立：

| 同意 | 何时需要 | 谁做 |
|------|---------|------|
| Entra SSO 同意 | `entra_sso=1` 且用**默认多租户 app** | Global Admin，每租户一次 |
| Microsoft Graph 同意（邮箱 / 日历） | 部署 **Outlook manifest** 就必需（与 `entra_sso` 无关） | Global Admin，每租户一次 |

- **默认多租户 app**：包内 `commands/consent.md` 给出对应的一次性同意 URL，Global Admin 在已登录的浏览器里打开、点 Accept 即可。不做这一步，每个用户首次打开都会撞 "Need admin approval"；完成后可用 `az ad sp show` 验证服务主体已进租户（命令见同册）。
- **用自己的 Entra app**（设了 `graph_client_id`）：上面的同意 URL 不适用——同意直接在你自己的 app 上管理，见下一节。
- **政策禁止给三方 app 授权**：注册自己的单租户 Entra app，授同一组 Graph 委托权限（`Mail.ReadWrite` / `Calendars.Read` / `People.Read` / `User.Read` / `offline_access`）并做管理员同意，再把它的 client ID 作为 `graph_client_id` 传入 Outlook manifest。数据流不变，只是批准对象换成你的 app。

::: warning 不是所有部署都需要 Entra 同意
不设 `entra_sso=1` 的静态网关 / Vertex 组织级配置用不到 Entra SSO 同意；但只要部署 Outlook，Graph 同意依然必需。
:::

## 注册自己的 Entra app

设置 `graph_client_id`（Outlook）、`entra_scope`、`gateway_auth_source=entra` 中任一项时，都需要在**你自己的租户**注册一个 app。清单如下，完整步骤与排错（`AADSTS50011` / `AADSTS65001` 等）在包内 `commands/entra-app.md`：

1. Entra admin center → **App registrations** → **New registration**（单租户）。最简形态：一个 app 同时充当登录客户端与 token 资源。
2. **重定向 URI**（登记在 **SPA 平台**下，不是 Web / Mobile），两条都按加载项的加载 origin 推导（自托管即你的 taskpane origin）：
   - SPA：`https://<你的-origin>/msal-redirect.html`
   - NAA broker：`brk-multihub://<你的-host>`（只写 origin 的**主机部分**——不带协议头、不带路径，有端口则带端口；由 Office 宿主运行时按加载 origin 拼装）。举例：加载 origin 为 `https://gatellm-addin.your-cdn.example` 时登记 `brk-multihub://gatellm-addin.your-cdn.example`；origin 带端口（如 `https://addin.example:8443`）时登记 `brk-multihub://addin.example:8443`。
   缺任一条，登录报 `AADSTS50011`。
3. **Expose an API**（`entra_scope` / `gateway_auth_source=entra` 必需）：Application ID URI 设为 `api://<app-guid>` → 添加 scope（如 `access_as_user`，允许管理员同意）→ 在 *API permissions* 里把该 scope 作为委托权限授予 app 自身。部署 Outlook 则另加 Microsoft Graph 委托权限（清单见上一节）。
4. **授予管理员同意**（*Grant admin consent for \<tenant\>*）。漏了这步，每个用户都会看到同意对话框，或在禁用用户同意时被直接拒绝。
5. 在 app **Manifest** 里设 `"accessTokenAcceptedVersion": 2`（仅当做了第 3 步 Expose an API）。不设则 Entra 发 v1.0 token（`iss` 不带 `/v2.0`、无 `preferred_username`），多数 JWT 中间件默认拒收。

网关侧对这张 token 做 `iss` / `aud` / `scp` 校验（JWKS 验签），网关怎么配见 [配置 SSO 企业登录](/zh-CN/howto/configure-sso.md)。

## 六条踩坑清单

以下每条都在包 README 排错表里实测过，按部署顺序排：

1. **证书必须用 mkcert**。openssl 自签证书会被 Office WebView 拒收，报 `Add-in Error — can't load the add-in`。`brew install mkcert` 后用 `mkcert -install` 把本地 CA 装入系统信任域。

2. **`GATEWAY_URL` 必须是「公网域名 + 受信 HTTPS 证书」，localhost 不行**。① `http://` 网关会被 Office WebView 的混合内容策略本地拦截，表现为 add-in 里 `Could not reach gateway`，且网关侧监控不到任何请求（请求压根没发出去）；② localhost 起的网关即使走 HTTPS、证书本地受信，Office WebView 实测也连不上——本地网关没法给加载项做端到端测试，必须部署到有公网域名 + 受信 CA 证书的地址。

3. **浏览器直开 `https://localhost:8443` 跳 `gatellm.io/downloads` 是正常的**。这是 SPA 的 host 检测——发现「不在 Office 宿主里」就引导下载。加载项必须在 Office 里打开，不是在浏览器里。

4. **CDN 必须满足三点**：`.js` / `.mjs` 供成 `text/javascript` MIME；目录索引设为 `index.html`；配置 SPA fallback 把未知路径回 `index.html`（给 `/auth/callback` 用）。否则 chunk 404 / MIME 错误。

5. **所有运行时 fetch 目标都要放行 CORS**。`bootstrap_url`、`mcp_servers[].url`、`skills[].url`、`otlp_endpoint` 的响应头都要放行 taskpane origin：
   ```
   Access-Control-Allow-Origin: https://gatellm-addin.your-cdn.example
   ```

6. **同 `<Id>` 同 `<Version>` 重传会被静默忽略**。M365 Admin Center 按 ID + Version 缓存，改 `<Version>` 第四段（如 `1.0.0.9` → `1.0.0.10`）再传。

## 下一步

- [Office / Microsoft 365 加载项](/zh-CN/usecases/office-m365-addin.md) 看能力、治理与数据面。
- 网关侧按真实用户鉴权 / 计费，配合 [配置 SSO 企业登录](/zh-CN/howto/configure-sso.md)。
