Policy
Privacy: what this service stores
What this service writes down, why each record exists, how long it stays, and what a reader can check without taking our word for it.
This page lists every record this service keeps, 9 in all. For each one it says where it lives, what it holds, and how long it stays.
What is stored
Of the 9 records, 6 are about the sites that were scanned, and the people their pages name. The other 3 are about the client that made a request.
The SQLite storage of one Durable Object, ScanHub, holds 6 of the 9 records. The object is created in the EU jurisdiction.
| Record | Where it lives | What it holds | How long it stays |
|---|---|---|---|
| Scan record | The records table in the SQLite storage of the ScanHub Durable Object, one row for each host and port. It is published in full at /aws/<key> and in the report files. | The host, the target URL, the scan time, and the rubric version. The homepage title and meta description as written, with its language, word count, size, and token estimate. The 61 check results, each with a detail line and an evidence line of at most 600 characters. The fingerprint, a summary of the previous measurement, and a request log of path, status, bytes, time, and content type. | Until it is removed on request, or evicted oldest-first once the store holds more than 500 records. A record a published directory listing points at is not evicted. A new scan of the same origin replaces it. A deleted row stays in point-in-time recovery for 30 days. |
| Scan job | The jobs table in the SQLite storage of the ScanHub Durable Object. A job's progress and its copy of the scan record stay in memory while the scan runs. | The scan target, its host and declared site profile, its state, the times it started and ended, and the error of a scan that failed. No client address. | At most 200 jobs, and past that the oldest finished job is dropped first. A finished job is also dropped at the next scan request or report view once it is 30 minutes old. A job that was running when the object restarted is marked as interrupted. A deleted row stays in point-in-time recovery for 30 days. |
| Badge claim | The badges document, a row of the docs table in the SQLite storage of the ScanHub Durable Object | The token, the host, the origin that was measured, and the issue and expiry dates. Whether and when the token was last found, and the time of the last verification attempt. Nothing about who made the claim. The score is read from the scan record when the badge is drawn. | The token expires after 365 days. The entry stays until it is removed on request. A deleted row stays in point-in-time recovery for 30 days. |
| Directory listing | The directory document, a row of the docs table in the SQLite storage of the ScanHub Durable Object | The host, the origin, the listing kind (verified or exemplar), whether it is published, and the last confirmation time. The score, grade, level, fingerprint, and scan time are read from the scan record when a page is rendered. | Published only while it was confirmed within the last 30 days. After that the entry stays in the document, unpublished. A verified entry is deleted when a verification finds its token gone or expired. An exemplar stays until the exemplar list is rewritten. A host on the removal list is not published. A deleted row stays in point-in-time recovery for 30 days. |
| Removal list | The suppressed document, a row of the docs table in the SQLite storage of the ScanHub Durable Object | Each removed hostname, in lowercase, with the time the removal was requested. A hostname covers every port and scheme. | Until the operator deletes the entry by hand. It has no expiry, because it is what keeps a removed host from being scanned again. A deleted row stays in point-in-time recovery for 30 days. |
| Rate-limit entries | The hits table in the SQLite storage of the ScanHub Durable Object | A salted SHA-256 hash of your client address, and the times of your requests in the current 1-minute window. They sit in 5 limiters: scans, health checks, badge claims, badge verifications, and verification page lookups. Behind Cloudflare, the address is the one in CF-Connecting-IP. The salt is a secret kept outside the storage. A hash is not anonymous: whoever holds the secret can test an address against it. | A hash of an address is kept for 1 minute, the window of its limit. The limiter by token keeps a hash of the token for 10 minutes, and it holds no address. A hash is deleted when a later request to a limited endpoint finds its window passed. If none comes, the object deletes it when it falls due. Cloudflare's point-in-time recovery keeps a copy of the storage for 30 days, and a deleted hash is still in that copy. A restart does not clear the windows. |
| Error lines | The Worker's console.error output, which Workers Logs stores, and the address in ERROR_WEBHOOK_URL when the operator sets one | One JSON line for each internal failure: the error, its stack, and the scan target, host, job id, or check id involved. No client address. | As long as Cloudflare keeps them in Workers Logs, and the webhook's owner keeps what it receives. This service sets no limit. |
| Cloudflare request log | Cloudflare, which carries every request to this service | Whatever Cloudflare records for a request to its network. This service cannot read it and writes no access log of its own. Its Workers invocation logs, which would record request metadata, are off. | Workers invocation logs are off. Cloudflare decides how long it keeps what it records. |
| Theme cookie | Your browser | aws-theme, set to light or dark. It is HttpOnly and SameSite=Lax, and Secure when the site is served over https. | Written only when you press the theme toggle. It lasts 365 days, or until you clear it. |
A stored scan record is the whole measurement: every status, the points behind it, and the evidence that produced it.
Evidence is an excerpt of the scanned site
A check records what it observed. Its detail line and its evidence line are each cut to 600 characters or fewer. Both are stored with the record and shown on the report page.
That text is the site's own. It can be a line of security.txt, a response header, or an excerpt of body text. It can also be a contact email or telephone number the site publishes in its JSON-LD.
It is not masked, because the evidence is what was observed. The record also keeps the homepage title and meta description as written. A person named in any of this text can ask for the record to be removed: see how removal works.
No whole response body is stored. The request log holds the path, the status, the byte count, the time, and the content type of each request.
Why each record exists
- The scan record keeps a report link stable:
/aws/<key>still resolves after the request that produced it. - The fingerprint lets a reader check the outcomes without trusting this service. It binds the host, the rubric version, and each check's id, status, rounded points, and counted flag. The detail and evidence text are not bound.
- A scan job lets a report page show a scan while it runs, and say how it ended.
- The claim record is the proof of control. A listing is published only when the token inside it is found on the host itself.
- The directory listing says whether a host is listed, and whether the claim is the site's or ours.
- The removal list is what makes a removal last. Without it, the next request for a removed host would scan it again.
- The rate-limit entries are what make the ceilings hold. Without a client key there is no per-client ceiling.
- An error line is how the operator learns that a check or the store failed.
- Cloudflare keeps its own record of the traffic it carries. This service does not read it.
- The cookie stores 1 choice, the theme, so a page can render it without a script.
How long each one stays
At most 500 scan records are kept. Past that, the oldest are dropped first, so a record has no expiry date but it can be evicted.
A scan request reuses a record younger than 6 hours, unless it asks for a fresh scan. A request that declares a site profile reuses only a record measured under that same declared profile. A request that declares none reuses only a record whose profile was detected.
A later scan of the same origin overwrites the row. A report URL shows the stored record whatever its age, and never starts a scan.
A record a directory listing points at is never evicted automatically, because deleting it would break a published link. Removal on request still applies to it. That protection and a site owner's wish are inverted. The records kept longest are the ones a directory chose, not the ones an owner wants kept.
A badge token lives 365 days from the day it was issued. After that it proves nothing, and a listing behind it is withdrawn.
A listing is published only while it was confirmed within the last 30 days. An entry that has aged out is withheld rather than shown as stale. It stays in the directory document until a verification or a new exemplar list removes it.
The windows of the rate limiters and the job registry are rows in the object's storage, and a restart does not clear them. A job that was running when the object restarted is marked as interrupted. The count of scans running at once is not stored. A restart ends every running scan, so the count starts again at 0.
A limiter row is a salted SHA-256 hash of a client address or of a token, and the time of one request. It is kept for the window of its limit, which is 1 minute for an address and 10 minutes for a token. The object deletes it when a later request to a limited endpoint finds its window passed. If none comes, it deletes the row when it falls due.
Cloudflare replicates the object's storage. Its point-in-time recovery keeps a copy for 30 days. A deleted row is still in that copy, a removed record and a deleted hash included.
The salt of the hashes is a secret kept outside the object's storage. A hash is not anonymous: whoever holds the secret can test an address against it.
What is not collected
- No analytics. No tracking pixel, no session recorder, and no third-party measurement tag.
- No executable script. Every page is rendered on the server, and the only
<script>element carriesapplication/ld+jsonstructured data. - No account and no password. Nothing here has a login, and nothing asks for your email address.
- No client address is stored in the clear. The rate limiters keep a salted hash of it for the window of the limit, and Cloudflare, which carries the request, may log it.
- No invocation log. The Worker's invocation logs, which would record request metadata, are off.
- No whole response body. An evidence line quotes at most 600 characters of what a check observed.
How to check this
- Count the script elements on any page:
curl -s https://agenticwebscore.com/ | grep -o "<script" | wc -lanswers 1. - The theme toggle is the one thing that sets a cookie:
POST /api/themewrites it when you press it. No page render writes one, whatever the request carries. Check it:curl -sI https://agenticwebscore.com/privacy | grep -i set-cookieprints nothing. - The stores are SQLite tables in the object:
records,docs,jobs,hits, andmeta. The operator reads them in Cloudflare's dashboard. A record is also published in full at/aws/<key>. - The route probe suite runs the script check on every page, and
npm run verifyfails when a page loads an executable script.
Who else receives data
Reading a page here sends no request to another origin. The 2 typefaces are served from this site: no font host, no analytics, no tag manager, and no advertising. The only <script> element is application/ld+json, which a browser does not execute.
Running the service sends data to others. Each recipient is listed here.
- The scanned site receives the scanner's requests. Each one names the scanner in its
User-AgentandFromheaders, and carries nothing about who asked for the scan. - A host the scanned site redirects to receives the request too, with the same
User-AgentandFromheaders. - DNS resolvers receive the scanned hostname. Every lookup goes to
cloudflare-dns.comover DNS-over-HTTPS, including the check of each host before it is requested. It also receives 4 DNS-AID questions: SVCB and TXT for_index._agents.<host>and_agent.<host>. Cloudflare's network resolves the host again when it connects. These questions carry the hostname, not your address. - The error webhook receives every error line, when the operator sets
ERROR_WEBHOOK_URL. - Cloudflare runs this service and its Durable Object, which holds 6 of the 9 records. The object is created in the EU jurisdiction.
- Anyone can read a scan record. It is published in full at
/aws/<key>and in its report files.
Removal and contact
A record is removed on request, and the removal lasts. Send the hostname, and the fingerprint if you have it, to hello@agenticwebscore.com. A question about what a record holds about you goes to the same address.
Read how removal works. That page also states what the scanner requests and how to stop it.
Who to contact
Privacy, removal, and data requests go to hello@agenticwebscore.com. This page gives no legal advice.