Skip to content

Spam Filter Whitelist

PhishSpot phishing simulations look like real attacks — that’s the point. Corporate spam filters (Microsoft 365, Google Workspace, Mimecast, Proofpoint, on-prem Postfix/SpamAssassin) will routinely block them unless they’re explicitly whitelisted. This chapter explains how to give your mail-server admin a single URL they can plug into their filter, and have it stay current automatically.

SPF, DKIM and DMARC tell receiving servers “this email is genuinely from the domain it claims to be from.” For real phishing they often pass — that’s exactly why phishing is hard. But the same checks pass for our simulations too, and modern spam filters use much more than SPF/DKIM: they look at content patterns, link reputation, sender behaviour history, and dozens of other signals. Several of those signals will (correctly!) classify a phishing simulation as suspicious.

The right fix is for the receiving filter to bypass spam scanning for traffic that comes from PhishSpot. That requires the admin to tell their filter:

  • which IP addresses we send from,
  • which sending domains we use, and
  • (optionally) which exact sender addresses appear on the From: header.

PhishSpot generates that list per account and exposes it at a stable URL. Configure your filter to pull it on a schedule (or react to our webhook when it changes) and you’re done.

Open Account settings → Integrations → Spam Filter Whitelist. You’ll see a panel with:

  • Your unique URL containing a 64-character secret token,
  • A format picker (txt / json / csv / md / Microsoft 365 / Google Workspace / Mimecast / Proofpoint / Postfix / SpamAssassin),
  • A status badge showing when the URL was last fetched and from which IP,
  • A rotate button to invalidate the current URL,
  • A disable toggle that returns 410 Gone until re-enabled,
  • A live preview of what’s currently allowed,
  • A download history of the last 50 fetches.

The URL is a single line you copy-paste into your spam filter or a small refresher script. There’s no API token, no Authorization header — the secret is in the path, and HTTPS encrypts it in transit. We rate-limit each token to 60 requests per minute, log every fetch (IP + UA) in the download history, and run on HTTPS only.

FormatWhen to use
txtPlain text. Default. Easy to grep and pipe into scripts.
jsonStructured payload. Best for custom integrations.
csvGeneric CSV — good as a fallback.
mdHuman-readable Markdown — for documentation and review.
microsoft365PowerShell snippet + Tenant Allow/Block List commands for Exchange Online.
google-workspaceCSV laid out for the Google Admin email allowlist import.
mimecastCSV in Mimecast’s Permitted Senders policy shape.
proofpointCSV in Proofpoint PPS Safelist shape.
postfixaccess table snippet for on-prem Postfix.
spamassassinwhitelist_from lines for local.cf.

URL pattern: https://platform.phishspot.com/api/v1/integrations/spam/<TOKEN>/<format> — leave the format off and you get plain text.

  1. In the PhishSpot panel, pick Microsoft 365 (PowerShell) and copy the URL.
  2. Save it to phishspot-whitelist.ps1 on a workstation that has Exchange Online PowerShell installed.
  3. Run Connect-ExchangeOnline (you’ll need Exchange Administrator rights).
  4. Execute the script. It does two things:
    • Adds each sending domain and address to the Tenant Allow/Block List with New-TenantAllowBlockListItems,
    • Merges the gateway IPs into the Hosted Connection Filter Policy via Set-HostedConnectionFilterPolicy.
  5. Optionally create a Mail Flow rule with “skip spam filtering” for senders matching @<your-phishspot-domain>. Re-pull the URL weekly to keep the list current.
  1. Pick the Google Workspace (CSV) format and download the file.
  2. In Google Admin Console, go to Apps → Google Workspace → Gmail → Spam, phishing and malware.
  3. Open the Email allowlist for your top-level OU and paste the IP entries from the CSV (one per line).
  4. Open Inbound gateway (also in Spam settings) and add the same IPs. This is what makes Gmail bypass spam scoring for those connections.
  5. To allow by domain instead of IP, add the domain entries from the CSV to the Approved senders list (same section).
  1. Pick Mimecast (CSV) in the panel.
  2. In Mimecast Administration, go to Gateway → Policies → Permitted Senders.
  3. Click Import and upload the CSV. Mimecast picks up sender IPs from the Sender IP column and senders/domains from the Sender column.
  4. Either schedule a curl job (curl -fSL '<URL>' > whitelist.csv then re-import) or use the Mimecast API for automation.
  1. Pick Proofpoint PPS (CSV).
  2. Either upload via System → User Management → Safelists → Import in the PPS UI, or push via the PPS REST API (/api/v1/safelist/import).
  3. PPS treats sender, domain and IP entries differently — the CSV’s type column tells PPS which list to put each row in.
  1. Pick Postfix access table.
  2. Save to /etc/postfix/phishspot_whitelist, then run postmap /etc/postfix/phishspot_whitelist to compile the lookup table.
  3. Reference it from main.cf:
    smtpd_sender_restrictions =
    check_sender_access hash:/etc/postfix/phishspot_whitelist,
    ...
  4. Run postfix reload.
  5. For IP-based bypass, copy the IPs into a separate CIDR file and add check_client_access cidr:/etc/postfix/phishspot_ips to smtpd_client_restrictions.
  1. Pick SpamAssassin local.cf.
  2. Append the snippet to /etc/spamassassin/local.cf.
  3. Validate with spamassassin -D --lint.
  4. Restart spamd.
  5. The snippet uses whitelist_from *@<domain> and trusted_networks <ips> — the latter raises the trust score for relayed mail.

The whitelist changes when you (or PhishSpot) add a sending domain, when a campaign uses a new From: address, or when our infrastructure team rotates gateway IPs. To keep the customer side current automatically:

  1. In Account settings → Webhooks → Endpoints, add a new endpoint pointing at a URL on your side.
  2. Subscribe to the event type spam_whitelist.updated.
  3. When the list changes we POST to that URL with a signed payload (HMAC-SHA256 in X-Webhook-Signature using the endpoint’s signing secret). The payload includes the new snapshot digest and the full set of whitelist URLs across formats.
  4. Your handler verifies the signature, then triggers your platform-specific import (the PowerShell job above, the Google Admin API call, Mimecast / Proofpoint API, etc.).

We retry failed deliveries 5 times with exponential backoff. After 5 consecutive failures we email account admins so the integration doesn’t silently rot.

We track when each URL was last fetched. If 24 hours pass without a successful fetch — meaning your spam filter has stopped pulling the list — we email every admin on the account. The most common causes:

  • The cron / scheduled task that pulls the URL stopped.
  • Your firewall is now blocking outbound HTTPS to platform.phishspot.com.
  • The URL was rotated and the old one expired before anyone updated the filter.
  • The integration was removed from the spam filter accidentally.

To silence the warning, re-trigger the fetch from your side (one curl is enough — we reset the counter on every successful request).

  • Schedule the pull at least daily, ideally hourly. The endpoint is cheap to hit.
  • Verify the snapshot digest (X-PhishSpot-Snapshot-Digest header) — if it matches what you have, skip the re-import to avoid noise in your downstream system.
  • Rotate quarterly. Even with no leak, regular rotation limits blast radius if a script ever logs the URL.
  • Monitor your side too. Alert if the cron job hasn’t run successfully in N hours. Don’t rely only on our stale-warning email.
  • Use the webhook in addition to the cron, not instead of it. The cron is the safety net; the webhook is the fast path.
  • Test your bypass with PhishSpot’s “Send test email” feature in a campaign before going live. If the test doesn’t land in the recipient inbox, your bypass isn’t working.

“Our phishing simulations still go to spam.” Confirm the spam filter is actually pulling the URL: check the download history in the PhishSpot panel — does the IP and timestamp match your filter’s egress IP and pull schedule? If yes, check the bypass rule is on the correct policy (often filters have separate inbound vs. transport policies). If no, the URL isn’t reaching the filter.

“The CSV format my filter expects is different.” Use the plain csv format as a template and transform it server-side. The json format is the most flexible source — easy to map to any target schema with jq or a 20-line script.

“Our webhook isn’t receiving deliveries.” Check the endpoint URL in Webhooks → Endpoints — make sure it’s HTTPS, publicly reachable, and not behind an authentication wall. Open the endpoint detail page in PhishSpot to see the delivery log with response codes and response bodies. Verify the HMAC signature handling on your side matches OpenSSL::HMAC.hexdigest("SHA256", signing_secret, raw_body).

“What if you change your gateway IPs?” You’ll get a spam_whitelist.updated event the moment we make the change, and the URL response includes the new IPs immediately. If your filter has a fresh pull within the change window, you’ll never notice.

“Can I have multiple URLs for different filters?” Not in the MVP — there’s one active URL per account. If you need separate URLs (e.g., for a phased rollout), use the rotation flow: rotate, wait 24h, rotate again. Each rotation gives you a fresh URL with a 24-hour grace period.