Legal

Privacy Policy

Effective date: October 15, 2026

Overview

Cover Me (“we”, “our”, or “us”) is an open-source Chrome extension that reads a job posting, tailors your resume to it, and writes a matching cover letter, using an AI model. This Privacy Policy explains what information we collect, how we use it, and your rights regarding that data.

Cover Me operates in two distinct modes with fundamentally different data handling characteristics:

  • →BYOK (Bring Your Own Key) — free, unlimited. You supply your own Claude or OpenAI API key. No account is required. Your resume, API key and history are stored on your device, and only the API key is encrypted. Your resume goes only to the AI provider whose key you use. From version 1.3.0, once you agree, the job page you use the extension on is also sent to our server so it can read the posting (see Job posting data below).
  • →Hosted (Free & Pro). You create an account. Your resume is encrypted and stored on our backend. Our server sends it to Anthropic, with our API key, to read it and to write your cover letters and tailored resumes. Pro subscribers are billed through Stripe. From version 1.3.0, once you agree, the job page is also sent to our server to read the posting, as in BYOK.

Where this policy applies differently by mode, it is clearly noted.

Information We Collect

Information you provide directly

  • →Resume text. When you upload a PDF or DOCX file, text is extracted client-side on your device. The raw binary file is never stored or transmitted; in Hosted mode its file name is stored, unencrypted, with your resume. In BYOK mode, the extracted text is stored only in your browser's local storage. In Hosted mode, the extracted text is transmitted to our server over HTTPS and stored in an encrypted database, and a copy is kept in local storage in the browser you use; from version 1.3.0, signing in on another browser downloads it, so you don't upload it again. In Hosted mode, when you upload a new resume, our server sends it to Anthropic right away to read its structure, so tailoring can start at once (or on your first tailor, if it hasn't been read yet).
  • →Account credentials (Hosted mode only). Your email address and password are used to create and authenticate your account, managed by Supabase Auth. Passwords are hashed using bcrypt and are never stored in plaintext. If you choose Continue with Google instead, there is no password: Google confirms who you are, and we receive your email address, name, profile picture link and Google account ID (see Third-Party Services below). Versions before 1.3.0 offered “Remember me”, which saved your password on your device, encrypted with AES-256-GCM, to pre-fill the sign-in form. Version 1.3.0 removes that feature and deletes any saved password when it updates.
  • →API keys (BYOK mode only). Your Claude or OpenAI API key is encrypted on your device using AES-256-GCM via the Web Crypto API before being written to local storage. It is decrypted only at the moment of an API call and immediately discarded from memory. It is never transmitted to our servers, logged, or included in error messages.
  • →Facts you add. Anything you type to give the AI more context, such as a referrer's name or experience missing from your resume, is saved in your browser and sent with each generation request: to our server in Hosted mode, or to your AI provider with your own key.

Information collected automatically

  • →Job posting data. From version 1.3.0, when you click Generate or Tailor Resume on a job posting, the extension copies the page you are looking at and sends it, with the full address of the page (and of each frame copied), including any query string, to our server over HTTPS, in every mode including BYOK, once you agree. The extension asks when you open it until you choose, and reads postings on your device only until you agree. You can turn this on or off at any time in the extension's Settings. The server reads the job title, company name, and job description from it and sends those back; the page itself is discarded as soon as it is read and is never logged or stored. The copy covers the page and any frames in it from the same site or from the six job-board services listed below. Scripts (except the posting's structured data), form fields, images and the data sites embed in them are removed in your browser before anything is sent, and so is LinkedIn's messaging panel where the extension recognises it. The rest of the page is sent as is: its text, including parts not on screen, its link addresses, short attribute values, and class and style attributes at any length, which on sites you are signed in to can include your name or a link to your profile. If our server can't be reached, the extension reads the posting on your device instead. The job details are then used only to generate your cover letter or tailored resume and, on Pro, to label your saved applications.
  • →Application history. Generated cover letters and tailored resumes are grouped by job application and saved locally in your browser storage (BYOK and Hosted Free modes) or also synced to our backend (Hosted Pro mode) for cross-device access. On our backend the letters and resumes are encrypted; the job title, company, posting address, dates, interview mark, ATS match score and missing keywords that go with them are not, so you can search and filter them.
  • →Authentication session tokens (Hosted mode only). A JWT access token and refresh token are stored in your browser's local storage to maintain your session. These tokens are transmitted to our backend with each generation request to authenticate you.
  • →Usage count (Hosted mode). We record the number of AI generations (cover letters and resume tailoring combined) per day per account to enforce the free allowance and Pro's fair-use limit. Apart from Supabase's short-lived request logs (see Third-Party Services), only the count is stored: no content of individual generations is recorded server-side for Free users.
  • →Rate-limit counter (all modes). To stop abuse of the posting reader, our server counts requests per IP address. It stores a keyed hash (HMAC) of the address, never the address itself. When it reads a newly uploaded resume, it also counts per account, keyed by a hash of your account ID. A counter not updated for two days is deleted at the next cleanup, which runs during later requests.
  • →Billing information (when you click Upgrade, and Pro subscribers). When you click Upgrade, we send Stripe your email address and Cover Me account ID to start checkout, and Stripe processes your payment. We store only your Stripe Customer ID and subscription status in our database. Full payment details (card numbers, CVV, etc.) are never transmitted to or stored by our servers.

Information we do NOT collect

  • →We do not track your browsing history. We receive a page's address only when you activate the extension on it.
  • →The extension contains no analytics or telemetry code. In BYOK mode the only thing it sends to Cover Me is the job page you activate it on, once you have agreed, so we can read the posting. Your resume and API key never reach us.
  • →In hosted mode our servers count how many letters and resumes you generate, to enforce the generation limits, and log errors. Logs never contain your resume, letters, or job descriptions.
  • →We do not use cookies for tracking or advertising.
  • →We do not collect any data from tabs other than the active job posting tab, and only when you explicitly activate the extension.
  • →We do not sell, rent, or trade your data to any third party.

How We Use Your Information

We use the information we collect exclusively to provide the Cover Me service:

  • →To read the job posting on the page you ask the extension to read.
  • →To protect the service from abuse, with rate limits.
  • →To tailor your resume to that posting and write a matching cover letter, using your resume and any facts you add.
  • →To authenticate you and maintain your session (Hosted mode).
  • →To enforce the generation limits: the free allowance and Pro's fair-use cap (Hosted mode).
  • →To sync your application history (cover letters and tailored resumes) across devices (Pro mode only).
  • →To process subscription billing through Stripe (Pro mode only).
  • →To respond to support requests you initiate by contacting us directly.
  • →To count, in aggregate, how many accounts sign up and use the service.

We do not use your data for advertising, profiling, training AI models, or any purpose beyond what is listed above.

Chrome Extension Permissions

The following section details every permission declared in Cover Me's manifest.json, why it is necessary, and exactly how it is used. No permission is requested beyond what is strictly required to deliver the extension's single stated purpose: helping you apply for a job by tailoring your resume to the posting and writing a matching cover letter.

Declared permissions

storage
Why it is needed: The extension must persist user data between browser sessions and popup opens/closes. Without storage access, settings, resume text, API keys, cover letter history, and auth session tokens would be lost every time the popup is closed.

Exactly how it is used:
  • User settings (AI provider, mode selection)
  • AES-256-GCM encrypted API key (BYOK mode)
  • Extracted resume text and parsed resume structure
  • Application history — cover letters and tailored resumes grouped by job
  • JWT session tokens (Hosted mode)
  • Facts you add for your letters, such as a referrer's name
  • Cached account tier to avoid redundant network requests
  • Transient in-flight generation state so results survive the popup closing mid-generation
  • The popup's last inputs and results, so they're still there when you reopen it
  • Your choice about sending job pages to our server to be read

chrome.storage.sync is deliberately never used to avoid any cloud synchronisation of sensitive data. All storage is local to your device.
activeTab
Why it is needed: The activeTab permission grants temporary host access to the tab the user is currently viewing. This is what allows chrome.scripting.executeScript to read the job posting in that tab. It is why Cover Me can work on job postings across thousands of sites without asking for access to all websites.

Exactly how it is used: When you click Generate or Tailor Resume, the service worker injects the job-posting reader from the extension's own package into the page you are viewing and reads the job title, company name, and description. From version 1.3.0, once you agree, it also sends the page's address and a stripped copy of the page to our server to read the posting (see Job posting data above). It reads no cookies, browsing history or other tabs.

Access is strictly user-initiated: Chrome grants this access when you click the Cover Me icon, and it ends when you leave the page or close the tab. The extension uses it only when you click Generate or Tailor Resume. It has no access to any other tab.
scripting
Why it is needed: From version 1.3.0, Cover Me runs no code on web pages until you ask. Its job-posting reader is injected only when you click Generate or Tailor Resume, using chrome.scripting.executeScript.

Exactly how it is used: On your click, the service worker injects the reader (a file inside the extension's own package, content.js) into the active tab. If that fails, it injects a smaller self-contained scraper function from the same bundle. No code is fetched from any remote source. Both read only DOM text and JSON-LD structured data to extract job title, company name, and description. From version 1.3.0, once you agree, the reader also returns the page's address and a copy of the page with scripts (except the posting's structured data), form fields, images and link query strings removed, which our server reads with the latest version of the reader. They do not write to the page, access cookies or localStorage, or persist anything.

Access is strictly user-initiated: Injection is gated by activeTab and only triggered when you click Generate or Tailor Resume. No scripts are injected in the background. Earlier versions loaded a small listener into every page that did nothing until you clicked Generate or Tailor Resume; Chrome shows those versions as able to read and change your data on all websites.
identity
Why it is needed: It lets you sign in with your Google account through Chrome's own sign-in window, using chrome.identity.launchWebAuthFlow.

Exactly how it is used: Only when you click Continue with Google, Chrome opens Google's sign-in page. After you approve, Supabase Auth receives the email address, name, profile picture link and Google account ID Google shares, and the extension receives a Cover Me session. The extension reads nothing else from your Google account or from Chrome's signed-in profile. The identity.email permission is not requested.

Job board host access

From version 1.3.0, Cover Me does not run on the websites you visit. It reads a page only when you click Generate or Tailor Resume, through the activeTab permission above. Six job-board domains are listed as host permissions so Cover Me can also read postings that a company's careers page embeds from those services. Together with the API domains below, Chrome shows this during installation as “Read and change your data on a number of websites.”

greenhouse.io, lever.co, myworkdayjobs.com, ashbyhq.com, bamboohr.com, workable.com⚠ Chrome shows: “Read and change your data on a number of websites”
Why it is needed: Many company careers pages show the job posting inside an embedded frame served by an applicant tracking system (Greenhouse, Lever, Workday, Ashby, BambooHR, or Workable). Chrome's activeTab permission only covers the page you are on, not frames from other sites inside it, so reading those embedded postings requires access to these six domains.

Exactly how it is used: Only when you click Generate or Tailor Resume, the job-posting reader is injected into the embedded posting frame and reads the job title, company name, and description. From version 1.3.0, nothing runs on these domains at any other time. The reader does not modify the page, inject any UI, monitor navigation, or transmit data independently.

What we do NOT do:
  • We do not read content from any tab other than the one you activate Generate on.
  • We do not monitor the pages you visit. We receive a page's address and content only when you click Generate or Tailor Resume on it.
  • We do not modify, inject into, or interact with web pages in any way beyond reading job posting data on explicit user request.
  • We do not track your browsing history or build any profile of the sites you visit.

Host permissions

Host permissions allow the extension to make network requests to specific domains. Cover Me requests the minimum set of domains required for each operating mode.

https://api.anthropic.com/*
Used by: BYOK mode only (when you select Claude as your AI provider and supply your own API key).

Why it is needed: In BYOK mode, the service worker calls the Anthropic Claude API directly from your browser using your own API key to write cover letters and tailor resumes, and the first time you tailor after uploading a resume, to read your resume's structure. The request contains your API key (in the Authorization header), the job description, and your resume text. No Cover Me server is involved — the request goes directly from your browser to Anthropic.

Not used in Hosted mode.
https://api.openai.com/*
Used by: BYOK mode only (when you select OpenAI as your AI provider and supply your own API key).

Why it is needed: Same rationale as the Anthropic permission above — direct browser-to-OpenAI API calls using your own key in BYOK mode.

Not used in Hosted mode.
https://ncnmkxzrygnwjiciyxqs.supabase.co/*
Used by: Every mode, to read job postings (from version 1.3.0). Everything else is Hosted mode only.

Why it is needed: The extension communicates with our Supabase backend for the following user-initiated purposes:
  • Reading the job posting (every mode) — sending the stripped copy of the page you click Generate or Tailor Resume on, and getting back the job title, company and description. The page is not stored.
  • Authentication — signing in, signing up, signing out, and refreshing JWT session tokens.
  • Account tier — fetching your plan after sign-in and when the Settings or History page opens.
  • Upgrade — getting a Stripe checkout page when you click an Upgrade button.
  • Cover letter & resume generation — sending job data and your session token to our backend Edge Functions, which retrieve your encrypted resume, call the Claude API with our key, and return the generated output.
  • Application history sync (Pro mode) — saving each new cover letter and tailored resume, uploading ones already in the extension when you agree, and fetching and deleting them on the History page.
  • Resume sync — after sign-in, uploading the resume already in the extension (versions before 1.3.0 always upload it; from 1.3.0 only if it's newer than the account's) or, from 1.3.0, downloading the account's copy; and uploading a new one when you add it. Uploads go to encrypted backend storage, and the server then reads the resume's structure with Anthropic.

Data Storage & Security

On-device storage (all modes)

  • →All on-device data is stored in chrome.storage.local — never in chrome.storage.sync, cookies, or localStorage — plus one “Not now” flag in chrome.storage.session, cleared when Chrome restarts.
  • →API keys (BYOK mode) are encrypted with AES-256-GCM through the Web Crypto API before being written to storage. The random key that encrypts them is stored alongside them, so this keeps the key from being read at a glance, not from someone with access to your browser profile. The plaintext key exists in memory only for the duration of a single API call.
  • →Resume text and cover letter history are stored unencrypted in your browser's local storage, in every mode. In Hosted mode the copies on our server are encrypted; the local copies stay on your device.

Server-side storage

  • →Resume text, and a parsed copy of its structure, are encrypted with AES-256-GCM before being stored in our Supabase Postgres database. The encryption key is derived from a server-side secret. Plaintext resume text is never persisted to disk.
  • →Cover letters and tailored resumes (Pro mode) are encrypted with AES-256-GCM before storage. The job title, company, posting address, dates, interview mark, ATS match score and missing keywords that go with them are stored unencrypted so you can search and filter them. Your resume's file name is stored unencrypted too.
  • →Rate-limit counters (all modes) hold only a keyed hash of an IP address, or a hash of your account ID when a new resume is read, and a counter not updated for two days is deleted at the next cleanup.
  • →All data in transit is protected by TLS 1.2 or higher (enforced by Supabase and Vercel).
  • →Database access is protected by Supabase Row-Level Security policies. Users can only access their own data rows.
  • →The Supabase service-role key (which bypasses RLS) is used only on our servers (the backend functions and the Stripe webhook) and is never exposed to clients.

Third-Party Services

Cover Me integrates with the following third-party services. Each service receives only the data necessary for its function.

When used: BYOK mode (Claude provider) and Hosted mode (our key)

Data received: Your resume text, the job posting data and any facts you add. In Hosted mode, also your resume on its own when you upload a new one (or on your first tailor, if it hasn't been read yet), and in BYOK mode the first time you tailor after uploading one, so its structure can be read. In BYOK mode, requests are made with your own API key and are subject to your agreement with Anthropic. In Hosted mode, requests are made with our key.

When used: BYOK mode only (OpenAI provider)

Data received: Your resume text, the job posting data and any facts you add, plus your resume on its own the first time you tailor after uploading it, to read its structure. Requests use your own API key and are subject to your agreement with OpenAI.

When used: Every mode (reading job postings, from version 1.3.0); everything else Hosted mode only

Data received: Copies of the job pages you ask us to read, which are processed and not stored, and rate-limit counters keyed by a hash of your IP address. In Hosted mode also: the job details, any facts you add and, when you regenerate, the previous tailored resume, sent with each generation request (not stored, except Pro history); email address, hashed password (email sign-in only), encrypted resume text, encrypted cover letters and tailored resumes with the unencrypted fields that go with them (Pro), your resume's file name, your Stripe customer ID, your Google name, picture link and account ID, session tokens, usage counts, and the account-keyed counter used when a new resume is read (see Information We Collect for each). Supabase Auth also records the IP address and browser of each signed-in session, kept with your account. Supabase hosts our backend functions, authentication system and database, and keeps standard request logs (IP address, browser, time, and the address requested, which can include a dashboard search) for a short period.

When used: If you choose "Continue with Google", and, before version 1.3.0, whenever the popup opens

Data received: Google confirms who you are and sends us your email address, name, profile picture link and Google account ID. We use the email address to create and sign in to your account, and show the picture as your account avatar in the extension and on the dashboard. Your browser loads the picture from Google's servers. The name is stored with your account but not used. We never see your Google password. Versions before 1.3.0 load the popup's fonts from Google Fonts, so Google receives your IP address and browser details each time the popup opens; from 1.3.0 the fonts ship inside the extension.

When used: When you click Upgrade, and for Pro subscribers

Data received: Your email address and Cover Me account ID when you start checkout, then the payment information you enter on Stripe's page (card details, billing address). Stripe processes all payments. Its notifications to our website include the checkout details it holds (such as your email, name and billing country or postal code); we keep only a customer ID and subscription status. We never see or store your raw card details.

When used: Anyone who visits cover-me.dev

Data received: Standard web server access logs (IP address, browser, requested URL) for every page of cover-me.dev. Vercel also runs the website's server code: for anyone signed in to the dashboard it reads your email, profile picture link, sign-up date, plan and usage from our backend to build the page; for Pro users it passes your saved applications (job details, cover letters and tailored resumes) from our backend to your browser; and it receives Stripe's billing notifications (your customer ID, subscription status and the checkout details Stripe holds). It stores none of these.

When used: Visitors to cover-me.dev (the website, not the extension)

Data received: Error reports and page-load timing from the website: the error, page URL, browser version, and your user ID if you are signed in. Form contents, cookies, and email addresses are removed before sending.

Data Retention

  • →BYOK mode: Your resume, API key and history stay on your device, and we hold no copy of them. You can delete them at any time by removing the extension or clearing extension storage in Chrome settings. The only BYOK data on our side are the rate-limit counters and Supabase's request logs described above.
  • →Hosted account data: Your account, resume, and application history (cover letters and tailored resumes) are retained for as long as your account is active. You may request deletion at any time by contacting us at support@cover-me.dev. We will permanently delete all your data within 30 days of a verified deletion request.
  • →Usage count records: Kept for as long as your account exists, because the free allowance counts generations over the life of the account. They are deleted with your account.
  • →Rate-limit counters: A counter not updated for two days is deleted at the next cleanup, which runs during later requests.
  • →Stripe billing records: Stripe retains transaction records as required by financial regulations. We cannot delete data held directly by Stripe.

Your Rights

Depending on your jurisdiction, you may have the following rights regarding your personal data:

  • →Access: Request a copy of all data we hold about you.
  • →Correction: Request correction of inaccurate data.
  • →Deletion: Request permanent deletion of your account and all associated data.
  • →Portability: Request your data in a machine-readable format.
  • →Objection: Object to processing of your data.
  • →Restriction: Request restriction of processing while a dispute is resolved.

To exercise any of these rights, email support@cover-me.dev. We will respond within 30 days. We may need to verify your identity before processing a request.

Limited Use Statement

Cover Me's use of information received from Chrome extension APIs, browser storage, and user-provided data is limited to the practices disclosed in this Privacy Policy. Specifically:

  • →Data collected is used solely to provide and improve the features you explicitly request: reading a job posting, tailoring your resume to it, and writing a cover letter.
  • →We do not use data to develop, improve, or train AI or machine learning models. We pass it to third-party AI APIs (Anthropic, or OpenAI with your own key) only as part of a request you make; each provider handles API data under its own terms, linked above. From version 1.3.0, requests made with your own OpenAI key ask OpenAI not to store them.
  • →We do not use data for personalised advertising or retargeting of any kind.
  • →We do not sell or transfer user data to third parties for purposes unrelated to providing the Cover Me service.
  • →We do not allow humans to read user-generated content (resumes, cover letters, job postings) except with explicit user consent, for security and fraud prevention, to meet legal obligations, or in aggregate anonymised form.
  • →We do not use data to determine creditworthiness or for lending decisions.

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

Children's Privacy

Cover Me is not directed at children under the age of 13. We do not knowingly collect personal information from children under 13. If you believe we have inadvertently collected such information, please contact us immediately and we will delete it.

Changes to This Policy

We may update this Privacy Policy from time to time. When we do, we will update the effective date at the top of this page. For material changes, we will notify Hosted mode users via email. Continued use of Cover Me after a policy change constitutes acceptance of the updated policy.

Because Cover Me is open source, all historical versions of this policy are visible in the public GitHub repository commit history.

Contact

If you have any questions about this Privacy Policy, wish to exercise your data rights, or want to report a security concern, please contact:

Lincoln Laylor

Developer, Cover Me

support@cover-me.dev

Cover Me is open-source software released under the MIT License. The source code is available at github.com/TheLinc/cover-me.