DRAFT — pending legal review

Pharos privacy policy

DRAFT. Not legal advice. Needs legal review before any Chrome Web Store submission. Written for the alpha (5 to 10 trusted testers who install the unpacked extension themselves). It describes what the code in this repository does as of version 0.6.0 (Weekend 4.5 added the optional alpha tester backend, section 2a; Weekend 5 added rescans when a page changes after it was checked, section 1). If the code and this document disagree, the code is wrong or this document is out of date: please open an issue.

Pharos is a browser extension that warns about and blocks phishing pages, fake virus warnings, payment scams and malicious downloads. To do that it has to look at the pages you visit. This document says exactly what it looks at, what leaves your computer, what stays, and what never happens.

A shorter, plain-language version ships inside the extension (extension/privacy.html, linked from onboarding and Settings → Privacy).

1. What Pharos reads

DataWhenWhy
Page URLEvery page you open (top frame)Checked against blocklists, scored by local URL heuristics, sent to the checkers below for pages that aren't already known
Page titleEvery page Pharos checksContext for the checkers
Visible page text and inline scripts (DOM text)Every page Pharos checksRead on your computer only: (a) hashed into a short fingerprint so a page that was already judged isn't sent again; (b) matched against patterns that identify redirect notices and browser security-warning pages, which Pharos skips. The text itself is not stored and not sent anywhere
Screenshot of the visible part of the pageOnly once the screenshot checker (Cloudflare) is set up, and only for pages that aren't on the popular-sites allowlist, aren't blocked or warned by the URL checks, and aren't in the verdict cache. Taken again if the page changes significantly after it was checked (a full-screen overlay appears, it goes fullscreen, its content is replaced, it opens repeated dialogs, or its text changes a lot), because scam pages can look harmless at firstSent to the screenshot checker (Clef) and, when it is unsure, to the AI double-check (the arbiter)
Download URL and file nameEvery downloadChecked against blocklists and file-name heuristics; suspicious downloads are paused until you choose Keep or Discard
How often a page opens alert()/confirm() dialogsEvery pageA page firing many dialogs in a short time is closed (a common scam trap)

The arbiter does not receive page text. It gets the same screenshot, URL and title as Clef, plus Clef's probability scores.

2. What Pharos sends, and to whom

In Direct mode (the default) Pharos has no server of its own. Everything external goes from your browser directly to a third party, using accounts and API keys that you own. Alpha tester mode is different; see section 2a.

RecipientWhat is sentWhen
Cloudflare Workers AI (api.cloudflare.com, model @cf/cloudflare/clef-flash) on your Cloudflare accountScreenshot (JPEG, at most 1280 px wide), page URL, hostname, page title, and fixed instructionsPages that reach the screenshot tier (see above)
The AI service you chose for the double-check: OpenAI, Anthropic, Google (Gemini) or xAIThe same screenshot, URL, hostname and title, plus Clef's scoresOnly when Clef's answer is not a clear "legitimate" (typically a few pages in a hundred). Never when the arbiter is set to Off or has no key
Blocklist publishers: URLhaus (abuse.ch), OpenPhish, and PhishTank if you add a keyNothing about you. Pharos downloads their public lists (PhishTank's download URL contains your PhishTank key)On install, every 6 hours, and when you click Refresh
The same checkers, for "Test connection"The Pharos icon as the image, and https://example.com/ as the URLOnly when you click Test connection or Check again

Each of these companies handles that data under its own terms and privacy policy, under your account with them. Review those terms, in particular whether the provider may retain or train on API inputs.

2a. Alpha tester backend (only if you set an alpha token)

Alpha testers can use Pharos without any accounts of their own. This mode is only active when you explicitly choose it: by answering "Yes" to "Do you have a Pharos alpha token?" during setup and pasting a token, or by selecting "Alpha tester" under Settings → Backend mode and saving a token. Switching back to Direct mode stops it immediately.

In alpha mode, the Pharos developer runs a small server (a Cloudflare Worker with a D1 database, code in worker/). It holds the developer's own Cloudflare and AI keys; your browser never receives them.

What crosses the network to the Worker:

RequestContentsWhen
Screenshot check (/v1/clef)Your tester token, plus the same request Pharos would otherwise send to Cloudflare: screenshot, page URL, hostname, page titlePages that reach the screenshot tier
AI double-check (/v1/arbiter)Your tester token, plus the same request Pharos would otherwise send to OpenAI or Anthropic: screenshot, URL, title, the screenshot checker's scoresWhen the screenshot checker is unsure
Budget check (/v1/quota)Your tester tokenAt browser start, every 5 minutes, and when you press Test or Check again
Telemetry (/v1/telemetry)Your tester token and the same counts as section 5 (verdicts by category, latency buckets, error and panic counts), plus each "Pharos got this wrong" report with the page's URL and title, and a note when the backend was unreachableAbout once a minute, or after 50 events, only while "Help improve Pharos" is ticked (it is ticked for you when you switch to alpha mode; untick it to stop)

The Worker passes screenshot and double-check requests on to Cloudflare Workers AI, OpenAI or Anthropic, under the developer's accounts, and returns their answers. Those providers' terms apply, under the developer's account.

What the Worker stores (D1):

TableContents
testersYour token, the name and email the developer entered when inviting you, creation date, budget, amount spent, active flag
eventsPer check: the model, token counts, cost, latency and success or error status. Never the screenshot, the URL or the title of a checked page. Telemetry batches (counts only), panic-button triggers, quota-exceeded events, backend-health failures, and your "Pharos got this wrong" reports (which do include the URL and title you reported)
daily_rollupPer tester and day: number of checks, verdict counts, panic count, cost

This data is linked to your tester token, and the developer knows which token they gave to whom, so it is pseudonymous rather than anonymous. It is used only to run the alpha: to keep within budgets, find bugs, and improve Pharos's accuracy. The developer sees it on a password-protected dashboard (tokens shown by their last 4 characters only) and, optionally, in a weekly email summary that lists false-positive reports with their URLs.

Retention: all telemetry and events are to be deleted 30 days after the alpha ends (the commands are in worker/README.md), and tester records with them. You can ask the developer to delete your data sooner.

Budget: each token has a small spending limit ($1 by default). When it is reached, Pharos shows a one-time notice and makes no calls to the Worker for 24 hours; it keeps protecting you with the checks that run on your computer (and your own Cloudflare key, if you set one up).

3. What Pharos stores on your computer

All in the browser's extension storage (chrome.storage), on this computer and this browser profile only. Nothing is synced to your Google account.

DataWhereHow long
Settings: Cloudflare account ID and API token, arbiter provider, model and API keys, PhishTank key, thresholds, developer-mode and telemetry choiceschrome.storage.localUntil you change them, Reset Pharos, or uninstall
Verdict cache by page fingerprint (origin + text hash → verdict)chrome.storage.sessionUntil the browser closes
Verdict cache by screenshot fingerprint (perceptual hash + URL → verdict)chrome.storage.local24 hours, at most 2000 entries
Per-tab state (current verdict, pending scans, held downloads, protection status)chrome.storage.sessionUntil the tab or browser closes
Blocklist index (blocked URL → which list)chrome.storage.localReplaced at every refresh
Scan log ("dev log"): page URLs, titles, verdicts, small screenshots, raw Clef answers, arbiter explanations, errorschrome.storage.localOnly while developer mode is on; last 1000 entries
"Pharos got this wrong" reports: URL, title and the verdict shownScan logKept even with developer mode off, because you created them on purpose; same 1000-entry limit
Telemetry (only if you opt in): counts per day of verdicts by category, latency histograms per tier, error counts by type, panic-button counts, report countschrome.storage.local90 days, or until you erase it
Onboarding progresschrome.storage.localUntil Reset Pharos or uninstall
Alpha tester settings (if used): backend mode, tester token, Worker address, a pending-upload queue of telemetry events, and the end of a quota pausechrome.storage.localUntil you change them, Reset Pharos, or uninstall. The token is never written to the log (only its last 4 characters)

API keys are never written to the scan log, telemetry, error messages or any exported file: every stored key is scrubbed from log entries before they are saved and again when the log is exported, and telemetry is rebuilt from fixed lists of allowed fields at export time.

4. What Pharos never sends

5. Telemetry

6. Your rights and controls

7. Children

Pharos is not directed at children and collects no personal information about anyone.

8. Changes

This is a draft for an alpha. Material changes will be noted in the repository's commit history and announced to testers before they ship.