Open Source Privacy Policy
Last updated: September 7, 2026
ProposalLift is open-source software designed to be self-hosted. This policy covers that open-source build and the ProposalLift Chrome extension, which connects to whichever instance of the software you point it at. It explains what information is collected, how it is used, and your rights regarding your data.
The short version
- ProposalLift is open-source software designed to be self-hosted. This policy covers that open-source build and the Chrome extension published by ProposalLift.
- The extension has no server of its own. It sends network requests only to the ProposalLift address you type into it.
- Your content lives in the database of the instance you signed up on. It is readable only by your own account.
- There is no analytics, no telemetry, no advertising, and no tracking of any kind in either the app or the extension.
- Personal information is never sold, and never shared with anyone for their own commercial purposes.
- AI generation runs on your API key. There is no shared platform key, and no request is billed to anyone but you.
- Using the hosted service at proposallift.com instead? That is a separate deployment with its own billing and infrastructure, covered by the main privacy policy.
1. Software, instance, and extension
Three different things share the name ProposalLift, and this policy applies to them differently. Reading it is much easier once they are apart:
| What it is | Who is responsible |
|---|---|
| The software. An open-source codebase that anyone may download and run. It is not a service and holds no data. | Nobody, until somebody runs it. Publishing the source collects nothing. |
| An instance. One running deployment of that software, with its own database and its own users. | Whoever operates it. Where you run the software yourself, that operator is you. |
| The Chrome extension. A client, published to the Chrome Web Store by ProposalLift. It is a window onto whichever instance the user points it at. | Its behaviour is described in section 3 and is the same wherever it is pointed. |
The operator of each instance chooses and controls the infrastructure that runs it. So if you connect the extension to an instance operated by somebody else, that operator, not ProposalLift, is responsible for the data you put into it, and this policy does not describe their practices. Installing the extension by itself creates no relationship with ProposalLift and sends ProposalLift nothing.
2. How your data moves
Every feature follows the same path, and each hop is something you initiated:
The Upwork job application page
You open it. Nothing has moved yet.
The Chrome extension
Reads the job details from that page when you press a button. Stores nothing about it.
The ProposalLift instance you configured
The only address the extension ever sends a network request to. Holds your account and your content.
Your AI provider, on your own API key
The instance forwards the prompt. The extension never holds the key and never talks to the provider.
The boundary that matters for the extension is between steps 2 and 3. The extension itself sends network requests only to the ProposalLift server address you configured. That instance may then communicate with the third-party services described in section 8 in order to do what you asked.
3. The Chrome extension
Single purpose
The extension has one purpose: to help you draft a proposal on an Upwork job application page, using the personas, portfolio, hooks, and templates stored in your own ProposalLift account.
Permissions, and why each is needed
| Permission | Why it is requested |
|---|---|
storage | Remembers your server address and your panel preferences between visits, and holds the sign-in session for the server you connected to. Without it you would re-enter your address and sign in on every page load. |
identity | Opens a normal browser window on your own ProposalLift site so you can sign in there, then receives a one-time code back. This is what lets sign-in work without the extension ever seeing your password. |
| Content script on www.upwork.com/nx/proposals/job/*/apply/* | Draws the drafting panel on the Upwork apply page, reads the job details you are applying to, and writes the generated draft into Upwork's own proposal box. It runs on that one page pattern and nowhere else: not on Upwork's other pages, and on no other website. |
The extension requests no host permissions. Chrome therefore never asks you to let it “read and change your data” on your ProposalLift domain; the connection works because your own server opts in via CORS. It also declares a strict content security policy (script-src 'self') and loads no remote code.
What is stored on your device
| Stored | Where | Why |
|---|---|---|
| Your ProposalLift server address | chrome.storage.sync | So the extension knows where to send requests. Synced so it follows you to your other Chrome profiles. |
| Panel preferences: selected persona, template, hook, tone, length, and whether to answer screening questions | chrome.storage.sync | Conveniences, so the panel opens the way you left it. |
| Your sign-in session: access token, refresh token, expiry, your email, and the server that issued it | chrome.storage.local | Keeps you signed in. Deliberately kept out of Chrome sync so a credential never travels between machines. A session is bound to the server that minted it and is discarded if you point the extension elsewhere. |
These values live in Chrome's storage on your own device. They are not transmitted to any ProposalLift server other than the one you configured, and they reach that server only when the extension needs to talk to it: the session token authenticates each request, and the server address is simply where the request is sent. Signing out or removing the extension deletes all of it.
What is read from the Upwork page
When you ask the panel to write a draft, it reads the following from the job application page you are already viewing and sends it to your configured ProposalLift instance so it can be given to the AI model:
- The job title, description, and URL
- The listed skills (up to 30)
- Budget, hourly range, and experience level, where the page shows them
- The text of any screening questions, but only when you tick the box asking for them to be answered
- When you select a passage and ask for a rewrite: that passage, your instruction, and roughly 600 characters either side of it for context
This happens when you act, not in the background. The extension does not read pages you have not asked it to work on, keeps no copy of what it read, and collects no browsing history.
What the extension never does
- It never submits a proposal for you. Every draft it writes into Upwork's box is yours to review, edit, and send by hand. No button is clicked on your behalf and no connects are spent.
- It never sees your password. Sign-in happens on your own site in a real browser window.
- It never receives your AI API key. The key stays on your instance; the extension is told only whether one is present.
- It contains no analytics, no error reporting, no advertising, and no third-party scripts.
Limited Use disclosure
Our use of information obtained through the extension adheres to the Chrome Web Store User Data Policy, including its Limited Use requirements. Specifically: data is used only to provide the proposal-drafting features described above; it is not transferred to anyone except as needed to provide those features, and never to advertisers, data brokers, or information resellers; it is not used for advertising, retargeting, or credit assessment; and no human reads it except where you explicitly ask for support, where the law requires it, or on data that has been aggregated and anonymised.
4. What an instance stores
Everything below is stored in the database of the instance you signed up on, owned by your account, and readable only by you. It exists because you entered it or asked the app to create it.
| Category | What it contains |
|---|---|
| Account | Your email address, an authentication record held by Supabase Auth (your password is stored only as a salted hash and is never visible to the operator), whether your email is verified, and sign-in timestamps. Where the operator has enabled Google sign-in, Google returns your email address and basic profile details to complete it. |
| Profile and personas | Your name, role, biography, skills, experience, and profile links, plus any personas you create. Optionally imported from an Upwork profile you connect. |
| Portfolio | Projects you add (titles, descriptions, links, categories, and tags), together with a numeric embedding of each project's text, used to match past work to a job. |
| Proposal material | Hooks, templates, saved job filters and their qualifying criteria, your knowledge-base notes, and the proposals you generate and save, with their status. |
| Upwork connection | The client ID and secret of the Upwork developer application you register, and the OAuth tokens issued to it. Both are encrypted at rest. |
| AI credentials | The OpenAI and/or Anthropic API key you supply, encrypted at rest with a separate key from the Upwork credentials. |
| Job alerts | Webhook destinations you configure, the state needed to tell a new job from one already sent, and a delivery log of attempts and their outcomes. |
| Operational records | Onboarding progress, a last-seen timestamp, counters of calls made to the Upwork API on your behalf, and short-lived one-time codes used to hand a session to the browser extension. |
Upwork job listings are not stored. The job feed is fetched live from Upwork each time you open it and is never written to the database, in keeping with Upwork's terms on caching their data. Whether you have applied to a job comes from Upwork's own records.
5. What is never collected
- No analytics or telemetry. There is no Google Analytics, no Sentry, no session recording, no heatmaps, and no product analytics anywhere in this codebase.
- No advertising or tracking. No advertising identifiers, no cross-site tracking, no fingerprinting, and no third-party marketing pixels.
- No payment data. This build has no billing, no plans, and no payment processing, so there is nothing to collect.
- No browsing history. The extension reads only the Upwork apply page you are working on, when you act.
On sharing, the precise position is this: personal information is never sold or rented, and it is never shared with third parties for their own independent advertising or commercial purposes. It is transmitted to service providers only where doing so is necessary to deliver a feature you asked for (sending a prompt to your AI provider, fetching jobs from Upwork, delivering a verification email), as described in section 8.
6. How your data is used
Your information is used only to run the features you asked for:
- To authenticate you and keep you signed in.
- To fetch job listings from Upwork on your behalf, using the credentials you connected.
- To assemble a proposal (the job, your chosen persona, the portfolio projects most similar to that job, a hook, and any template or knowledge-base notes) and send it to the AI model you selected.
- To notify your configured webhook when a saved filter matches a new job, if you set that up.
- To send transactional email: address verification, password reset, and job alerts. No marketing email is sent.
- To keep the service secure and to enforce rate limits.
You are not profiled, no automated decision with legal effect is made about you, and your content is not used to train any AI model belonging to ProposalLift.
7. AI processing and your own API key
This build has no shared AI key. Generation, job qualification, rewriting, and portfolio embedding all run on the OpenAI or Anthropic key you save in Settings, and nothing works until you provide one.
The path is always the same:
↓ your own API key
OpenAI or Anthropic
The content sent for generation (the job text, your persona, the matched portfolio projects, your hook, template, and knowledge-base notes) is transmitted by the instance directly to that provider under your own account, and their privacy policy and data-retention terms govern what happens to it. Review OpenAI's policy or Anthropic's policy for whichever you use.
Your key is encrypted at rest, is never sent to the browser, and is never given to the Chrome extension. When the extension asks what it may offer you, the instance answers with the list of models you have configured and a yes-or-no on whether a key exists, never the key itself.
8. Service providers
Because this build is self-hosted, the providers behind an instance are chosen by whoever operates it, and an independently run instance may use entirely different ones. The list below is the default set the open-source build is wired for. Each is used for one job and nothing else.
| Provider | What it handles |
|---|---|
| Vercel | Hosts the application and serves it to your browser. Processes request metadata such as IP address in the ordinary course of serving traffic. |
| Supabase | The Postgres database and authentication. Everything in section 4 is stored here. |
| OpenAI / Anthropic | Generates proposal text and embeddings, under your own API key. See section 7. |
| Upwork | Job search and profile data, fetched live using the developer credentials you connect. Upwork's own terms and privacy policy apply to your relationship with them. |
| Resend | Delivers transactional email: verification, password reset, and job alerts. |
| Google (optional) | Only where the operator has enabled “Continue with Google” as a sign-in method. Google then supplies your email address and basic profile details to create or match your account. |
| Upstash (optional) | Rate limiting. Used only when the operator configures it; the app runs without it. |
10. Security
- Every row in the database is owned by exactly one user and isolated by Postgres row-level security, so one account cannot read another's data even if application code is at fault.
- Upwork credentials and AI API keys are encrypted at rest, each under a separate, independently rotatable key.
- The extension refuses to store a server address that is not
https, other thanlocalhost, so tokens do not travel unencrypted. - Extension sign-in uses a one-time code that expires after 120 seconds, requires an explicit click on a consent screen, and is bound by exact match to the extension that requested it.
- A session is tied to the server that issued it and is discarded rather than reused if the extension is pointed somewhere else.
No system is perfectly secure, and absolute security cannot be guaranteed. If you believe you have found a vulnerability, please report it to admin@proposallift.com rather than disclosing it publicly.
11. Retention and deletion
Your content is kept until you delete it or close your account. Deleting a persona, portfolio project, proposal, template, hook, or filter removes it immediately.
You can disconnect Upwork or remove your AI key at any time in Settings, which erases those credentials. Removing the extension from Chrome erases everything it held locally.
You can delete your account yourself, in Settings, with no request and no approval. It asks you to type your own email address to confirm, then removes the account immediately: there is no grace period, no waiting list, and nothing is archived.
Everything belonging to the account goes in the same operation, including records you never created by hand: your profile and settings, saved filters, personas, portfolio projects and their embeddings, proposals, templates, hooks, webhook configurations, their delivery logs, and your Upwork API usage counters. Deletion is irreversible.
12. Your rights
Depending on where you live, in particular under the GDPR in the UK and EEA, and the CCPA/CPRA in California, you may have the right to access the personal information held about you, correct it, delete it, obtain a portable copy, object to or restrict certain processing, and withdraw consent where processing rests on it.
Most of these you can exercise yourself, without asking anyone: nearly everything held about you is visible and editable in the app, and erasure is a button in Settings rather than a request (see section 11). For anything else, email admin@proposallift.com and ProposalLift will respond within 30 days. You will not be treated differently for exercising a right. If you are in the UK or EEA and are unsatisfied with the response, you may complain to your local supervisory authority.
Where the GDPR applies, the lawful bases are performance of a contract with you (running the service you signed up for), legitimate interests (keeping the service secure and working), and consent where you have given it.
13. Children
ProposalLift is a tool for professional freelancers and is not directed at children. Personal information is not knowingly collected from anyone under 16. If you believe a child has provided information, email admin@proposallift.com and it will be deleted.
14. International transfers
The providers in section 8 may process data in countries other than your own, including the United States. Where personal information is transferred out of the UK or EEA, it is protected by the transfer mechanisms those providers maintain, such as the European Commission's standard contractual clauses.
15. Changes to this policy
This policy may be updated as the software changes. The date at the top always reflects the current version, and because ProposalLift is open source, the full history of this page is public in the project's repository. If a change materially affects how your data is handled, you will be told by email or in the app before it takes effect.
16. Contact
Questions about this policy, or about the data held on an instance operated by ProposalLift, go to:
ProposalLiftadmin@proposallift.com
If you use an instance operated by someone else, contact that operator instead. ProposalLift has no access to their data.
