Security
How we handle your data
The same honesty rule that governs our numbers governs this page: what is written here is true of the product as it runs today. Where something is being built rather than shipped, we say so in words, not with a badge that implies it already exists.
What we store
Account records for the people who sign in: an email address, a password stored as a one-way hash (never the password itself), and a role. Agency records: a display name, an accent color and an optional logo used to brand the reports an agency shares with its clients. Brand and prompt configuration: the businesses and questions a report measures. Run results: the citations an AI assistant returned, the evidence gathered about each cited page, and the statistics built from them. Access requests submitted from the public site: an email address, a company name, and an optional note. Share-link tokens, which are long random strings, not guessable identifiers. We do not store payment or billing details — there is no checkout in the product today. Cost figures for running a measurement live only on internal, operator-only records; they never appear on a report, a shared link, or any surface an agency or their client can see.
Who can see it
Every request for stored data passes through one gate in our code, scoped to the person who is signed in. An agency account can see only its own brands, its own reports and its own settings — never another agency’s. The one deliberate exception is the operator account, which can see across every agency in order to run the product; that exception is a single, explicit branch in the code rather than a separate set of rules, and it has been independently audited. A shared report is reachable by anyone holding its link, which is how white-label sharing is meant to work — the link is long enough that guessing it is not practical, it is never listed in search engines, and a revoked, expired or otherwise dead link shows the same plain “this link is no longer active” page with no client branding leaked.
How it is protected
Passwords are hashed with argon2id, the algorithm currently recommended for this purpose, using industry-standard cost parameters — never stored or logged in the clear. An account that fails to sign in five times in a row locks for fifteen minutes. Sign-in errors are deliberately generic: a wrong password, an unknown email address and a deactivated account all return the same message and take the same amount of time to answer, so an outside party cannot use the sign-in form to learn which email addresses have accounts. Session cookies are marked so that no script on the page can read them, are sent only over an encrypted connection in production, and are re-checked against the database on every request that matters — a cookie that merely looks valid is not enough on its own.
The database also ships a separate, general-purpose data interface, turned on by default by our hosting provider and reachable from the open internet. We do not use it — the product speaks to the database directly, as its owner — so we turned it off and revoked every permission it had, including the default permissions that would otherwise silently reopen it the next time the database schema changes. That state is re-checked by a command our operator runs before any change to the production database, and the pre-deployment check fails outright if the interface is found open, so a regression here is caught before it ships rather than waiting to be noticed.
A logo an agency uploads for its white-label reports is checked by its actual file content, not just the name of the file or the extension it claims; its dimensions are verified; and if it is an image format capable of carrying a small program inside it, that active content is stripped out before we store it. Secret keys and credentials are never written into the code we keep in version control, and every change to the repository is scanned automatically to catch one that slips in by mistake.
Every page also tells the browser exactly which sources of code and content it may load, and every visit in production is forced onto an encrypted connection for the next two years. Sign-in attempts are limited per visitor as well as per account, and a shared-report link that does not resolve costs the guesser a budget that runs out after sixty misses in ten minutes. Account and settings changes — who signed in, who changed a password, who created or revoked a shared link — are written to a durable record that the operator can read, kept for four hundred days. The libraries the product depends on are scanned for known vulnerabilities before every change is merged, and the check blocks the merge when it finds one.
Any account can add a second step at sign-in: after the password, a six-digit code from an authenticator app on your phone. It is optional for agency accounts and required for our own operator account, the one that can see across every agency. The shared secret behind those codes is encrypted before it is stored, under a key the database itself does not hold, so a copy of the database on its own does not let anyone generate your codes. Each code works once — presenting the same one twice is refused — and enrolling gives you eight single-use recovery codes for the day your phone is not to hand.
You can reset a forgotten password yourself. We email a link that works once and stops working after an hour, and setting a new password signs out every session that was open, including any we did not know about. If your account has the second step turned on, the reset page asks for a code as well as the new password — a recovery code will do. That rule is the point of the feature rather than a detail of it: without it, anyone who reached your mailbox would have reduced your two steps back to one. The reset page tells you nothing about whether an address has an account with us, and neither does the form that asks for the link. Recovering an account that has lost the mailbox as well, or that has lost both its phone and its recovery codes, stays a manual step that a person here carries out.
Sub-processors
A short list, and we mean it to stay short. Two companies run the infrastructure the product is built on: Vercel hosts the application and Supabase hosts the database, in the United States. Two more are how a measurement actually happens: DataForSEO carries out the sampling against OpenAI’s ChatGPT, Google’s Gemini, and Google’s AI Overviews and AI Mode on our behalf, and Perplexity is queried directly for its own answers. One more delivers the few messages we send: Resend, in the United States, receives the address and the text of an invitation, a password-reset link, or the note that a month’s report is ready. It never receives a report, a measurement, or anything about your clients. No other outside company receives your data — no advertising network, no separate marketing or customer-relationship tool.
Data residency
The database lives in Amazon’s Oregon region (us-west-2, in the United States), and stays there. Any transfer of data out of the European Economic Area — for a customer based there — is covered by the Standard Contractual Clauses referenced in our data processing agreement, described below.
Data retention
We keep an account’s data for as long as the account is active. If an agency’s relationship with us ends, or a client asks us to remove their data, we delete it — our data processing agreement commits to doing so within thirty days of a written request. We do not yet run an automatic deletion schedule for data nobody has asked us to remove; today, deletion is something we do on request, not on a timer. That is a gap we state plainly rather than imply otherwise.
What we do not have
We do not hold a SOC 2 report, or any third-party security certification. Below roughly $500 a month, this is the norm for products like ours, not a red flag — but we would rather say it outright than let its absence go unmentioned. If a formal certification becomes a requirement for the agencies we serve, we will pursue one; it is not needed to sign the agreement below. Written policies covering security, access, incident response and vendor handling already exist and are available on request in the meantime.
Reporting a vulnerability
If you find a security problem, email thomas@mapford.com with what you found and how to reproduce it. We read every message at that address ourselves, we will confirm receipt, and we ask that you give us a reasonable window to fix a real problem before describing it publicly.
Request a data processing agreement
If your agency needs a signed data processing agreement to bring Mapford in as a vendor, email thomas@mapford.com and we will send one over. It is a standard agreement — the sub-processor list above, a thirty-day deletion commitment, and the transfer terms referenced under data residency — and your counsel should review it before anyone signs.
Questions about how a measurement itself works, rather than how we handle data, belong on the methodology page.