Privacy Policy — Bookmarks Manager

Version: 1.0 · Effective date: 2026-09-28 · Hosted URL: https://nguyensitrung.github.io/BookmarksManager/privacy/

Who publishes this extension

Bookmarks Manager is published by NguyenSiTrung.

Contact: trungnsai95@gmail.com — monitored; privacy questions and deletion requests are answered there. Issues may also be filed at github.com/NguyenSiTrung/BookmarksManager/issues.

Summary

The developer does not collect, receive, or store any of your data. There are no accounts, no analytics, no telemetry, no crash reporting, no remote code, and no developer-operated servers.

Bookmark management works fully offline: there is no account, no sign-in, and no API key required. Everything stays in your browser unless you explicitly start a feature that sends data to a provider you chose. The optional AI provider flow — disclosure, consent, host permission, encrypted key storage, revocation, the Test connection, and the bookmark decisions flow — is off by default and is the only code path that can ever make a network request. At a fresh install the extension sends zero requests.

How the extension handles your bookmarks

Data stored locally (never sent to the developer)

Data sent to third parties — only at your direction

The only features that can send data are the optional Test connection, bookmark decisions, and the separately consented LLM features below. All are off until you configure them, and send only inside actions you start.

The synthetic Test connection (jev_test)

Bookmark decisions (jev_decisions)

Beyond the synthetic test, an optional bookmark-data flow can send bookmark metadata to the same provider for AI decisions (categorize, tag, folder pre-select, near-duplicates, misfiled scan, and search re-rank). It is a separate consent scope, jev_decisions, granted per provider, and it is off until you enable it.

When a cleaned URL is sent, it includes the remaining path after removing matrix parameters and replacing opaque segments (32 or more ASCII letters, digits, underscores, or hyphens) with _redacted_; query strings, fragments, and embedded usernames/passwords are removed. Encoded equivalents are also removed or redacted. This applies to bookmark decisions, explanations, second opinions, and both summary hops. Ordinary short paths remain; native bookmark URLs and local summary resource matching are unchanged.

Optional LLM provider features (llm_test, llm_explain, llm_escalate, llm_restructure, llm_summary, jev_summary_verify)

You may optionally configure one OpenAI-compatible LLM provider — an OpenAI or OpenRouter preset, or a custom HTTPS endpoint (HTTP only for a loopback service such as http://localhost:11434). A custom HTTPS origin is granted through the manifest's https://*/* optional host pattern: the broad optional host pattern is capability only — it grants the exact configured origin at runtime from your direct Enable click, never default access, and it can be revoked like any other host grant. A custom endpoint whose host is not a public address — a private IP range, an intranet name, or a loopback — shows a warning in Options before you enable it; enabling it is still your choice. Each feature below is a separate consent scope, granted per provider origin, and every request is re-checked against the exact configured origin, the saved consent, the host permission, and the closed request schema before it can leave the device. Your stored provider credential goes in the request's authentication header only — never inside the message body. Notes, the full page DOM, and credentials in the message body are never sent under any scope. Text a provider returns is treated as untrusted: URLs and markdown syntax are stripped before a summary or a proposed folder name is displayed or saved.

Both summary hops remove the URL's query string, fragment, and embedded username/password, strip path matrix parameters, and replace opaque path segments with _redacted_ before sending the remaining path. The original URL stays local for admission and matching. Notes, the extraction's byline, and the full page DOM are not included in either summary payload; only a Jev-supported summary is saved, not the excerpt.

Opening the Summarize dialog only reads the configured recipients and current consent status. It displays both exact origins, their field lists, and the consent version before Agree and summarize authorizes extraction and sending. Closing it grants nothing. The worker rechecks the displayed recipients/version against current configuration before granting consent; a changed provider requires reviewing again. Unknown-cost confirmation is a separate choice that retains the accepted recipient/version binding.

Each grant is tied to the exact configured origin (including the port for a loopback endpoint). Revoking the provider deletes every consent scope at its origin, removes the host permission, and deletes the stored credential. LLM spending is metered: when reliable per-token pricing is configured, each request first reserves an estimated cost; when it is not, requests run only inside the unknown-cost mode you chose. Nothing is sent on install, on a timer, or in the background.

The consent is versioned — consentVersion, currently 4 — so a change to the sent fields or recipients re-shows the disclosure before the next request. Older grants remain stored as stale records and authorize no request until the user reaccepts for that exact scope and origin; reacquiring one origin does not refresh another origin's grant. Revoking a provider deletes every consent grant for its origin — jev_test, jev_decisions, and every llm_* scope — removes its host permission, and offers to delete its key.

Requests to a provider are governed by that provider's own privacy policy and retention terms. The in-product disclosure links to typesafe.ai/legal/privacy-policy (TypeSafe) and openrouter.ai/privacy (OpenRouter); both must be verified against the providers' real policies before submission.

API keys

Your API key is yours. It is transmitted only to the provider that issued it, inside the Authorization: Bearer header, over HTTPS, with cookies and credentials omitted and redirects refused. It is encrypted at rest on your device (AES-GCM via WebCrypto; the encryption key is stored non-extractably in IndexedDB) and is never logged, exported, or shown in full — only a masked last-four hint (or the **** placeholder for short keys) appears in Options as a reminder.

Your choices and deletion

Security

All remote requests must use HTTPS, pass through a single audited network module, require a matching stored consent record at the current consent version and a live Chrome host permission, and stay limited to the provider origins listed above. The consent gate, encrypted key storage, the synthetic Test connection, and the bookmark-data decision flow are all in place — the build makes no remote requests except the synthetic test request on an explicit Test connection click and a jev_decisions request on a user-started save, Analyze, library scan, or Ask search, and the separately consented LLM features above (including both Summarize hops). None send until you configure a provider and start the corresponding action.

Limited Use statement

The use of information received from Google APIs will adhere to the Chrome Web Store User Data Policy, including the Limited Use requirements.

In plain terms: this extension uses any data it handles only to provide its single user-facing purpose (managing your bookmarks, with an optional provider connection you control). It does not sell your data, does not use it for advertising, does not use it to determine creditworthiness, and does not let humans read it. Only the disclosed fields leave the device for the optional provider features you start; native bookmark management remains local.

Children

This extension is not directed at children under 13.

Changes to this policy

Data-handling changes will be disclosed in the extension and will require renewed consent before the changed feature can send data. The policy version and effective date above are updated with each release.