Skip to content

Commit c3fb274

Browse files
authored
Draft Reader extension privacy page (#57)
* Draft Reader extension privacy page for publisher review * Ground Reader policy in Connect service and retention evidence * Record publisher contact confirmation and backup gate status * State confirmed Reader data-use commitments * Prepare policy handoff after publisher confirmation
1 parent 3c05f27 commit c3fb274

3 files changed

Lines changed: 213 additions & 1 deletion

File tree

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Reader extension privacy page — evidence and Store handoff
2+
3+
URL: `https://mdbase.dev/apps/reader/extension/privacy/`.
4+
5+
This page describes the 0.2.0 candidate uploaded from `mdbase-reader` commit `adc9d27f86d0040320f5f26f2d96c176c33aa92b`; if the submitted ZIP changes, re-audit it. The source audit, data-category mapping and candidate hash are in `mdbase-reader/docs/chrome-web-store/` on `fix/extension-store-hardening`.
6+
7+
## Repository findings used in the draft
8+
9+
- **Operator/contact:** The owner confirmed Callum Alpass as operator and `callum@mdbase.dev` as the public privacy-request address. `mdbase-cloud-ops/docs/account-and-service-inventory.md` also lists it as the Google OAuth support and product email. Test delivery before publication.
10+
- **Topology:** `mdbase-cloud-ops/docs/render-production.md` describes Render Connect, hosted provider, relay broker and separate PostgreSQL databases. The hosted provider handles records/files; the control plane does not persist record payloads. `docs/r2-storage.md` describes Cloudflare R2 file objects and deferred deletion after retained references are gone. The existing `/privacy/` page already distinguishes local connector data, encrypted relay payloads and provider-readable hosted data.
11+
- **Backups/logs:** `mdbase-cloud-ops/docs/disaster-recovery.md` and `.github/workflows/backups.yml` document Render PITR and encrypted logical exports retained for 90 days as GitHub artifacts on the database-only path. A complete AWS S3 archive is designed but gated by `RECOVERY_ARCHIVE_ENABLED`; `gh variable get RECOVERY_ARCHIVE_ENABLED --repo mdbase-dev/mdbase-cloud-ops` reported the variable absent on 2026-09-27, so the scheduled workflow chooses database-only unless changed. This does not prove every historical backup is gone. `docs/render-production.md` and `docs/observability.md` describe privacy-bounded Render application logs, but do not establish a public, exact log-retention interval. Do not promise instant erasure from backups.
12+
- **Usage/retention:** `mdbase-connect/docs/usage-report.md` describes aggregate operator reports from existing account/grant/token/usage rows and daily deletion of expired authorization/protocol-usage rows no longer needed after 395 days. This does not set a 395-day retention period for all account, audit, provider or backup data.
13+
- **Revocation/deletion:** `mdbase-connect/apps/editor/src/ConnectApp.tsx` has application-grant revocation controls; local/hosted authority confirmation may be pending. `apps/editor/src/AccountManagement.tsx` conditionally disables account deletion when the service reports it unavailable. The ops desired `render.yaml` enables it, but a live check is required before claiming it is currently available. Browser-local extension reset is not server-side revocation. Hosted record/file deletion can leave retained versions or backups.
14+
- **Email:** `mdbase-cloud-ops/docs/account-and-service-inventory.md` identifies Resend for account-related delivery. DOI lookups and original-site PDF requests are documented in the extension-store-hardening audit, not Connect.
15+
16+
## Store handoff and follow-up
17+
18+
- The owner confirmed `callum@mdbase.dev` as the public contact and the page uses 27 September 2026 as its effective date. Test actual delivery and define the operational handling path for privacy/deletion requests.
19+
- The page does not promise an exact Render log/PITR retention interval or instant erasure. The repositories provide desired state and implementation but cannot prove all live provider settings or data already retained there. Check live retention and account-deletion availability as an operational follow-up. Recheck the GitHub recovery variable before making a future archive claim.
20+
- On 2026-09-27 the publisher confirmed the three Web Store data-use commitments: no sale/impermissible transfer apart from approved uses, no unrelated use or transfer, and no creditworthiness/lending use or transfer. The policy now states those commitments. The exact dashboard category mapping still needs reconciliation with the final ZIP and service behaviour before certification. Chrome Limited Use is a separate policy review, not automatically proven by these three statements.
21+
- Reconcile Web Store data categories with the actual submitted build and backend: website content, visited URLs, authorization credentials, account identifiers, IP/location and activity/usage reporting. Recheck optional HTTPS permission and DOI traffic before claiming they stop or omit data.
22+
- Check the published page against the production ZIP and the other Reader/Connect pages. The site's in-progress Reader documentation currently exists as untracked work in the canonical `mdbase.dev` checkout, not on this branch; coordinate separately rather than copying or overwriting it.
23+
- After deployment, fetch the public URL without authentication and verify its content, canonical URL and links before entering it in the Chrome Web Store. Save the draft, re-open “Why can't I submit?”, and submit only with explicit publisher approval.
24+
25+
## Validation
26+
27+
`pnpm check` and `pnpm build` pass. `pnpm check:links` reports an unrelated existing `/sdk/` → `/spec/#section-14` fragment problem on `origin/main`; new policy links and inline-code checks pass. The uploaded 0.2.0 ZIP still matches the recorded SHA-256 `79565e2b93c7b8b1d294cc9a83aa4dcb97f1ce2681d8281d428a282f2cf080e3`. On 2026-09-27, extension tests (84) and web-capture tests (27) passed. Source inspection confirms optional HTTPS access is requested from the setting and removed on disable, while navigation lookups are gated by the setting and permission; DOI fetch uses `credentials: "omit"` and sends the encoded DOI through `doi.org`. These checks do not replace a live network trace of the uploaded ZIP.
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
import BaseLayout from "../../../../../layouts/BaseLayout.astro";
3+
---
4+
5+
<BaseLayout
6+
title="mdbase Reader extension privacy"
7+
description="How the mdbase Reader browser extension handles page content, annotations, browsing addresses, and Connect authorization."
8+
>
9+
<article class="legal">
10+
<header>
11+
<h1>mdbase Reader browser extension privacy</h1>
12+
<p>
13+
This page covers the mdbase Reader browser extension, operated by
14+
Callum Alpass. The <a href="/privacy/">mdbase website and Connect privacy page</a>
15+
covers the related website and Connect service.
16+
</p>
17+
</header>
18+
19+
<h2>What the extension does</h2>
20+
<p>
21+
Reader lets you save supported web articles and PDFs, add highlights and
22+
notes, and revisit them in a collection you authorize through mdbase
23+
Connect. The extension is not a standalone storage service.
24+
</p>
25+
26+
<h2>Pages and information you choose to save</h2>
27+
<p>
28+
When you open Reader on a supported page, it reads the page address,
29+
title, content, available citation metadata and selected text to prepare
30+
a capture. Saving is a separate action. When you save, Reader transfers
31+
the source content and any tags, notes, comments or highlights you enter
32+
through Connect to your selected collection.
33+
</p>
34+
<p>
35+
For articles, new captures include a readable copy and a minimized
36+
text-and-structure HTML archive. The archive leaves out scripts, forms,
37+
embedded application state, arbitrary attributes and resource or link
38+
addresses from the document markup. Explicitly hidden elements are
39+
removed. This is not anonymization: visible text, titles, citation
40+
metadata and the separately saved source address, including any query
41+
parameters, may still contain private information. Existing captures are
42+
not rewritten. Only save pages you intend to keep in that collection.
43+
</p>
44+
<p>
45+
For supported PDFs, Reader downloads the document for saving. Where
46+
Chrome permits, the download uses your existing access to the original
47+
website. The extension does not copy the website's login cookies into
48+
the saved PDF as part of that operation.
49+
</p>
50+
51+
<h2>Citation lookups</h2>
52+
<p>
53+
If a DOI is available, citation preparation may send that DOI to{" "}
54+
<code>doi.org</code> and the registry it redirects to, such as Crossref
55+
or DataCite. This can happen before you save. The lookup does not
56+
intentionally send your notes, highlights or full article content.
57+
Those services also receive ordinary network information such as your IP
58+
address. Extension DOI requests omit cookies.
59+
</p>
60+
61+
<h2>Optional saved-page recognition</h2>
62+
<p>
63+
“Mark pages I've saved and show my highlights on them” is optional. If
64+
enabled, Chrome requests access to HTTPS websites. Reader then sends the
65+
addresses of HTTPS pages you visit, including pages you have not saved,
66+
through your configured Connect route to query your selected collection.
67+
It retrieves matching saved highlights and may read page text to display
68+
them. This is not merely an on-device browser comparison. Turning the
69+
feature off stops these background lookups and requests removal of the
70+
optional website permission.
71+
</p>
72+
73+
<h2>Connection and local browser data</h2>
74+
<p>
75+
The extension keeps Connect authorization state, the selected collection,
76+
preferences and interrupted-write recovery information in Chrome's
77+
extension-local storage. Signing keys and application identity are held
78+
in the extension's IndexedDB databases. Recovery data can include
79+
identifiers, addresses and pending changes. Draft text and selected
80+
passages are kept in extension session storage and cleaned up when their
81+
tab closes. This implementation does not use Chrome's synchronized
82+
storage for those drafts.
83+
</p>
84+
<p>
85+
Connect grants are sensitive credentials used to access only collections
86+
you authorize. Extension API requests do not use ambient Connect portal
87+
cookies. The separate Connect approval website handles its own sign-in.
88+
</p>
89+
90+
<h2>Where data goes</h2>
91+
<p>
92+
The production extension contacts <code>connect.mdbase.dev</code> for
93+
authorization and collection operations. Depending on your collection,
94+
records and files are handled by a hosted collection service or your own
95+
connector, with a cloud relay where applicable. Not all traffic remains
96+
on your computer. The <a href="/privacy/">Connect privacy page</a>
97+
describes account, routing and hosted-collection handling.
98+
</p>
99+
<p>
100+
For a collection served from your computer, you may separately allow
101+
direct access to the connector on your own device. This is optional;
102+
Chrome controls the localhost and local-network permissions. Websites
103+
you capture and DOI registries have their own privacy practices.
104+
</p>
105+
106+
<h2>Purposes, service providers and sharing</h2>
107+
<p>
108+
Reader uses this information to prepare and save sources, look up citation
109+
metadata, store annotations, access an authorized collection, recover
110+
interrupted writes and, if enabled, recognize saved pages. Connect
111+
processes account and grant details, routing metadata and bounded usage
112+
counts needed to operate the service; its operator report uses aggregate
113+
counts rather than returning individual records or page contents.
114+
</p>
115+
<p>
116+
Production Connect and its hosted provider run on Render with managed
117+
PostgreSQL. Hosted files are stored as opaque objects in Cloudflare R2;
118+
the hosted provider handles authorized record and file operations.
119+
Render provides database recovery, and encrypted logical database
120+
backup artifacts are retained through GitHub Actions. Account email may
121+
be delivered through Resend. DOI registries receive a DOI when
122+
a lookup is made, and the original website serves content or a PDF when
123+
you choose to capture it. These providers may process the network and
124+
operational information necessary to provide those services. The
125+
extension does not contain an advertising or third-party analytics SDK.
126+
We do not sell user data, use or transfer it for purposes unrelated to
127+
Reader's stated function, or use or transfer it to determine
128+
creditworthiness or for lending. Transfers to service providers and DOI
129+
registries are limited to the functions described above.
130+
</p>
131+
132+
<h2>Retention and controls</h2>
133+
<ul>
134+
<li>
135+
Saved sources, files and annotations remain in the selected collection
136+
until removed using the collection's controls. Removing the extension
137+
does not delete them.
138+
</li>
139+
<li>
140+
Session drafts are temporary. Local preferences, authorization and
141+
recovery state can persist across browser restarts.
142+
</li>
143+
<li>
144+
Turn off saved-page recognition in extension Settings to stop
145+
background address lookups and request removal of website access.
146+
</li>
147+
<li>
148+
Settings → Disconnect this browser → Disconnect and clear local data
149+
removes extension-local state, session drafts and IndexedDB credentials
150+
after confirmation. It also requests removal of optional website and
151+
local-connector permissions. Finish pending saves first: a write already
152+
sent may still complete, and recovery information is discarded.
153+
</li>
154+
<li>
155+
Clearing this browser does not revoke server-side grants or delete
156+
collection content, and does not affect other browsers. Highlights
157+
already drawn on an open page may remain until it is reloaded. Revoke
158+
Reader's application access in Connect and remove records/files in
159+
your collection using its controls. Revocation for a connector-backed
160+
collection can remain pending until that connector confirms it.
161+
</li>
162+
</ul>
163+
<p>
164+
Connect deletes expired authorization and usage rows that are no longer
165+
needed, generally after about 13 months. Other account, grant and audit
166+
information can be retained while needed for service, security or legal
167+
purposes. Hosted file deletion may first leave retained versions and
168+
backups that are removed through maintenance or backup expiry; deletion
169+
from all recovery copies is not immediate. The provider and Render may
170+
retain operational logs. The <a href="/account-deletion/">Connect account-deletion page</a>
171+
explains account-level controls and exceptions; local collection files
172+
on your own computers are not removed by deleting an account.
173+
</p>
174+
175+
<h2>Contact and changes</h2>
176+
<p>
177+
For privacy questions or requests, contact
178+
<a href="mailto:callum@mdbase.dev">Callum Alpass at callum@mdbase.dev</a>.
179+
Changes to this policy will be posted at this address with an updated
180+
effective date.
181+
</p>
182+
<p>Effective date: 27 September 2026.</p>
183+
</article>
184+
</BaseLayout>

‎src/pages/privacy/index.astro‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ import BaseLayout from "../../layouts/BaseLayout.astro";
5757
<p>
5858
Applications connected through mdbase receive data under the grants users
5959
approve. Each application provider is independently responsible for its
60-
own handling of authorized data.
60+
own handling of authorized data. For the mdbase Reader browser extension,
61+
see its <a href="/apps/reader/extension/privacy/">extension privacy page</a>.
6162
</p>
6263
<h2>Contact</h2>
6364
<p>

0 commit comments

Comments
 (0)