# Cloudflare: how to read it into Maplith

*DNS · also known as Cloudflare DNS, Cloudflare DMARC Management, DMARC, DMARC aggregate reports, SPF, DKIM, email domain health, email domain · last checked 2026-10-14 · recipe `maplith://systems/cloudflare`*

Cloudflare is where many companies keep their DNS. With a read-only token Maplith reads who sends mail as your domain and whether it passes, and checks every morning that your email domain is protected (SPF, DKIM, DMARC). It never reads a message and never changes a DNS record.

## Best path

**Recommended: Maplith's own integration reads it.** Maplith's own Cloudflare integration reads the DMARC summary with a read-only token, and checks your email domain every morning, under Data sources › Systems in every workspace; without Cloudflare, share an export of the summary.

Try the paths in this order (ADR-0031):

1. **Your agent fetches it**, with the access your human already gave you. No named client connector confirmed: check the tools you already have. The agent looks up the DMARC record of each domain (the TXT record at _dmarc of the domain) and, where its human has a DMARC service, reads its summary: per sending organisation, how many messages passed and failed DMARC, SPF and DKIM over the last weeks. It only reads; it never changes a DNS record.
2. **Maplith reads an MCP server your human already has.** No official MCP server confirmed. Cloudflare runs MCP servers for other parts of its platform; none of them is confirmed to serve DMARC reports. Maplith reads only a server that serves MCP resources and takes a token a person types under Data sources › Systems in the Maplith app, such as the customer-run template for a database (ADR-0028).
3. **Export files**, the fallback that always works: see *Export steps* below.
4. **Maplith's own integration** (available in every workspace, under Data sources › Systems): see *Maplith's integration* below.

## Datasets that make a good map

| Dataset | One row is | Key columns | Joins to |
|---|---|---|---|
| DMARC records | One domain's published DMARC policy: the policy (none, quarantine or reject), the subdomain policy, and where reports go. | domain, p, sp, rua | The sending sources by policy domain. |
| Sending sources | Per policy domain and sending organisation (the network owner of the sending address) and day: how many messages, and how many passed DMARC, SPF and DKIM. | domain, sending organisation, date, messages | The known senders by organisation; the DMARC record by domain. |
| Known senders | The services allowed to send as the domain (a mail provider, a newsletter or billing service) and the forwarders that pass mail on. | organisation, role | The sending sources by organisation. |

Columns are named, never their values. Maplith tries to mask personal data such as email addresses, but that is best effort: your human decides what goes in.

## Read-only access

**Who usually has the rights:** Whoever administers the domain's DNS account, such as a Cloudflare account administrator.

**For the key your own agent's client uses, choose only these read permissions:** `Zone: Zone Read`, `Account: Account Analytics Read`, `Zone: DMARC Management Read`

**Where to click:**

1. In Cloudflare, open My Profile, then API Tokens, and click Create Token
2. Choose Create Custom Token and add the three permissions above, all read. Then turn DMARC Management on for the zone
3. Under Zone Resources, include only the zone of the domain
4. Create the token; it is used in the next step and is never pasted into a chat

A key or token made here stays in the tool that reads the system for your human, never in a chat. Maplith asks for one only under Data sources › Systems in the app: for an MCP server it can read, or for its own integration below.

## Export steps

**Format:** CSV from the DMARC service, or the XML aggregate reports themselves · **Date range:** The last 4 weeks

1. In Cloudflare, open the zone, then Email, then DMARC Management, and export the sources for the last 4 weeks; or collect the aggregate report files the reporting address received
2. Keep per sending organisation and day the message counts and the DMARC, SPF and DKIM pass counts
3. Add the DMARC record of each domain as it is published
4. Upload the files under Data sources › Scans

## Volume hint

**About 100–3,000 rows a month** (an estimate). Estimate for a small company with one or two domains, not a measured figure: one row per sending organisation per domain per day.

Every row an agent reads passes through its context, about one token per four characters. Above a few thousand rows a dataset, or for a daily refresh, prefer an MCP server or an export over fetching through the chat.

## Maplith's integration

**Status:** available in every workspace, under Data sources › Systems.

**How to connect:**

1. Create the read-only Cloudflare token for the domain's zone, as under Read-only access above
2. In Maplith, open Data sources › Systems and connect Cloudflare with the token and the zone ID
3. Maplith reads one day of DMARC sources to check the token, and says which permission is missing if it cannot
4. List the services allowed to send as the domain; Maplith suggests them from what the first read finds

**The permissions it needs, and why:**

- `Zone: Zone Read`: finds the zone of the domain the token is limited to
- `Account: Account Analytics Read`: reads the aggregated DMARC counts through Cloudflare's analytics API
- `Zone: DMARC Management Read`: reads the DMARC sources: per sending organisation, how many messages passed and failed

**What it reads:**

- Per policy domain, sending organisation and day: message counts and how many passed DMARC, SPF and DKIM
- The live DMARC record of each domain, from public DNS
- What reaches the map: the domains and their policy, the known senders, and the drift Maplith finds; counts, never a message

**What it never reads or does:**

- A message, a subject, an address or a sending IP address
- Changing a DNS record: the token is read-only, and a stricter policy is a proposal a person makes
- Zones other than the one the token is limited to

**Choosing what is read:** The token is limited to one zone, and the domains to check are listed with their policy ladder. A person changes the domains, the ladder and the known senders under Data sources › Systems.

## What Maplith sets up once it is connected

Maplith builds these itself; a person corrects them, and never has to approve them first (ADR-0038). If the system is disconnected, Maplith takes the playbooks it set up and nobody changed out of use, and puts them back when the system is connected again; a playbook a person changed stays as they left it.

**Signals:**

| Kind | Delivery | When |
|---|---|---|
| `dmarc_drift` | poll | mail from a sender fails DMARC, an unknown organisation sends as the domain, the next stricter policy is overdue, or the live record no longer matches the ladder |
| `link_dead` | poll | the daily read is refused: the token expired or a permission is missing |

**Checks:**

- **Email domain check** (daily): reads the last 14 days of DMARC sources and the live records, and compares them with the known senders and the policy ladder

**Suggested playbooks:**

- **Tighten DMARC to quarantine.** Starts when the domain has had 14 clean days at p=none and the next rung is overdue. Steps: Read the signal: every message in the last 14 days passed DMARC, and it carries the current record and the proposed one; Propose the change to the person who manages DNS: the TXT record at _dmarc of the domain becomes the proposed record with p=quarantine, keeping rua so the reports keep coming; After the change, look the record up and record the new rung and its date, so the next rung counts its clean days from it; Record what was done on the signal; it resolves itself once the live record is the proposed one.
- **Handle an unknown sender.** Starts when an organisation not on the known-sender list sent mail as the domain. Steps: Read which organisation sent, how many messages, and whether only DKIM passed; If only DKIM passed, it is most likely a forwarder: add it to the known senders as a forwarder; If it is a service the company uses, add it to the known senders; if nobody recognises it, find out who set it up before trusting it; Record what was decided on the signal.
- **Handle a DMARC drift signal.** Starts when any dmarc_drift signal: read its cause, then follow the steps for that cause. Steps: Read the signal: its payload names the cause, the domain and, where there is one, the sending organisation, with counts and never a message.; Mail from a sender failed DMARC (cause failing): Read the counts in the signal: which sending organisation, how many messages, and whether SPF or DKIM passed. If the organisation is one of your senders (a mail, newsletter or billing service), its setup is incomplete: turn on DKIM signing for your domain in that service, or add it to your SPF record, as its documentation says. If you do not recognise it, someone may be sending as your domain: that is what DMARC is for, and a stricter policy stops it. Nothing to change on your side. Record what you did with record_action. The signal resolves itself once 14 days pass without failing mail from that sender.; A sender not on the known-sender list (cause unknown_sender): An organisation not on your list of known senders sent mail as your domain, and it passed DMARC. If only DKIM passed and SPF did not, it is most likely a forwarder (a recipient passing your mail on): add it to the known senders as a forwarder. If it is a service you use, add it to the known senders. If you do not recognise it, find out who set it up before you trust it: it holds a signing key for your domain. Record what you decided with record_action. The signal resolves itself once the sender is on the list, or after 14 days without its mail.; A stricter policy is overdue (cause rung_overdue): Every message in the last 14 days passed DMARC, so the next, stricter policy is safe to take. The signal carries the current record and the proposed one. Propose the change to the person who manages your DNS: replace the TXT record at _dmarc.<domain> with the proposed record. Leave rua as it is so the reports keep coming. After the change, look the record up (dig +short TXT _dmarc.<domain>). The email domain check records the stricter policy the day it first sees it, so the next rung counts its clean days from then; a person can record the true date on the Cloudflare connection under Data sources › Systems in Maplith. Record what was done with record_action. The signal resolves itself once the live record is the proposed one.; The live record is not the recorded rung (cause record_changed): The live DMARC record is not the rung the ladder records, so its clean days cannot be counted. If the change was deliberate, a person records the new rung and the date it was taken on the Cloudflare connection under Data sources › Systems in Maplith (a stricter policy the check sees is recorded by itself). If not, find out who changed it and propose putting it back. Record what you did with record_action. The signal resolves itself once the ladder and the live record agree.; Never change a DNS record yourself: the token is read-only, and a record change is a proposal a person makes..

**Schedules:**

- **Weekly DMARC review** (weekly, Monday 09:00): the policy ladder moves in weeks, and a weekly look catches a rung that is ready before it waits too long

**What setup integrity expects:**

- The Cloudflare connection exists, the email domain check is on and its last daily read succeeded
- Every domain checked has a policy ladder and a list of known senders
- Each suggested playbook exists, or a person removed it

## Always

- Read-only, and never a credential sent to Maplith through the chat.
- The same recent period, a few months, from every system.
- Your human decides what goes in.

## Sources

Written from the vendor's public documentation, last checked 2026-10-14:

- https://developers.cloudflare.com/dmarc-management/
- https://developers.cloudflare.com/fundamentals/api/get-started/create-token/
- https://www.rfc-editor.org/rfc/rfc7489
