Ask Dockli (the Spark plan’s AI assistant) is built so that the client never holds a model key, the AI can only ever act within the signed-in user’s permissions, and a cancelled or lapsed licence stops paid AI server-side — not just in the UI. This page covers the full trust model.
The AI gateway: no client key, fail-closed
Ask Dockli uses Azure OpenAI (gpt-4o), but the Dockli client never talks to Azure OpenAI directly and never holds the Azure OpenAI billing key. Every request goes through an Azure API Management (APIM) gateway.
On each AI call, the Dockli service attaches two things to the request to the gateway:
- An APIM subscription key (
Ocp-Apim-Subscription-Key) — a revocable gateway credential. - A signed entitlement token (
X-Dockli-Entitlement) — a short-lived JWT proving the user has a live, licensed seat.
The gateway then does the security-critical work server-side:
- It validates the entitlement JWT — signature, and that it corresponds to an active seat — before doing anything else.
- Only if validation passes does it inject the real Azure OpenAI key and forward the request to the model.
This is fail-closed: if the entitlement can’t be minted or is invalid, the gateway rejects the call. A patched or reverse-engineered client that somehow kept the subscription key still cannot use paid AI without a live seat, because the key it needs is never on the client to begin with — the gateway holds it.
A lapsed seat stops the AI, server-side
The entitlement token is signed by the licensing service (RSA / RS256) and carries the tenant, user, tier, and seat status, with a short lifetime. Dockli refreshes it periodically, so a cancelled or expired seat stops working at the gateway within the refresh window — even if the client’s UI is momentarily stale. Enforcement does not depend on the client behaving. See Licensing and entitlement.
What is — and isn’t — sent to the model
Ask Dockli is deliberately narrow about what leaves the machine:
- The Microsoft Graph token is never sent to the model or the gateway. The AI runs inside the same loopback service that owns the delegated token; when a tool needs Graph (search, calendar, move a file), it calls Graph server-side. The AI orchestration and the model see the results a tool returns, not your access token.
- For attachments, only extracted text is sent — never raw file bytes. When a user attaches a document, Dockli extracts its text and sends that text as context. The original binary is never uploaded to the model.
- Only what’s needed for the turn — the conversation history the user sees, the system prompt, any attached document text, and the results of tools the model called — is sent. Raw file contents are pulled in only when the user asks the AI to read or act on a specific file, and only that file’s extracted text is used.
Attachment handling: extracted text, short-lived, in memory
When a user attaches a document to a conversation:
- Dockli extracts the text and stores it in an in-memory store keyed by a generated id. The raw bytes are not persisted.
- Entries are evicted by age and count — a time-to-live of roughly three hours, and a cap on how many are retained.
- The extracted text is never written to disk and is not part of any long-lived cache. There is no server-side AI session — the visible conversation lives on the client, which replays the attachment ids for follow-up turns.
The total attachment text fed to the model per turn is capped so a large stack of documents can’t overflow the context window; text beyond the cap is truncated rather than silently dropped.
Dictation: short-lived Speech tokens
Ask Dockli’s dictation (speech-to-text) uses Azure Speech, and the Speech resource key never reaches the client, exactly like the OpenAI key:
- The client asks Dockli’s loopback service for a token each time it starts dictating.
- The service exchanges the Speech key server-side for a short-lived authorization token (about a 10-minute lifetime, region-scoped) and returns only that token to the browser Speech SDK.
- Because the token is always freshly minted at the start of dictation, it stays well within its lifetime, and the long-lived key stays on the server side.
On the WebView2 side, the shell extension auto-grants only the microphone permission so dictation works in the secure https://app.dockli.local context. Every other browser permission kind is left at WebView2’s default (deny), so enabling dictation doesn’t widen the surface beyond the mic.
The model doesn’t train on your content
Ask Dockli runs on Azure OpenAI, where prompt and completion content is not used to train the foundation models. Your documents and conversations are processed to answer the request in the moment; they are not turned into training data for the underlying model.
Scoped to the user’s permissions
The AI is not a privilege-escalation path. Every tool it can call runs as the signed-in user, through the same delegated Graph token as the rest of Dockli:
- It can only find, read, and act on files the user could already reach — the same permission model applies to AI-initiated actions.
- If an operation is denied by the user’s own M365 permissions, the tool returns that failure and the AI reports it plainly; it cannot retry its way around a permission boundary.
- Destructive operations (delete, cross-account transfer) surface a confirmation the user must approve; the AI cannot fabricate that a file operation succeeded.
More on AI privacy
For a plain-language walkthrough of what the assistant can see, what it retains, and the choices available to users and admins, see AI privacy and security.
Summary of the AI trust boundaries
| Concern | How it’s handled |
|---|---|
| Model billing key | Held only by the APIM gateway; injected server-side. Never on the client. |
| Entitlement / licensing | Signed JWT validated at the gateway before the key is injected — fail-closed without a live seat. |
| Graph token | Never sent to the model or gateway; tools call Graph server-side as the user. |
| Attachments | Extracted text only, in memory, ~3-hour TTL; raw bytes never uploaded. |
| Dictation | Short-lived server-minted Speech token; the Speech key stays server-side; only the mic permission is granted. |
| Training | Content is not used to train the foundation models. |
| Authorization | All AI actions run as the signed-in user, bounded by their M365 permissions. |