Skip to content

AI security

How Ask Dockli talks to a governed AI service without ever holding the model key, what leaves the machine and what doesn't, and why a cancelled seat stops the AI server-side.

Last updated: July 2026

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:

  1. An APIM subscription key (Ocp-Apim-Subscription-Key) — a revocable gateway credential.
  2. 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

ConcernHow it’s handled
Model billing keyHeld only by the APIM gateway; injected server-side. Never on the client.
Entitlement / licensingSigned JWT validated at the gateway before the key is injected — fail-closed without a live seat.
Graph tokenNever sent to the model or gateway; tools call Graph server-side as the user.
AttachmentsExtracted text only, in memory, ~3-hour TTL; raw bytes never uploaded.
DictationShort-lived server-minted Speech token; the Speech key stays server-side; only the mic permission is granted.
TrainingContent is not used to train the foundation models.
AuthorizationAll AI actions run as the signed-in user, bounded by their M365 permissions.
Still stuck? Email support@dockli.io — a human replies within one business day. Or book a demo.