Privacy Policy
Effective: 30 August 2026. Two changes since the last version: signing in is now Google-only (the emailed-code route and the email provider behind it are gone), and a verified address is now stored, encrypted, rather than only hashed.
The short version
Your conversations never leave your device. No chat text, no titles, no prompts and no exports are ever sent to us or to anyone else. That is the claim this product is built on, and it is the one you can verify by reading the source.
Tvara does run one server — a licence issuer. It exists to decide whether a licence is real, how many devices are using it, and, once you sign in, which account it belongs to. It never sees a conversation. What it does see and store is listed below, in full.
Where the extension connects, and why
Three places. There is no fourth.
- The AI sites you are already signed into — ChatGPT, Claude, Gemini, Perplexity, DeepSeek, Grok. It makes the same authenticated requests their own pages make, using the session cookie your browser already holds, to read your own conversation history and (while Allowance tracking is on) your own remaining plan allowance. That data is written to local extension storage on your machine. It is not sent anywhere.
- Our payment provider's licence API (Dodo Payments, merchant of record) — when you activate or release a device. It receives your licence key and a coarse device label such as “Chrome · macOS”.
- Our licence issuer (
tvara.tharuntejandhe.workers.dev, a Cloudflare Worker) — described in the next section. - Google's own sign-in page — when you press “Continue with Google” to sign in. Described under “Signing in” below.
What our licence issuer receives and stores
It is contacted when you start the free trial, when you activate Pro, when you view or remove a device, and on a routine re-check. The check that matters runs before a Pro action, whenever the last one was over fifteen minutes ago — that is what lets a cancelled or refunded licence stop working promptly rather than weeks later. A background alarm runs twice a day as well, but only contacts the issuer while the signed 30-day token is inside its final 10 days. Starting the free trial contacts it too — an earlier version of this policy said the free tier never did, which was not correct.
Each request carries: your licence key (Pro only), your device's public key, the activation receipt id from the payment provider, a random one-time number, a timestamp, and a signature. As with any web request, our server also sees your IP address.
It stores, per licence:
- A hash of your licence key — the key itself is never written to disk by us. Retained up to 400 days after last use.
- A device fingerprint for each active device (a hash of that device's public key) with the time it was last seen, so the five-device limit can be enforced and so you can remove a device. Up to 400 days.
- Your trial start date, against your device fingerprint, so reinstalling does not hand out a second free week. Up to 400 days.
- A hash of your IP address, to notice one licence key being used from an implausible number of places. Not the address itself, and deleted after 30 days. It is used to flag a licence for a human to look at; it never automatically blocks anyone.
- Short-lived counters for rate limiting and to stop a request being replayed. Minutes to a couple of hours.
- A sharing flag, and only past a threshold: if one licence key is seen from more than twelve distinct IP hashes inside a window, the issuer records a count and a timestamp against that licence for 90 days so a person can look at it. It is evidence for review, never an automatic block.
What it handles but does not store: your email address as the payment provider knows it. The issuer asks Dodo Payments for it at the moment of a check and places it inside the signed token your own browser holds, so the extension can show you which account a licence belongs to. That copy is not written to our storage. The address you sign in with is a separate thing and is stored; see the next section. We do not use either for marketing, and there is no mailing list.
What it never receives: conversation text, chat titles, prompts, URLs you visit, cookies, or anything read from an AI site. There is no analytics service, no tracking pixel, no advertising identifier, and no third-party SDK anywhere in the extension.
Signing in
A device slot alone does not survive a reinstall or a move to another browser. Signing in lets your trial and your purchase follow you instead, which is why it is asked for before a free trial or a purchase. Browsing with the free features needs no account at all.
Continue with Google is the only way to sign in. It uses the browser's built-in identity API to open Google's own sign-in page and asks for openid email and nothing else — no profile, no contacts, no offline access, no ability to read anything in your Google account. Google returns an identity token straight to your browser, in the page fragment, which never reaches a server on its own; the extension then forwards that token to our licence issuer, which checks Google's published signing keys before believing a word of it. Sign-in always asks which account to use rather than silently reusing the one the browser is already signed into.
An earlier version of Tvara could also verify an address by emailing a six-digit code, which meant handing that address to a transactional email provider. That route and that provider are both gone. No third party other than Google is involved in signing in, and your address is no longer sent anywhere to be delivered to you.
What the issuer keeps once you have signed in:
- An identity fingerprint — a salted hash of your canonicalised address. This, not the address, is what every other record is keyed on: your trial start date, and (if you buy Pro) the link to your licence.
- The address itself, encrypted. It is sealed with AES-GCM under a key that exists only in our server's secret store, kept in its own table, and read by no part of the service — no request returns it and none of our code sends it anywhere. It is held so that we can tell you what we have about you, delete it on request, and answer a support question about which account owns a licence. A copy of the database on its own is ciphertext.
Both are kept for up to 400 days of inactivity, and for as long as a live licence is attached to them, so a purchase stays restorable. Pressing Restore my purchase asks the issuer whether the signed-in identity owns a licence. Use a different account forgets the sign-in on that install only — it does not delete what the issuer holds; ask us for that, see “Access and erasure” below.
Firefox. Firefox gives every installation a different internal address, which Google will not accept as a sign-in destination, so Continue with Google cannot work there. Free features work normally on Firefox; the trial and Pro cannot be started on it.
Your device key
On first use the extension generates a cryptographic key pair inside your browser and stores it there. The private half is created as non-extractable: the browser will not export it — not to the page, not to us, not to you. It is used only to prove to our licence issuer that a request came from this device, so that a device slot cannot be claimed by someone who merely has your key. Only the public half is ever sent.
Scripts that run inside the AI pages
- ChatGPT message times — a read-only script reads each message's timestamp from the app's own state so real send times can be shown. It makes no network request and changes nothing on the page.
- The allowance reader — while Allowance tracking is on, this observes the rate-limit information the AI sites' own responses already carry, so the figure agrees with the site instead of being an estimate. It is strictly passive: requests are never altered, blocked, delayed or replayed. It reads rate-limit response headers, and opens a response body only when the URL's own path says the response is about limits — never chat traffic, never a stream. What crosses from the page into the extension is the rate-limit response headers, the URL path (never the query string), and — for those limit responses only — the parsed JSON, because the number has to be found inside it. That JSON is read in memory and discarded; what is written to disk is a redacted sample in which every string longer than 40 characters is replaced by its length, so a wrong reading stays diagnosable without keeping any prose. No part of it is transmitted anywhere. This is the only place the extension hooks
fetch/XHR, it is switchable off in the popup, and with it off the hooks disable themselves.
What the extension keeps on your device
- Your archive — the conversations it has read, in the browser's own storage on your machine. The extension declares
unlimitedStorageso a long history is not silently truncated. None of it is uploaded, and clearing it from the extension deletes it at once. - Backup files — with automatic backup on, encrypted
.lctbackupfiles are written toDownloads/Tvara/on your own disk and nowhere else. The passphrase is never stored, never synced, and cannot be recovered by us. - Allowance diagnostics — the redacted response sample described above, kept so a wrong allowance figure can be explained rather than guessed at.
- An account tag — when you use more than one account on the same provider, the extension has to keep those archives apart. On Gemini it reads the signed-in address from Google's own account-switcher label, or the seat number in the URL, and stores only a salted hash of it. The address itself is not stored and never leaves your machine.
- Temporary chats — off by default, and switched on per your choice in the popup. A temporary or incognito-mode chat never gets a conversation id from the provider, so when this is on the extension derives one itself from a signal in the page and a hash of the opening message, then archives the chat the same way as any other — locally, nowhere else. A badge is shown on the page for as long as one is being archived, so it is never silent. Turning this off does not delete chats already archived; delete them from the extension like any other entry.
The permissions it asks for, and what each is for
storage,unlimitedStorage— hold your archive and settings locally.downloads— write exports and scheduled encrypted backups into your Downloads folder.notifications— two local notices, and no others: a chat you had archived was deleted at the provider, and an allowance is running low. Both are raised on your machine; no notification service is involved.alarms— run the scheduled backup and the licence re-check on a timer.identity— used only for “Continue with Google”: opening Google's sign-in page and reading back the redirect. Used for nothing else, and untouched until you press that button.- Host access to the AI sites listed above, and to
tvara-app.github.ioso the purchase page can hand a licence key back to the extension. - Not requested:
cookies,tabs,history,bookmarks,webRequest,scripting, or access to any site not named above. You can check this againstmanifest.jsonin the packaged extension.
Your data, your call
- Your archive is yours. Delete it at any time from the extension — that removes it from your device immediately, and we never held a copy to begin with.
- Exporting your archive never requires a licence. If your Pro licence lapses, is refunded, or you remove the device, you can still export everything the extension has archived. We will not hold your own conversations behind a paywall.
- Access and erasure. Email tvara.exten@gmail.com from your purchase address and we will tell you exactly what our licence issuer holds for your licence or your signed-in account — including the encrypted copy of your address — or delete it, within 30 days. Deleting either releases every device slot and cannot be undone. For payment records, the merchant of record is the controller — we will point you to them.
- This website is static HTML with no cookies, no analytics and no third-party scripts.
Verifying any of this
The extension ships as unminified, unobfuscated JavaScript, and the licence issuer's source is in the repository as server/entitlement-worker.js. Everything above is a statement about code you can read. If you find a place where the code and this page disagree, that is a bug — please report it and we will fix whichever one is wrong.
Questions: tvara.exten@gmail.com