Deploy the Office add-in
The add-in has two deployment forms: local sideload is only for development verification; production goes through centralized distribution in the M365 admin center. See Office / Microsoft 365 add-in for the background and capability overview.
Prerequisites
- Get the deployment package: the
gatellm-for-msft-365-localhostpackage is provided by GateLLM to contracted customers and is not publicly downloadable; if you haven't obtained it, first reach out via the official product page. The package is a self-contained directory containingstart.sh/sideload.sh(local start and install),scripts/build-manifest.mjs(manifest generation),webroot/(a pre-built scrubbed SPA),templates/(manifest templates),commands/(all operation guides: consent, Entra app, access_policies, troubleshooting, etc.). All commands below run inside the package directory. - Node.js 18+.
- mkcert (
brew install mkcert): signs a locally trusted TLS certificate; see pitfall 1 for why you can't use an openssl self-signed certificate. - Gateway address (public domain + trusted HTTPS certificate) + API key: see the quick-deployment pages (e.g. Docker single node) for how to run the gateway. Note: a gateway running on localhost cannot be used for the add-in — the gateway must be deployed at an address with a public domain + trusted CA certificate, see the warning below and pitfall 2.
- (As needed) an Entra app registered in your own tenant: needed when using
entra_scope/gateway_auth_source=entra, or when not using the default multi-tenant app, see "Register your own Entra app" below.
A localhost gateway cannot be used for add-in testing
Even if you run an HTTPS gateway locally (with a locally trusted certificate), the Office WebView still can't connect — this has been field-tested to fail. A local gateway can only verify the gateway itself; end-to-end validation of the add-in requires first deploying the gateway to an address with a public domain + trusted CA certificate (a staging environment is fine), then pointing GATEWAY_URL at it.
Local sideload (development verification)
- Configure gateway credentials:bash
cp .env.example .env # fill in GATEWAY_URL (an HTTPS address on a public domain, cannot be localhost) and GATEWAY_TOKEN - Start and install:bash
./start.sh # reads .env → signs the cert → generates the manifest → starts the HTTPS service ./sideload.sh # installs the office (TaskPane) manifest ./sideload.sh --outlook # or installs the outlook (Mail) manifest ./sideload.sh --clear # uninstall - Acceptance: quit and reopen Excel / Word / PowerPoint → Insert → My Add-ins shows Gatellm (confirms successful loading; end-to-end conversation with a model still requires the gateway to be on a public domain, see the warning above).
Sideload uses a self-signed certificate, and Office is more lenient with
localhost; openinghttps://localhost:8443in a browser shows a certificate warning, which is normal.
Production: centralized distribution via the M365 admin center
Production deployment splits in two halves: the SPA onto a CDN and the manifest uploaded to the M365 admin center.
- Host the SPA: statically host the package's
webroot/directory onto your CDN (S3 + CloudFront, Azure Static Web Apps, nginx, etc.). - Generate the production manifest (pointing
taskpane_urlat the CDN origin):bashThe two hosts are two independent add-ins (the Office version TaskPaneApp / the Outlook version MailApp, with different permission models): generate each manifest, upload each, and version each separately. If deploying Outlook too, generate another one withnode 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=entraoutlook. - Validate the manifest:bash
npx --yes office-addin-manifest validate manifests/manifest-office.xml - Upload: M365 Admin Center → Settings → Integrated apps → Upload custom apps. Acceptance: the user opens the add-in in Office and can enter a conversation directly.
Production hard requirements:
- The manifest's
<SourceLocation>must be publicly reachable HTTPS + a real trusted CA certificate (not self-signed). - HTTPS throughout, and the
.js/.mjsin the SPA must be served with thetext/javascriptMIME type.
Outlook / Entra admin consent
There are two kinds of consent, mutually independent:
| Consent | When needed | Who does it |
|---|---|---|
| Entra SSO consent | entra_sso=1 and using the default multi-tenant app | Global Admin, once per tenant |
| Microsoft Graph consent (mail / calendar) | Required when deploying the Outlook manifest (independent of entra_sso) | Global Admin, once per tenant |
- Default multi-tenant app: the package's
commands/consent.mdgives the corresponding one-time consent URL; the Global Admin opens it in an already-logged-in browser and clicks Accept. Without this step, every user hits "Need admin approval" on first open; after completion you can verify the service principal has entered the tenant withaz ad sp show(command in the same guide). - Using your own Entra app (set
graph_client_id): the consent URL above does not apply — consent is managed directly on your own app, see the next section. - Policy forbids granting third-party apps: register your own single-tenant Entra app, grant the same set of Graph delegated permissions (
Mail.ReadWrite/Calendars.Read/People.Read/User.Read/offline_access) and do admin consent, then pass its client ID asgraph_client_idinto the Outlook manifest. The data flow is unchanged; only the approval object becomes your app.
Not all deployments need Entra consent
A static gateway / Vertex organization-level config without entra_sso=1 does not use Entra SSO consent; but as long as you deploy Outlook, Graph consent is still required.
Register your own Entra app
Setting any of graph_client_id (Outlook), entra_scope, gateway_auth_source=entra requires registering an app in your own tenant. The checklist is below; full steps and troubleshooting (AADSTS50011 / AADSTS65001, etc.) are in the package's commands/entra-app.md:
- Entra admin center → App registrations → New registration (single-tenant). Minimal form: one app acts as both the login client and the token resource.
- Redirect URIs (registered under the SPA platform, not Web / Mobile), both derived from the add-in's load origin (self-hosted = your taskpane origin):
- SPA:
https://<your-origin>/msal-redirect.html - NAA broker:
brk-multihub://<your-host>(write only the origin's host part — no scheme prefix, no path; with a port, include the port; assembled by the Office host at runtime from the load origin). Example: when the load origin ishttps://gatellm-addin.your-cdn.example, registerbrk-multihub://gatellm-addin.your-cdn.example; when the origin has a port (e.g.https://addin.example:8443), registerbrk-multihub://addin.example:8443. Missing either one givesAADSTS50011on login.
- SPA:
- Expose an API (required for
entra_scope/gateway_auth_source=entra): set the Application ID URI toapi://<app-guid>→ add a scope (e.g.access_as_user, allowing admin consent) → in API permissions grant that scope as a delegated permission to the app itself. If deploying Outlook, additionally add Microsoft Graph delegated permissions (list in the previous section). - Grant admin consent (Grant admin consent for <tenant>). Miss this step and every user sees the consent dialog, or is directly rejected when user consent is disabled.
- In the app's Manifest, set
"accessTokenAcceptedVersion": 2(only when you did step 3 Expose an API). Without it, Entra issues a v1.0 token (isswithout/v2.0, nopreferred_username), which most JWT middleware rejects by default.
The gateway validates iss / aud / scp on this token (JWKS signature verification); see Configure SSO enterprise login for how to configure the gateway.
Six pitfalls checklist
Each item below has been field-tested in the package README's troubleshooting table, ordered by deployment sequence:
The certificate must use mkcert. An openssl self-signed certificate is rejected by the Office WebView, reporting
Add-in Error — can't load the add-in. Afterbrew install mkcert, runmkcert -installto install the local CA into the system trust store.GATEWAY_URLmust be a "public domain + trusted HTTPS certificate"; localhost won't do. ① Anhttp://gateway is blocked locally by the Office WebView's mixed-content policy, appearing asCould not reach gatewayin the add-in, and the gateway monitors no requests at all (the request was never sent); ② a gateway started on localhost, even over HTTPS with a locally trusted certificate, still can't be reached by the Office WebView in practice — a local gateway can't do end-to-end testing for the add-in and must be deployed to an address with a public domain + trusted CA certificate.Opening
https://localhost:8443in a browser and being redirected togatellm.io/downloadsis normal. This is the SPA's host detection — finding "not inside an Office host" it guides a download. The add-in must be opened inside Office, not in a browser.The CDN must satisfy three points: serve
.js/.mjsas thetext/javascriptMIME type; set the directory index toindex.html; configure SPA fallback to return unknown paths toindex.html(for/auth/callback). Otherwise chunks 404 / MIME errors.All runtime fetch targets must allow CORS. The response headers of
bootstrap_url,mcp_servers[].url,skills[].url, andotlp_endpointmust allow the taskpane origin:Access-Control-Allow-Origin: https://gatellm-addin.your-cdn.exampleRe-uploading the same
<Id>with the same<Version>is silently ignored. The M365 Admin Center caches by ID + Version; change the fourth segment of<Version>(e.g.1.0.0.9→1.0.0.10) and upload again.
Next steps
- Office / Microsoft 365 add-in for capabilities, governance, and the data plane.
- On the gateway side, authenticate / bill by real users, together with Configure SSO enterprise login.
