Available only in Switzerland

Schweizerform is currently available exclusively for users in Switzerland. Account creation from your region is restricted.

Security architecture

A form provider that cannot read its own customers' data.

Schweizerform is a zero-knowledge system. Every submission is locked inside the respondent's browser before it leaves the page, and the keys that unlock it never exist outside the owner's session. This page explains how — and what we cannot do as a result.

Symmetric cipher

AES-256-GCM

Asymmetric cipher

RSA-OAEP 2048, SHA-256

Key derivation

PBKDF2-SHA-256 · 100 000

Hosting jurisdiction

Switzerland — Infomaniak

First principles

Three things we believe, four things we don't do.

Security isn't a feature we shipped on top of a form builder. It's the shape the form builder was built around.

Principle 01

The operator must not be able to read your data.

Not "will not." Cannot. A trusted operator is a single point of failure — and a magnet for court orders, insider threats, and stolen credentials. Our system removes us from the unlocking path entirely.

Principle 02

Sovereignty is physical, not contractual.

A "data residency" clause in a contract is paper — switching jurisdictions takes one amendment. We run the whole stack — application, database, file storage, and email — on Swiss infrastructure. No US or EU vendor ever sits in the data path.

Principle 03

The respondent's browser belongs to the respondent.

The public form page loads no third-party scripts. No Google Analytics, no Sentry, no Mixpanel, no Intercom, no advertising pixel. The only network the respondent touches is ours.

Key hierarchy

Four layers of keys. None of them on our servers.

Your Access Code, typed into your browser, produces a Master Key in memory. That Master Key opens each form's Form Key. The Form Key opens the form's private key. The private key opens every submission's one-time key. The chain ends in your head — never in our database.

Layer 01 · Owner secret

Access Code

Origin: A passphrase you choose (6 chars minimum)

Storage: Only in the owner's head — never sent anywhere

PBKDF2-SHA-256 · 100 000 rounds · 32-byte salt

Layer 02 · Derived

Master Key

Algorithm: AES-256-GCM (used as a Key-Encryption Key)

Storage: In browser memory only · cleared on logout

unwraps

Layer 03 · Per form

Form Key

Algorithm: AES-256-GCM · bound to form_key_creation

Storage: Stored in the database — but only the sealed version, never the open one

unwraps

Layer 04 · Per form

Form RSA Private Key

Algorithm: RSA-OAEP 2048 · SHA-256 · bound to form_private_key

Storage: In the database, sealed under the Form Key

unwraps

Layer 05 · Per submission

Submission Key

Algorithm: AES-256-GCM · bound to formId:submissionId

Storage: Sealed under the form's RSA public key

Submission lifecycle

Plaintext enters the respondent's browser. Plaintext exits the owner's browser. In between, only scrambled bytes.

Respondent's browser

Encrypt → send

  1. 1Loads the public form page. Receives only the form's public lock (an RSA public key) — never the key that opens it.
  2. 2If the form is password-protected, the questions stay on the server until the password is checked — the question list never even reaches the browser before then.
  3. 3Fills in the answers. Selects the files to attach.
  4. 4The browser generates a fresh AES-256 Submission Key using the built-in Web Crypto API — the same one Chrome, Firefox and Safari ship with.
  5. 5Encrypts the answer payload with AES-GCM, bound to this form's ID and this submission's ID so it can't be replayed elsewhere.
  6. 6Encrypts each file separately. Generates a random filename for each.
  7. 7Seals the Submission Key with the form's RSA public lock (OAEP, SHA-256).
  8. 8Sends the sealed key, the initialisation vector, and the encrypted blobs to our API.

Schweizerform server

Persist → forget

  1. 1Checks request size, rate limits, and the password challenge if one is set.
  2. 2Writes the encrypted blobs to Infomaniak's S3-compatible storage under {userId}/forms/{formId}/submissions/{submissionId}/.
  3. 3Saves the sealed key and initialisation vector in MySQL on the submission row. That is the only "key-shaped" data we store — and it's useless without your Access Code.
  4. 4Bumps the response counter on the form.
  5. 5Returns 201 Created. That's the end of the server's involvement.
  6. 6We never see plaintext. We never derive a key. We never hold a private key.

Decryption — owner side

When you open a submission, your browser walks the four-key chain in reverse: Access Code → Master Key → Form Key → Form Private Key → Submission Key → readable content. All of it happens locally; nothing decrypted ever leaves your device.

Threat model

What an attacker would have to do to read your forms.

We documented these so our customers and their security teams can review them. If you spot a scenario we haven't covered, write to support@schweizerform.ch.

AdversaryWhat they getWhat we do about it
Database dump leaked or stolenSealed data blobs and sealed key blobs. No readable content.Everything is encrypted with AES-256-GCM. Without the owner's Access Code, not a single row decrypts.
Compromised server admin or insiderSame as above. Our server-side code never sees the Master Key or any plaintext.An append-only internal audit log records every privileged action. Production is least-privilege; our engineers cannot read submissions through the dashboard.
Subpoena / lawful order to discloseCiphertext blobs and metadata (created-at, IP, request ID).We can comply with a valid order and still hand over nothing readable. We document this on the public page.
Stolen owner session cookieAccess to the dashboard shell — but every form is still locked behind the Access Code, which we don't keep in the session.Sessions are short-lived and slide on activity. The Access Code must be entered each session and lives only in browser memory.
Phishing / malicious browser extensionWhatever the user types. This is outside our trust boundary.Strict Content Security Policy on the public form page. No third-party scripts allowed. We warn owners against shared or untrusted devices during onboarding.
Brute force on the Access CodeA slow wall of 100 000 PBKDF2 rounds standing between them and a single guess.Each guess costs ~80 ms in a modern browser. We rate-limit logins on the server, lock accounts after repeated failures, and steer owners toward long, hard-to-guess Access Codes.
Forged / replayed submissionJunk bytes that fail authentication during decryption.Each ciphertext is bound to its specific form and submission ID. A blob replayed against another form will simply fail to authenticate and be rejected.

Infrastructure

Every byte, every server, in Switzerland.

Application servers, MySQL database, S3-compatible file storage, and transactional email all run on Infomaniak — a 100% Swiss-owned, employee-controlled hosting provider. The only outside calls we make from our servers are a brief IP lookup (3-second timeout, fail-closed) and Stripe for owner billing.

Stripe never touches respondent data. It only sees owner billing details for the subscription itself.

  • Application servers (Next.js)

    Infomaniak · CH

  • MySQL database

    Infomaniak · CH

  • Object storage (S3-compatible)

    Infomaniak · CH

  • Transactional email (SMTP)

    Infomaniak Mail · CH

  • DNS / network edge

    Infomaniak Envoy · CH

  • Geo IP resolution

    ipinfo.io · server-to-server only

  • Billing (owners only)

    Stripe · owners only, never respondent data

Honest limits

Things we cannot do — and won't pretend to.

Zero-knowledge cuts both ways. Here's what it costs you, stated plainly.

Not possible

Recover a lost Access Code.

Your Access Code is the starting point for every key that protects your forms. We never receive it, never store it, never email it. If it's lost, the data sealed under it is unrecoverable. You can change it from inside your account — that re-encrypts every form under the new code.

Not possible

Reset a password and "decrypt your data automatically."

Some "encrypted" services do this — which quietly means they had the keys all along. We don't. A password reset gets you back into the dashboard, but you still need your Access Code to read any form.

Not possible

Look up a submission's content for support.

If you write to us asking "what did so-and-so submit on Tuesday?", we genuinely cannot answer. Our support team sees the same scrambled bytes as everyone else. We can help with metadata: counts, timestamps, billing.

Not possible

Run AI / analytics on submission content.

We don't train AI models on your form data — because we don't have your data in any form we could train on. Aggregate counts come from server-side metadata, never from the answers themselves.

What's encrypted, what isn't

Total transparency on every byte.

Some data has to stay readable for the system to work — your email address (for password resets), and the form's public lock (so respondents can encrypt to it). Everything else is opaque.

DataVisible to usWhy / how protected
Form answers (text, numbers, choices)NoAES-256-GCM. The key never leaves the owner's browser.
File uploads (PDFs, images, etc.)NoEach file is encrypted with the same one-time Submission Key. Original filenames are replaced with random IDs server-side.
Form titles, question labelsPartialStored on the form record so the public page can render the form. Hidden from respondents behind password protection until the password is accepted.
Owner email + nameYesNeeded for login, billing, one-time codes, and password reset. Treated as personal data under nFADP and GDPR.
Owner password hashNobcrypt with 12 rounds. We never see the password itself, only the hash.
Submission timestamps + respondent IPYesNeeded for rate-limiting and audit. The IP is recorded in the audit log; it never appears as plaintext inside the form payload.
Submission ciphertext + wrapped keyNoStored in S3 and MySQL. Both are useless without the chain of keys that ends in your Access Code.
Site analytics events (operator-side)AggregatedPseudonymous (a hashed fingerprint), hosted by us on our Swiss servers. Used only for the marketing site and our internal observability — never for respondent answers.

Compliance

Aligned with the rules that matter for sensitive data.

Schweizerform isn't a compliance-checkbox tool, but the architecture is designed so that meeting these rules becomes much easier for our customers.

nFADP

Revised Swiss Data Protection Act

In force since 1 September 2023. We align with its requirements: Swiss data residency, breach-notification readiness, data-subject rights, and encryption of personal data both at rest and in transit.

Architecture aligned · Compliant by design

GDPR

EU General Data Protection Regulation

Compatible architecture: a lawful basis for the limited owner-side data we hold; respondent data never leaves Switzerland (so no Standard Contractual Clauses needed for it); a Data Processing Agreement is available on request for business customers.

Architecture aligned · DPA on request

HIPAA

US Health Insurance Portability & Accountability Act

Our encryption building blocks are compatible with the HIPAA Security Rule (encryption, access control, audit). We don't currently sign Business Associate Agreements — talk to us if you need one and we'll share where it sits on the roadmap.

Primitives compatible · BAA on roadmap

Beyond encryption

The boring controls that hold the rest of it up.

Append-only audit log (operator-side)

We keep an internal, tamper-evident trail of every login, one-time code, form publish, and billing event — with IP, browser, and request ID — that we use for security review and incident response. It's an internal tool, not a customer-facing dashboard.

Session & OTP

Sessions slide for up to 7 days, with 128-character opaque tokens stored in HttpOnly + Secure + SameSite cookies. We use a 6-digit one-time code on signup and password reset.

Rate limiting

Persistent token-bucket rate limits on login, one-time codes, password attempts, and Access Code attempts. Survives restarts and works across multiple instances.

CSRF protection

Cross-site request forgery is blocked by a double-submit token across the whole authenticated surface. The public form route is exempt by design (no session) but is rate-limited.

Strict CSP & headers

The public form page disallows third-party scripts at the browser level via Content Security Policy. HSTS, X-Frame-Options, and X-Content-Type-Options are applied across the surface.

First-party error & site analytics

Our error logger and marketing-site analytics run on our own Swiss servers. Sentry, Google Analytics, and Mixpanel are not in the picture — and respondent submission data is never touched by either system.

Disclosure

Found something?

We take security reports seriously and reply within one business day. Please disclose responsibly — we credit researchers on request.

Contact

support@schweizerform.ch

PGP key on request. Please include reproduction steps, impact, and any logs — and don't include real customer data in your report.

Common questions

Security, explained without hand-waving.

A form provider that cannot read your forms. Now try it.

Full end-to-end encryption on every plan, including free. No credit card required.