Technical¶
The security model — what runs where, what the add-in can access, how users authenticate — and implementation detail for people debugging or extending. For what users experience, see How It Works.
In one paragraph¶
The add-in's own code and API are served by the customer's own Lime CRM instance — there is no Lime-hosted middle service, and email data is never sent anywhere else. It can read only the email the user currently has open, and only while they have it open. Users sign in with their own Lime CRM credentials using a standard OAuth flow; there are no API users, no shared service accounts and no tokens for IT to distribute. Email content travels directly from the user's Outlook to the customer's Lime CRM and nowhere else — the task pane does load a UI library and some styling from Microsoft and a public CDN at page load; see Content Security Policy and transport.
What runs where¶
graph LR
O["Outlook<br/>(task pane)"] -->|"reads the open message<br/>via Office.js"| O
O -->|HTTPS| C["Customer's<br/>Lime CRM instance"]
C -->|"serves the add-in,<br/>the save form and the API"| O
M["Microsoft<br/>Office.js library"] -.->|"loaded by every<br/>Office add-in"| O
| Component | Hosted by |
|---|---|
| The add-in task pane | The customer's Lime CRM instance |
| The save form | The customer's Lime CRM instance (it is the web client) |
| The API the add-in calls | The customer's Lime CRM instance |
office.js |
Microsoft (appsforoffice.microsoft.com) — mandatory for all Office add-ins |
| Web client assets | cdn.lime-crm.com |
No separate Lime-operated middle service receives or transports email data; the customer's Lime CRM instance is the processing and storage location (and may be hosted on Lime Cloud).
Components¶
Everything ships in the single limepkg-mail-addin package:
| Part | What it is |
|---|---|
| Flask backend | Custom endpoints on the Lime CRM instance: OAuth device-code authentication, email import, and serving the Outlook manifest. |
| Outlook task pane | An Office.js add-in running inside Outlook. Reads the open message and hands it to the backend. |
| Web client components | Stencil web components rendered inside the Lime CRM Web Client — the import form, the success screen, and the OAuth authorization dialog. |
| Lime Admin component | A Stencil web component for configuring the add-in in Lime Admin. |
The task pane is served from the Lime CRM instance at <base-url>/<database>/limepkg-mail-addin/addin.
What the add-in can access¶
The manifest requests the ReadWriteItem permission. In Microsoft's add-in permission model this grants access to:
- The message the user currently has open — subject, body, sender, recipients, headers, attachments, and date.
- Writing a custom property back onto that same message — used to mark an email as saved, so reopening it shows "Already saved".
It does not grant:
- Access to other messages in the mailbox.
- Access to the mailbox as a whole, folders, or search.
- The ability to send, delete or move mail.
- Access to the calendar or contacts.
- Any server-side or background access to the mailbox. The add-in only runs while a user has it open.
The add-in also declares SupportsSharedFolders, which lets it work in shared mailboxes the user already has access to. It does not grant access to any mailbox the user cannot already open.
Table and field definitions¶
The add-in requires no specific limetype or fields to exist. The administrator picks an existing limetype during configuration and maps email properties onto its fields. Nothing is added to the data model on install.
Field type constraints are enforced in the configuration UI:
| Mapping | Accepted property types |
|---|---|
| From (Sender) | belongsto, hasone |
| Received Date | date, time |
| Subject | string |
| Body | text |
| Headers | text, string |
Attachments and the .eml file¶
Alongside the user's own attachments, the add-in generates an .eml copy of the full email — headers, body, inline images and attachments bundled into one file. It appears in the attachment list like any other attachment, so the user can keep or remove it.
The attachment selector separates files into two groups: regular attachments (including the .eml file) and embedded images (images referenced from the body via CID, such as pasted screenshots).
Signature images are excluded from the selector entirely. The backend identifies signature regions using the HTML markers common email clients insert around signature content — Outlook, Gmail and Proton Mail among them — and flags images found inside them. See Known Limitations for coverage.
How attachments are linked¶
When the chosen limetype has a relation to Document, selected attachments are saved as Document records. How they attach to the created record depends on that relation:
hasmanyrelation to Document — every selected Document is linked to the record through that relation. This is the recommended setup.belongstorelation to Document — a separate picker lets the user choose which single saved Document fills that relation. The remaining Documents are still saved, but are not linked through it.
Inline images¶
Images embedded in the body are matched to their attachment by the attachment's content id when the email provides one, and otherwise by comparing the filename in the image's CID reference against the attachment filename.
When matching succeeds the image renders normally in the saved body. When it fails, a placeholder is shown in its place and the original is still kept as an attachment. See Known Limitations for why matching fails.
Import tracking¶
The "already saved" state is stored on the Outlook item itself, using Office.js custom properties — not in the Lime CRM database.
Consequences:
- Tracking is per mailbox. The same email in two mailboxes gives each user an independent status.
- In a shared mailbox the marker is visible to everyone with access.
- Deleting the record in Lime CRM does not clear the marker in Outlook.
How users sign in¶
The add-in uses the OAuth 2.0 Device Authorization Grant (RFC 8628) — the same pattern as pairing a TV app with an account.
sequenceDiagram
participant U as User
participant A as Add-in in Outlook
participant C as Lime CRM
A->>C: Request a device code
C-->>A: Show a short code
U->>C: Sign in to Lime CRM and approve the code
C-->>A: Issue tokens for that user
A->>A: User is connected
What this means in practice:
- No API user or service account is required.
- No secret or token is distributed to users by IT.
- Each user authenticates as themselves. Emails are saved under their own identity, and their existing Lime CRM permissions apply unchanged — the add-in cannot do anything in CRM the user could not do in the web client.
- Approval happens in Lime CRM's own sign-in page, protected by whatever the customer has configured there.
This replaces the previous add-in's model of manually managed API users and tokens.
Tokens¶
| Access token | Valid for 1 hour. Signed JWT. Identifies the user to the Lime CRM API. |
| Refresh token | Valid for 30 days. Single-use — each refresh issues a new one and invalidates the old one. |
| Stored | In the browser storage of the Outlook task pane, on the user's own device. Not on any shared server. |
| Signed with | A per-application secret held only by the customer's Lime CRM instance (the JWT signing key). |
Tokens are per user and per device. A user who signs in on a laptop and a phone has two independent connections.
Device-flow state and refresh-token records are held in Redis — provided by the platform on Lime Cloud, configured explicitly on-premise.
Revoking access¶
- A user can disconnect from the task pane, which clears the tokens stored on that device. This does not revoke the refresh token server-side — it remains valid until it expires naturally (up to 30 days) unless also revoked administratively.
- An administrator can revoke a user's access server-side.
- Removing a user from Lime CRM removes their ability to save emails, since every request is authorised as that user.
Because access tokens are self-contained and short-lived, an already-issued access token remains valid until it expires — at most one hour after an administrator revokes it.
Where the data goes¶
Email content is read in the task pane and sent directly to the customer's Lime CRM instance over HTTPS.
- No analytics, telemetry or error-reporting service receives email content.
- No Lime-operated service sits in the path.
- No data is shared with third parties.
See GDPR for what is stored and why.
Content Security Policy and transport¶
The task pane is served with a CSP that:
- restricts outbound connections (
connect-src) to the Lime CRM origin — the add-in cannot call any other service; - allows scripts from Microsoft's Office add-in hosts,
cdn.lime-crm.comandunpkg.com; styles and fonts from Microsoft's Office add-in hosts andcdn.lime-crm.com; - restricts
frame-ancestorsto Microsoft's Outlook domains, so the task pane cannot be embedded by an arbitrary site.
The Lime CRM backend must be served over HTTPS. Office add-ins refuse to load over plain HTTP, and the add-in will not work without it.
Hosts that must be reachable from the client: Network requirements.
The JWT signing key¶
Before users can sign in, a signing key must be set in the application configuration:
<your-app>:
secrets:
limepkg_mail_addin:
jwt_signing_key: <a long random string>
Treat this like any other application secret:
- Generate it randomly and make it long. It is not a password anyone types.
- It is unique per application — do not reuse one across customers or environments.
- Changing it invalidates every existing connection; all users must reconnect.
See Configuration.
Platform differences¶
The add-in detects mobile hosts and adjusts:
- Attachment content is not fetched on mobile — Office.js does not expose it there. Attachments are recorded as unavailable rather than failing the import.
- The save form opens by navigation rather than in a dialog on mobile, since a separate window is not workable there.
Questions IT often asks¶
Does the add-in have standing access to our mailboxes? No. It runs only in the user's Outlook, only while the task pane is open, and only against the message they have open. There is no background or server-side mailbox access.
Do we need to create an application registration in Entra ID? No. The add-in does not authenticate against Microsoft — it authenticates against Lime CRM.
Can a user save emails they shouldn't see? No. The add-in can only read the message the user already has open in their own (or a shared) mailbox, and it can only write to Lime CRM as that user, with that user's permissions.
Where can we see what was saved? Every saved email is a normal record in Lime CRM, subject to the same audit, access rules and retention as any other record.
What happens if we uninstall the add-in? Records already saved in Lime CRM are unaffected. See Deploying to Outlook.
Related¶
- Configuration — every setting
- Known Limitations — edge cases and their causes