Security
How M365Clarity protects your data and your Microsoft 365 tenant.
Read-only Microsoft Graph access
M365Clarity is operated by Stephen Bennett as a sole trader. We are registered with the Information Commissioner's Office (ICO) under registration number ZC173030. You can verify this at ico.org.uk.
M365Clarity requests only read-only Microsoft Graph API scopes. It is technically impossible for M365Clarity to:
- Modify any settings in your Microsoft 365 tenant
- Send emails on your behalf
- Access the content of emails, files, Teams messages, or calendar events
- Create, delete, or modify users, groups, or policies
You can view and revoke M365Clarity's permissions at any time via myapps.microsoft.com.
Token encryption
Microsoft OAuth access and refresh tokens are encrypted with AES-256-GCM before being written to the database. The encryption key is stored in Cloudflare's secrets management system, separate from the data store. Tokens are:
- Encrypted before storage using a unique IV per token
- Decrypted only at scan execution time in server memory
- Never logged, never transmitted to third parties (except Microsoft to perform the scan), and never exposed in API responses
- Automatically refreshed before each scan without requiring you to re-authenticate
MSP client data encryption
For MSP Multi-Tenant accounts, sensitive client data is encrypted at the application layer using per-organisation AES-256-GCM keys before being written to the database. This is in addition to Cloudflare's default encryption at rest.
The following fields are encrypted at the application layer with a unique AES-256-GCM key derived per MSP organisation, in addition to Cloudflare's default encryption at rest:
- Client tenant company names and primary domains
- MSP team member email addresses and names
- MSP account company name and domain
The encryption key is derived using HKDF (SHA-256) from a secret pepper stored in Cloudflare's encrypted secrets management system — it is never stored in the database alongside the encrypted data. Encrypted values are stored with an enc:v1: prefix. Even with complete access to the database, client company names and team member details cannot be read without the separate encryption key.
This encryption applies to all MSP data including existing records — a full migration was run on 22 June 2026 to encrypt all pre-existing plaintext values.
The MSP admin's own login email address is not encrypted at the application layer as it is required for authentication, billing, and support communications.
Data storage
- Location: Cloudflare D1 (SQLite) — WEUR region (Amsterdam, Netherlands)
- Encryption in transit: TLS 1.3 for all connections
- Encryption at rest: Cloudflare D1 encrypts all data at rest by default
- Isolation: all database queries include user ID and tenant ID scoping — cross-tenant data access is architecturally prevented
What is encrypted, and at which layer
There are two distinct layers. Understanding the difference matters, so here is exactly what applies to each plan.
| Data | Platform encryption at rest (all plans) | Additional application-layer encryption |
|---|---|---|
| Microsoft OAuth access & refresh tokens | Yes | Yes — all plans. AES-256-GCM, unique IV per token |
| Scan results and configuration findings | Yes | No — these are your own tenant's configuration state, not credentials |
| Your account name and email (Free and Pro) | Yes | No — required in plaintext for authentication, billing and support |
| MSP client company names, domains, team member names and emails | Yes | Yes — MSP plans. AES-256-GCM, per-organisation key |
Why the difference: MSP accounts hold data about third parties — an MSP's client list is commercially sensitive and those clients never agreed to be listed with us. That warrants a second layer of protection where the key is held separately from the data. For Free and Pro accounts the stored personal data is your own name and email, which must remain readable for us to log you in, bill you and reply to your support requests. Encrypting them at the application layer would prevent that while adding no meaningful protection, since the key would need to be available on every request anyway.
Your Microsoft credentials are the genuinely sensitive item, and those are encrypted at the application layer on every plan, with the key held in Cloudflare's secrets store rather than in the database.
IP address policy
M365Clarity does not store IP addresses in its database. Rate limiting is enforced in memory at the Cloudflare edge for authentication and checkout endpoints — the IP is used only at request time and never written to storage. Cloudflare's own infrastructure handles DDoS mitigation and abuse detection at the network level.
This is a deliberate design decision: IP addresses are personal data under UK GDPR, and storing them indefinitely would create an unnecessary data processing obligation with no operational benefit once the request has been handled.
Authentication and sessions
- Session tokens are 128-bit cryptographically random values generated using the Web Crypto API
- Sessions expire after 30 days and are stored in Cloudflare KV with automatic TTL
- Rate limiting is enforced per IP on authentication and checkout endpoints — the IP is used only at request time and is never written to storage (see IP address policy below)
- All authenticated endpoints require a valid Bearer session token
- One-time codes (OTC) for MSP tenant connection: when an MSP connects a client tenant, a short-lived one-time code is generated server-side (60-second TTL, single use, immediately deleted on first read). The browser redirects to Microsoft's OAuth flow carrying only the OTC — the MSP session token is never placed in a URL. This prevents session tokens from appearing in server access logs, browser history, or referrer headers.
Audit logging
All significant actions are logged to an audit trail associated with your account, including logins, scan starts, schedule changes, remediation actions, ticket email sends, data exports, and billing events. Audit log entries contain only the action name, timestamp, and account ID — no IP addresses or browser identifiers are recorded. You can view your audit log in Account settings and export it as part of your data export. Audit log entries are automatically purged after 12 months.
Guest account and personal data handling
The Guest Audit feature reads external guest user names, email addresses, and sign-in dates from your tenant. This data is classified as personal data under UK GDPR. It is:
- Stored within your account in the EU (WEUR region) under the same access controls as scan data
- Scoped strictly to the connecting user and tenant — no cross-tenant or cross-user access is possible by architecture
- Not shared with any third party
- Deleted when you disconnect the tenant or delete your account
M365Clarity does not send guest account data to Anthropic or any AI provider. AI features only receive feature names and configuration statuses — not personal data about individuals in your tenant.
Ticket email security
When you use the Ticket Export feature to send findings by email, M365Clarity sends the email via Brevo (transactional email provider) from noreply@m365clarity.com. The email contains only the feature name, severity, category, and AI-generated remediation hint — no personal data, no raw Graph API data, and no authentication credentials. The recipient email address is the one on your M365Clarity account (or a helpdesk address you provide), and is transmitted to Brevo under their standard DPA.
Webhook security
Stripe webhook payloads are verified using HMAC-SHA256 signature verification before processing. Payloads older than 5 minutes are rejected to prevent replay attacks.
Infrastructure
M365Clarity runs entirely on Cloudflare Workers — a serverless edge compute platform with no persistent server processes. The attack surface is minimal by design:
- No persistent server processes or VMs to compromise
- No SSH access or open ports
- Cloudflare's global network provides automatic DDoS mitigation
- All secrets managed via Cloudflare's encrypted secrets store
- MSP logos stored in private Cloudflare R2 object storage (WEUR region) — never publicly accessible, served only to authenticated MSP sessions via the Worker
Responsible disclosure
If you discover a security vulnerability in M365Clarity, please report it responsibly to security@m365clarity.com. We ask that you:
- Give us reasonable time to investigate and remediate before public disclosure
- Do not access or modify data belonging to other users
- Do not perform destructive testing
We will acknowledge all valid reports and aim to respond within 48 hours.