How InPerson protects your association's data

How InPerson protects your association's data

September 19, 2026
5 min read
Author: Martin Žust

When you trust us with your member records, accounting documents and internal communication, you expect your data to be safe. In this post, without technical jargon, we explain how the platform is built and why your data is in good hands.

In short: what protects you

  • File protection — files are stored under randomly generated identifiers, not under user-supplied names
  • DDoS protection — Vercel's global edge network absorbs attacks before they reach our code
  • High availability — the frontend, backend and database automatically recover and scale with load
  • No SQL injection — MongoDB has no SQL parser, so this category of attack simply isn't possible
  • Encryption — TLS/HTTPS at every point of transfer: browser, API, database, external partners
  • Access control — each administrator independently decides which tabs and data members may see
  • Built-in database security — encryption at rest and in transit, mandatory authentication and an IP allowlist
  • Secure passwords and sessions — bcrypt password hashing, random session tokens, httpOnly cookies

1. Why write about security at all?

Associations store a fair amount of sensitive data: members' personal information, financial records, scanned documents, internal communication. InPerson Platform was designed with the idea that security must be built into every layer of the system — not "added" afterwards.

At the same time, we believe in the power of proven solutions. Instead of building security mechanisms ourselves from scratch, we stand on the shoulders of serious providers (Vercel, AWS, MongoDB Atlas) who maintain their systems with entire teams of security experts.

Our core principle: Security isn't a feature you add at the end — it's part of the architectural decisions you make at the start.

2. Protection against unauthorized file access

There's a class of attack where an attacker inserts sequences like ../../ into an uploaded file's name, trying to read files outside the allowed area. A classic example: instead of contract.pdf, they send ../../etc/passwd.

InPerson eliminates this category of attack through an architectural decision, not through filtering:

  • Every uploaded file (documents, receipts, post images) is stored in Amazon S3 under a server-generated random identifier — a UUID — never under a name chosen by the user.
  • The original file name is stored only as metadata in the database for display purposes — it never becomes part of the file path.
  • Because the file path contains no user input at all, there's no string an attacker could even inject ../ sequences into.

The same applies across every module — documents, accounting, email templates and post images.

3. Protection against DoS attacks and traffic spikes

The InPerson Platform frontend runs on Vercel, which is backed by a global edge network (anycast infrastructure). This gives us enterprise-grade DDoS protection without building our own security systems:

  • Traffic floods are absorbed at the global edge network before they reach our servers.
  • Vercel automatically detects and blocks suspicious traffic patterns and bots.
  • Static content is served from caches near the end user — less traffic ever reaches the compute infrastructure at all.

Just as we inherit DDoS protection from Vercel, we inherit it for the backend too (AWS App Runner) — each layer has its own protections that together form defense in depth.

4. Reliability: a platform that doesn't "go down"

Every layer of InPerson Platform runs on managed cloud infrastructure designed for high availability — not on a single server we operate ourselves.

  • Frontend (Vercel): A distributed edge network with automatic failover in case of regional issues. No single point of failure.
  • API (AWS App Runner): Automatic scaling, health checks and automatic restarts of unhealthy instances. No manual server management.
  • Background processes (AWS Lambda): Email and image generation run separately from the main API — spikes in background tasks don't slow down the platform.
  • Database (MongoDB Atlas): A replica set with automatic failover if one node goes down. Automatic backups without our intervention.

Because each layer scales and recovers independently, there is no single component whose failure would bring down the entire system.

5. Why SQL injection isn't possible with us

Classic SQL injection works by an attacker inserting their own SQL code into a database query. InPerson doesn't prevent this category of attack — it simply doesn't need to:

  • Instead of SQL we use MongoDB — a document database with no SQL parser. There's nothing for an attacker to "inject" into.
  • All database queries are structured Python dictionaries via Motor (the official MongoDB driver) — not manually assembled strings.
  • Every request is validated against a Pydantic schema before it reaches the database, ensuring correct types and field shapes.

To be fair, MongoDB has its own vulnerability category ("NoSQL injection"). InPerson addresses this by avoiding JavaScript-evaluating operators ($where) and building filters only from validated, typed fields.

6. Built-in database security

MongoDB Atlas — the managed database we use — comes with security settings that are enabled by default, with no extra work on our part:

  • Encryption in transit: every connection to the database uses TLS.
  • Encryption at rest: data on disk is encrypted automatically.
  • Mandatory authentication: there is no anonymous access — every connection must authenticate.
  • Network access control: the database only accepts connections from explicitly approved IP addresses. Even with stolen credentials, an attacker can't connect from an untrusted network.
  • Automatic backups: Atlas handles continuous backups and point-in-time restore — without us running our own backup infrastructure.

7. Who sees your data — and who doesn't

InPerson Platform uses a discretionary access control (DAC) model, scoped per association. The association's administrator — and only them — decides who has access and to what.

Access is governed at two levels:

  • Level 1 — Is this person even a member of the association? Every account carries an explicit list of the associations it belongs to. Without an invitation or approval from an administrator, there's no access to anything — not even the public member list.
  • Level 2 — Which tabs may they see? Every member has a "can view / cannot view" setting for each tab (Members, Events, Accounting, Mail…). Only association administrators grant or revoke these settings.

Both levels are enforced on the server, on every request — not just in the interface. A member without permission for a tab cannot access that tab's data even with a direct API call.

8. Encryption from the browser to the database

Every "hop" of every request is encrypted — data never travels in plain text anywhere along the path:

  • Browser ↔ Vercel: HTTPS/TLS is mandatory; Vercel automatically obtains and renews certificates.
  • Frontend ↔ Backend: The Next.js server proxy communicates with AWS App Runner over HTTPS.
  • Backend ↔ MongoDB Atlas: The mongodb+srv:// format enforces TLS automatically.
  • Backend ↔ External partners (SendGrid, Google, Stripe…): All calls go over HTTPS using each provider's official SDK.

9. Passwords and sessions — stored safely, handled safely

Your password is never stored in our database in a form anyone could read. The same goes for login sessions:

  • Passwords: Hashed with bcrypt (via the passlib library) — a slow, salted algorithm designed to resist brute-force and rainbow-table attacks. Even a full copy of the database wouldn't expose passwords in a usable form.
  • Sessions: Not JWTs that a client can decode or forge. They are random, cryptographically secure tokens (32 bytes of random data) that only identify a row in our sessions database. The token itself carries no information.
  • Cookies: Set with httpOnly (inaccessible to JavaScript), secure in production (HTTPS only), and SameSite=Lax.
  • Logout takes effect immediately: Sessions expire automatically and are checked against the database on every request — logging out or an administrative session revocation takes effect immediately.

10. Conclusion: security is not a promise, it's an architecture

InPerson Platform's security isn't based on one magic solution, but on a set of deliberate architectural decisions: proven cloud providers with their own security teams, patterns that eliminate entire categories of attack (rather than just filtering them), and access control enforced on the server — not just in the interface.

The platform keeps evolving, and so does this document. Whenever the infrastructure or the security model changes, we'll update this overview.

Have questions about security? Get in touch — we're happy to address them specifically.