Security
How QuoteBill protects accounts and documents: row-level security, hashed keys and links, logged administrator access, the E-Contracts audit chain.
What this page covers
This page lists what QuoteBill’s code and database do to protect accounts and documents. It describes measures, not guarantees: no service is free of flaws, and this page is neither a certification nor an audit. What each feature stores and for how long is in the privacy notice; the trust details of E-Contracts have a page of their own.
Who can read your data
Your saved documents and company settings are protected by row-level security in the database: from a browser, only the signed-in owner can read or change them.
A sign-in token issued to an AI app is refused on those tables by a restrictive rule, so an AI app you connect cannot open your saved documents, contracts or files. The QuoteBill MCP server itself uses only public information and calculations; it does not read member data.
Tables that only our servers use, such as visit records, daily totals and rate-limit counters, are closed to browsers and AI apps: row-level security is on, and no policy or privilege lets them read.
E-Contracts data sits in a private database schema that browsers cannot query. It is reachable only through a fixed set of database functions that check who is asking. A contract is looked up by its id and its owner, so another member’s contract answers exactly like one that does not exist.
Some data is public by design: community posts and published articles. Company logos, stamps and signature images are stored where anyone who has their address can open them, so do not upload confidential images.
Passwords and sign-in
Your password goes from your browser straight to Supabase Auth, our sign-in provider; QuoteBill’s own code never stores it, and how Supabase Auth protects it is described by Supabase. If you sign in with Google, Google tells Supabase Auth who you are. QuoteBill remembers in your browser only how you signed in and your email address, so that the next sign-in is quicker.
E-Contracts: links, codes and sessions
A signing link carries a secret of 32 random bytes. QuoteBill stores only its SHA-256 hash, and the sender is shown the link once, when it is made. The secret travels after the # sign of the address, which keeps it out of the request lines our server logs, and the page removes it from the address bar after reading it. Making a new link for a signer ends the old one at once.
An access code has 8 characters from an alphabet of 32 symbols and is stored only as a salted bcrypt hash. Wrong codes lock the link for 15 minutes after the fifth and after the tenth wrong try, and after the fifteenth the link is revoked.
A signer’s session is a random secret of which only the SHA-256 hash is stored. It lasts 30 minutes from the last action and 2 hours at most.
Each action has a limit per network address and per signer, counted with a salted hash of the address. A sweep every ten minutes deletes counters older than two hours.
Once a contract is closed (completed, declined, voided or expired) its link stops working, and the stored hashes of its link, code and session are deleted within 30 days at the latest.
E-Contracts: the audit chain
Every action on a contract (sent, opened, consented, signed, declined, reminded and so on) is written as an event. The SHA-256 hash of an event covers its own content (the contract, the sequence number, the kind of event, the actor, the time from the database clock, the network address, and hashes of the browser and of the detail) and the hash of the event before it. The first event is chained to the contract’s reference. The hash of the final completed event is the certificate hash printed on the certificate and shown on the verification page.
The text that is signed is frozen and bound to a fingerprint, the SHA-256 hash of its canonical form, which the database recomputes. Triggers in the database refuse to update, delete or truncate events, signed records and the verification record.
You can check an evidence file on the verification page: your browser walks the chain and the signatures itself and sends QuoteBill only the contract’s reference and fingerprint.
What this shows: that the evidence file is consistent with itself and matches the record QuoteBill keeps. What it does not show: who signed, because QuoteBill does not verify identities. No secret key signs the chain and no outside time-stamp service stamps it, so the times are those of QuoteBill’s own database clock. Someone with administrator access to the database could in principle switch the triggers off, rewrite records and recompute the hashes; copies held by the parties would then no longer match. That is why each party should keep its own signed copy.
What administrators can see
Administrator pages need an administrator account. On every call the database checks the role and that your sign-in session still exists, and it refuses tokens issued to AI apps.
Administrators can open the documents members have saved to the cloud, to give support, to look into abuse or to meet a legal duty. Opening is read-only, and each opening is written to a log (which administrator, which document, when) that triggers keep from being changed. The list that leads to a document shows the owner’s email address and name, the document’s name, number, customer, status and total; only opening a document is logged.
That screen does not open E-Contracts. For contracts that were reported, administrators see the title, reference, status, number of reports, the last reason and the owner’s email address, not the contract text or the signatures, and they can suspend a sent contract.
Changing a member’s role or document limit needs a written reason and is recorded in a log that cannot be edited; only a super administrator changes roles. QuoteBill has no feature to sign in as a member.
The people who run the database can technically reach everything stored in it. The measures above control and record the use of QuoteBill’s own administrator pages, not that technical access.
API keys and AI apps
An API key has the form qbk_ followed by 32 random characters. QuoteBill stores its SHA-256 hash with its first eight characters (so that you can tell your keys apart), its name, its permissions and its dates; the key itself is shown once, when you make it. You can have five active keys at a time, each expires after 30, 90 or 365 days as you choose, and you can revoke one at any time.
A key can create draft documents and read your saved documents in a reduced form (customer details, items, notes and totals). It cannot edit, delete, send or sign anything, change settings or keys, or reach E-Contracts. Each key is limited to 60 requests a minute and 5,000 a day, and the API’s log keeps only the method, the route and the result, never the content.
An AI app such as ChatGPT, Claude or Gemini signs in with your permission and receives an ordinary sign-in token for your account, issued by Supabase Auth. With it the app can read your account’s email address, name and photo as Supabase Auth returns them. The MCP server asks Supabase Auth whether the token is valid, remembers the answer for up to a minute, and does not pass the token on. Its tools use only public information and calculations. The database refuses a token issued to an AI app for your saved documents, contracts, files and administrator functions, and for making API keys.
For rate limits the MCP server stores a salted one-way hash that changes every minute, and its log has the tool that was called, whether it answered and the app’s name, never the request.
What is hashed, and what QuoteBill does not encrypt
QuoteBill’s own code does not encrypt stored data. The site is served over HTTPS and sends a Strict-Transport-Security header for one year; encryption of the connection and of stored data is provided by our hosting and database providers, and this page makes no claim about it beyond that.
- Signing links, signer sessions and API keys: stored only as SHA-256 hashes.
- Access codes: stored only as salted bcrypt hashes.
- Visit codes: a keyed hash (HMAC-SHA-256) of your network address and browser details, with a key that changes every day; the address itself is not stored.
- Rate-limit counters: salted hashes of network addresses.
- Invitation records: a SHA-256 hash of the email address that was entered.
- Passwords: handled by Supabase Auth.
Protections in the browser
Pages are sent with X-Content-Type-Options: nosniff and a strict referrer policy. Other sites cannot show them in a frame (X-Frame-Options: DENY and a frame-ancestors none rule), except the template and tool embeds that are made to be embedded.
The contract, signing and verification pages carry a strict Content Security Policy: scripts only from QuoteBill itself, no frames, and connections only to QuoteBill and its database provider. They carry no ads, analytics or visit counting, are not indexed by search engines and are not cached.
Deleting your account
You can delete your account in settings. QuoteBill removes the images you uploaded and your account, and the documents, contracts, API keys, likes and invite codes tied to it go with it. What stays is listed in the privacy notice: the verification record of completed contracts, the minimal record of a deleted sent contract (kept for a limited time) and the invitation record.
Report a vulnerability
If you find a weakness, please write to auto0104@gmail.com with the page, the steps to reproduce it and what you saw. Do not include other people’s data, and please give us time to fix it before you share it. The same address is in our security.txt file, at /.well-known/security.txt.
This page makes no promise of a reward.
Changes
Last changed 2026-10-06.
- 2026-10-06: First version of this page.