Last updated: October 6, 2026
CalcForms stores two kinds of data on your behalf: the forms you build, and the submissions your customers send. This page explains how both are protected. It is written to be checked against, so it states only what is actually in place. Questions go to security@badabingapp.cc.
Forms, submissions and file uploads are stored in a Postgres database and a private storage bucket hosted by Supabase in the United States. The website and form pages are served by Cloudflare. Transactional email is sent by Resend. When you use the AI builder, your form description, or your current form and the change you asked for, is sent to OpenRouter to build the form. When you brand a form from your website, what we read there (its address, name, page title and description, colors, fonts, and logo image addresses and alt text) is sent to OpenRouter to choose the form's look. Submission contents are never sent to OpenRouter. They reach ChatGPT or Claude only when you ask your own connected assistant for them. Pro subscriptions are sold through Lemon Squeezy, the merchant of record, which handles card details, billing address and tax; we never receive a full card number. The privacy policy lists these five services with the same scope. Some pages also load fonts or code straight from Google Fonts, unpkg or jsDelivr, and those providers see the visitor's IP address when they do. A CRM you connect (HubSpot or Salesforce) is your own account, not a CalcForms subprocessor; see Connected CRMs. A webhook address you set on a form receives each new submission in full, and the service behind it is your choice, not a CalcForms subprocessor.
All traffic to and from CalcForms uses TLS. This includes form pages, the dashboard, the MCP connector endpoint, webhook deliveries (which are refused unless the destination is HTTPS), deliveries to a CRM you connect, and connections from our edge code to the database and storage. Data at rest is stored on our hosting providers' managed infrastructure.
Every owner-scoped table is protected by Postgres row-level security. For forms, submissions, invites and sessions it is keyed to the owner's account: a signed-in user can only read or change their own, and that rule is enforced by the database, not only by application code. The tables that hold a connected CRM's settings, credentials and send records are closed to browsers and connected assistants: row-level security is on with no rule that opens them, so only our server-side code reads or writes them, and that code, not a database rule, limits what a signed-in user sees or changes there to their own account.
The browser and connected assistants only ever hold a public, publishable key plus a token for the signed-in user. The privileged service key that can bypass row-level security exists only in server-side code and is never sent to a browser or a client.
Calculated fields are private to you unless you mark one as visible. Your customers see only the results you mark visible; private results are hidden. The formulas and lookup tables that compute every result, private ones included, are still in the page source, so someone who reads the source can see how a private result is worked out. Webhook settings and your email address are never included in the page.
File uploads go to a private bucket. Files are written only under the folder of a published form and cannot be listed or enumerated across forms.
Each submission receipt page is protected by a random token in the link, so submission records cannot be found by guessing IDs.
Sign-in is by one-time email code or by email and password, handled by Supabase Auth. Assistants such as ChatGPT and Claude connect over OAuth 2.0: the user is sent to a CalcForms consent page, signs in there, and the assistant receives a short-lived access token and a refresh token for that user's account. CalcForms never receives the user's ChatGPT or Claude credentials.
Tokens are scoped to one account and carry the same row-level security as a dashboard session. You can disconnect CalcForms from ChatGPT or Claude at any time, which stops further access. CalcForms connects to a third-party account on your behalf, and stores credentials for one, only when you connect a CRM, as described under Connected CRMs.
When you connect HubSpot or Salesforce, you choose, form by form, which answers and results are sent there with each new submission. Until you connect one, CalcForms holds no credentials for either. For HubSpot we hold the access and refresh tokens HubSpot issues when you approve the connection, limited to reading and writing contacts. For Salesforce we hold the consumer key and secret of an app your Salesforce admin creates in your own Salesforce account, and the access tokens Salesforce issues for that app. We also keep your Salesforce account's My Domain address, which is not a secret: the dashboard's links to your Leads use it.
These credentials are encrypted with AES-256-GCM before they are stored, with a key held only in the environment of our server-side code, never in the database. They are never shown back to you and never sent to a browser: the dashboard shows which account is connected and, for Salesforce, the last four characters of the consumer key. Disconnecting in the dashboard deletes them, and asks HubSpot to revoke the refresh token, or Salesforce the access token. For HubSpot, the CalcForms app stays installed in your HubSpot account until you uninstall it there. For Salesforce, the key and secret stay valid in your Salesforce account until your admin deletes the CalcForms app in Salesforce, which your admin can do at any time to cut off access.
Public form submission and email-sending endpoints are rate-limited per address and per form, forms carry a honeypot field, and outbound webhooks are validated against private and internal network ranges before delivery. Web pages are served with a content security policy and standard browser hardening headers.
Every webhook delivery can be verified. When a secret is set, each request carries an X-CalcForms-Signature header containing an HMAC-SHA256 of the raw body. Details are in the documentation.
Forms and submissions are kept for as long as your account is active. You can delete forms and individual submissions at any time, in ChatGPT or in the web portal on Pro. Files your customers upload are not deleted with a submission or a form; they are kept until we delete them. Answers a customer saved to finish a form later are kept after their 30 day link stops working, until the form is deleted or we delete them. Website analytics are first-party and cookie-free; raw records are deleted after 90 days and only daily totals are kept. To have a file or saved answers deleted, or to delete an account and everything in it, email hello@badabingapp.cc. What is kept, and for how long, is set out in the Privacy Policy.
Every change to CalcForms ships through a reviewed pull request and an automated pipeline that verifies the live site after each deploy. The pipeline includes a check that the sign-in and OAuth surfaces have not changed unless the change was declared, so authentication cannot drift by accident. A daily check compares production against the repository and alerts us if anything was changed outside that process.
We run internal security reviews of the code and of the live database policies. The most recent reviews found and fixed issues in tenant isolation and public read access; each fix was verified against production before it was recorded. We do not currently hold a SOC 2 report or an external penetration test. If your procurement process needs one, tell us and we will say plainly where we stand.
If you believe you have found a security issue, email security@badabingapp.cc with enough detail to reproduce it. We acknowledge reports within two business days and will tell you when the issue is fixed. Please do not access data that is not yours while investigating; a proof of concept against your own account is enough.