Security and data handling

What Sigil asks for, what it stores, where it runs and how to report a problem. Written for the person who has to sign off admin consent.

Microsoft Graph permissions Sigil requests

Sigil requests three Microsoft Graph application permissions at admin consent. All three are read-only. No write permission and no mail permission is requested, so Sigil cannot send mail, change directory data or read message content.

ScopeTypeWhy Sigil needs it
User.Read.AllApplicationReads the directory attributes a signature is personalised from: name, job title, department, phones, address, manager and extension attributes. The narrowest scope that returns title, department and phone numbers.
Organization.Read.AllApplicationReads the organisation’s name and registered address once, at onboarding, to pre-fill the billing profile. It never overwrites an address an admin has saved.
GroupMember.Read.AllApplicationResolves group membership for group-based assignment rules and group-based mailbox exclusions.

Separately, the Outlook add-in’s manifest declares the Office permission ReadWriteItem. That is the add-in permission on the message currently being written, which the Office API requires in order to insert a signature into it. It is not a Graph permission and grants nothing on your tenant.

How sign-in works

  • Users of the add-in are signed in silently with Microsoft Entra ID using nested app authentication; portal administrators sign in with a standard Entra single-page-app flow.
  • Every API call carries an Entra-issued token that Sigil verifies itself: signature, issuer, audience, home tenant and scope. A separate portal_admin scope keeps administrator tokens distinct from add-in tokens.
  • There are no shared secrets in the add-in. Its code is public by design; the security boundary is the verified token.
  • No personal data travels in a URL. The add-in requests a signature with a POST whose body carries the mailbox address, so nothing identifying lands in a proxy log, browser history or referrer header.

Tenant isolation

Data is pooled with a tenant identifier on every row, and storage, cache and asset keys are tenant-scoped. The two code paths that legitimately query across that scope carry explicit guards with regression tests behind them, so isolation is checked rather than asserted.

Where data is stored and processed

Sigil runs on Cloudflare’s developer platform. The application, including signature rendering, runs as a Cloudflare Worker with a placement hint for Cloudflare’s Western Europe region, so requests are normally processed in the Cloudflare data centre nearest that region rather than wherever the person happens to be. A placement hint is a latency setting, not an enforced boundary: Cloudflare can move execution for network maintenance or under very high load. The enforced guarantees are the jurisdictions on the stores below.

The database, the per-tenant stores, uploaded images, backups and the signature cache were all created under Cloudflare’s EU jurisdiction restriction. A jurisdiction is fixed when a resource is created and cannot be relaxed afterwards, so it is a guarantee enforced by Cloudflare rather than a routing preference we could quietly change.

  • Database (tenant records, templates, rules, telemetry, audit log): Cloudflare D1 in the EU jurisdiction. Cloudflare only creates read replicas of an EU-jurisdiction database inside the EU.
  • Per-tenant stores (a tenant’s own dedicated data store, and the live-update channel the portal uses): Cloudflare Durable Objects, created in the EU jurisdiction.
  • Uploaded images (logos, banners): Cloudflare R2 object storage in the EU jurisdiction.
  • Backups: a nightly dump of the database to a separate R2 bucket, also in the EU jurisdiction, that nothing in the application reads from. Each dump expires after 30 days.
  • Cache: Cloudflare KV holds short-lived copies of rendered signatures and of the directory details they are built from, so the next message a person writes is fast wherever they are. The namespaces are in the EU jurisdiction, so the cache is durably stored inside the EU. Cloudflare may still hold a transient copy of a cached entry on its global network while it is being served. Entries are per tenant, expire on their own and are refreshed when a template or rule is published.

The data processing agreement makes the same commitment and covers those transient copies under an adequacy decision or the UK Addendum to the EU Standard Contractual Clauses. If your organisation needs something stricter, ask us before you onboard.

What we store and what we don’t

Stored

  • Directory attributes, read on demand from Microsoft Graph to render a signature and cached only transiently.
  • Signature templates, compliance footers, campaign banners and the images you upload.
  • Signature activity metadata: which mailbox requested a signature, which template version was served, the compose type, and whether the add-in applied it. This is what the per-mailbox adoption report is built from.
  • Click counts on tracked links in signatures and banners. Per-click detail expires after 90 days.
  • Your organisation’s tenant record, subscription details and an append-only log of administrator actions.

Never stored

  • Message content, and the rendered signature HTML.
  • Recipient identities. Sigil does not know who you emailed.
  • IP addresses of your users or of anyone who clicks a link.
  • Payment card numbers. Card handling is performed by Stripe.
  • Tokens. Telemetry stores metadata only.

Sub-processors

ProviderPurposeLocation
MicrosoftIdentity (Microsoft Entra ID) and directory data (Microsoft Graph)Your tenant’s own Microsoft 365 region; Sigil reads through Graph and stores nothing there
CloudflareApplication hosting, database, storage, caching and transactional emailDatabase, per-tenant stores, uploaded images, backups and cache under Cloudflare’s EU jurisdiction; application compute normally in Western Europe (a placement hint, not a jurisdiction); transient cached copies on Cloudflare’s global network
StripeSubscription billing and payment card processingStripe’s own infrastructure; card data never reaches Sigil

GDPR, DPA and data subject requests

Your organisation is the controller of its directory data and Sigil is a processor. A data processing agreement can be read and accepted in the portal, and acceptance is recorded. Per-mailbox data subject access request export is built in. For our own account and billing records we act as controller; contact privacy@usesigil.app. The privacy policy has the full detail.

Reporting a vulnerability

If you believe you have found a security issue in Sigil, email security@usesigil.app. Please give us a reasonable time to investigate and fix the issue before disclosing it publicly. The same contact is published in /.well-known/security.txt.