Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions scripts/check-site.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

The page makes promises a reviewer should not have to re-check by hand:

- no third-party subresources (fonts included) — the self-hosted analytics
ingest is the one first-party exception,
- no third-party subresources (fonts included) — the cookie-free analytics
ingests (self-hosted Plausible, Cloudflare Web Analytics) are the only
exceptions,
- the release metrics the deploy script injects are present and findable,
- JSON-LD structured data parses and the FAQ stays in sync with it,
- every in-page anchor resolves and the public anchor ids stay put,
Expand Down Expand Up @@ -44,11 +45,14 @@
# The only host a subresource may load from (the page serves from this domain).
OWN_DOMAIN = "tailroute.app"

# First-party hosts a subresource may additionally load from: the self-hosted
# Plausible ingest, same registrable domain, DNS-only behind grey cloud. It
# must stay that way — proxying it through a CDN challenges cross-origin
# event POSTs and pageviews drop silently.
FIRST_PARTY_HOSTS = frozenset({"pulse.tailroute.app"})
# Analytics hosts a subresource may additionally load from. Both are
# cookie-free, aggregate-only page analytics: the self-hosted Plausible
# ingest (same registrable domain, DNS-only behind grey cloud — proxying it
# through a CDN challenges cross-origin event POSTs and pageviews drop
# silently) and the Cloudflare Web Analytics beacon, which per Cloudflare
# "does not collect or use your visitors' personal data". Nothing else may
# load cross-origin.
ANALYTICS_HOSTS = frozenset({"pulse.tailroute.app", "static.cloudflareinsights.com"})

# Claims the page must never make again: unsourced, stale, or contradictory.
BANNED_PHRASES = (
Expand Down Expand Up @@ -310,8 +314,8 @@ def external_host(url):


def subresource_host_allowed(host):
"""Same-origin, or a first-party host (see FIRST_PARTY_HOSTS)."""
return not host or host == OWN_DOMAIN or host in FIRST_PARTY_HOSTS
"""Same-origin, or an approved analytics host (see ANALYTICS_HOSTS)."""
return not host or host == OWN_DOMAIN or host in ANALYTICS_HOSTS


def inline_styles(page):
Expand Down Expand Up @@ -411,7 +415,7 @@ def check_third_party(pages, css_sources):
fails.append(Failure(
page.rel, element.line,
f'<{element.tag} {attr}> loads from "{host}"'
f" — every subresource must be same-origin or first-party",
f" — every subresource must be same-origin or an approved analytics host",
))
style = element.attrs.get("style")
if style:
Expand All @@ -422,7 +426,7 @@ def check_third_party(pages, css_sources):
fails.append(Failure(
page.rel, element.line,
f'inline style loads from "{host}"'
f" — every subresource must be same-origin or first-party",
f" — every subresource must be same-origin or an approved analytics host",
))
for source in css_sources:
for pattern in CSS_URL_PATTERNS:
Expand All @@ -431,7 +435,7 @@ def check_third_party(pages, css_sources):
if not subresource_host_allowed(host):
fails.append(Failure(
source.rel, source.line_at(match.start()),
f'CSS loads from "{host}" — every subresource must be same-origin or first-party',
f'CSS loads from "{host}" — every subresource must be same-origin or an approved analytics host',
))
return fails

Expand Down
4 changes: 3 additions & 1 deletion site/docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
<!-- Plausible analytics: self-hosted, first-party (same registrable domain).
Ingest = pulse.tailroute.app; keep it DNS-only — never CDN-proxy it. -->
<script defer data-domain="tailroute.app" src="https://pulse.tailroute.app/js/script.js"></script>
<!-- Cloudflare Web Analytics: cookie-free, aggregate-only. -->
<script type='module' src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "418fcc4385174264b82cae5eb6305a76"}'></script>
<script type="application/ld+json">
{
"@context": "https://schema.org",
Expand Down Expand Up @@ -340,7 +342,7 @@ <h2 id="see-also">See also</h2>

</main>
<footer>
<p class="colophon">No trackers, no analytics on this page—the daemon doesn’t call home either.</p>
<p class="colophon">Site analytics: cookie-free, aggregate-only (Plausible + Cloudflare)—the daemon doesn’t call home either.</p>
<p class="legal">CLI: Apache-2.0 · App: proprietary · © 2026 <a href="https://github.com/shrwnsan/tailroute-cli">tailroute</a> · not affiliated with Tailscale Inc. · <a class="backlink" href="../">← tailroute</a></p>
</footer>
<script>
Expand Down
2 changes: 2 additions & 0 deletions site/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
<!-- Plausible analytics: self-hosted, first-party (same registrable domain).
Ingest = pulse.tailroute.app; keep it DNS-only — never CDN-proxy it. -->
<script defer data-domain="tailroute.app" src="https://pulse.tailroute.app/js/script.js"></script>
<!-- Cloudflare Web Analytics: cookie-free, aggregate-only. -->
<script type='module' src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "418fcc4385174264b82cae5eb6305a76"}'></script>
<!-- /region:assets -->

<!-- region:meta owner:meta -->
Expand Down
26 changes: 22 additions & 4 deletions tests/test-check-site.sh
Original file line number Diff line number Diff line change
Expand Up @@ -283,11 +283,29 @@ PY
assert_not_contains "FAIL third-party" "$CHECK_OUT"
}

test_third_party_allows_cloudflare_beacon() {
local dir
dir=$(make_fixture)
write_good_page "$dir"
python3 - "$dir/index.html" <<'PY'
import sys

path = sys.argv[1]
text = open(path, encoding="utf-8").read()
script = "<script type='module' src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{\"token\": \"x\"}'></script>"
open(path, "w", encoding="utf-8").write(text.replace("</head>", script + "\n</head>"))
PY
run_checker "$dir"
assert_eq "0" "$CHECK_RC" "the Cloudflare Web Analytics beacon must pass: $CHECK_OUT"
assert_not_contains "FAIL third-party" "$CHECK_OUT"
}

test_third_party_still_flags_third_party_analytics() {
# Only the self-hosted first-party ingest (pulse.tailroute.app, same
# registrable domain) is allowed; the SaaS host is third-party. The
# ingest must never be CDN-proxied instead: a proxy challenges
# cross-origin event POSTs and pageviews drop silently.
# Only the approved analytics hosts (see ANALYTICS_HOSTS:
# pulse.tailroute.app and static.cloudflareinsights.com) may load
# cross-origin; other analytics SaaS hosts are third-party. The
# Plausible ingest must never be CDN-proxied instead: a proxy
# challenges cross-origin event POSTs and pageviews drop silently.
local dir
dir=$(make_fixture)
write_good_page "$dir"
Expand Down
Loading