Security

Security at RowFold

Your operations live in here. This page describes how that data is protected, in enough detail to be checked — including the things we have not built yet.

Last updated · July 29, 2026 · Report a vulnerability · security@rowfold.com

01Principles

Plain English: security controls are part of every account, not a feature of an expensive tier. There is no plan on which your data is protected less.

Three ideas shape everything below.

  • A permission is only real if it holds everywhere. A field you hide must stay hidden when it is pulled through a relation, summed into a report, matched by search, or read by AI. A rule that applies only to the grid is not a rule.
  • Isolating access should not mean severing data. Products in this category typically isolate by splitting information into separate bases or boards, which breaks every relationship across the split. RowFold isolates access with folders and permissions and leaves the model intact.
  • Deleting should be recoverable. Records are soft-deleted so an accident is a visit to Trash rather than a support ticket.

02Signing in

ControlHow it works
Password storagePBKDF2 with HMAC-SHA256, 100,000 iterations, a unique random salt per user, and a 32-byte derived key. Passwords are never stored or logged in a recoverable form.
Two-factor authenticationTime-based one-time codes (TOTP, RFC 6238) from any authenticator app, plus single-use recovery codes that are themselves stored hashed.
Single sign-onGoogle and Microsoft. Only addresses the provider has verified are accepted, so an unverified email cannot open an account.
SSO account linkingA signed-in provider account links on the provider's own immutable subject identifier, never on the email address — so a reassigned or spoofed address cannot inherit an existing RowFold account.
Secrets at restTwo-factor seeds and connected-app OAuth tokens are encrypted in the database, not merely stored in it. A dump of the tables does not yield working authenticator secrets or usable third-party tokens.
Session cookiesHttpOnly and SameSite-restricted, marked secure, and served over HTTPS with HSTS in production.
Brute-force resistanceTwo layers. Authentication endpoints are rate-limited per source address, and each account separately counts consecutive failures, locking for 15 minutes after 10. The per-account counter is the one that matters against credential stuffing, where attempts arrive from many addresses at once.
Enforced two-factorThe owner of a workspace can require two-factor of everyone in it. People without it are sent to set it up before they can continue, and the requirement applies to members invited later.

03Sessions & alerts

A sign-in lasts 30 days per device. That is a long time for a stolen cookie to stay useful, so two things bound it.

  • Sign out everywhere. One action ends every session on every device, immediately, including the one you are using. Changing a password by reset does the same automatically — otherwise resetting a stolen password would leave the thief's existing session working for the rest of its life, which is the opposite of what someone resetting a password believes they are doing.
  • Alerts you can act on. We email you when a sign-in arrives from a device the account has not used before, and when a security setting changes — password, two-factor turned on or off, recovery codes regenerated, or all sessions ended. Turning two-factor off is the first thing an attacker with a live session does, and it is silent otherwise.
What our security emails never contain: a link that performs an action. No "wasn't me — click to undo". A security alert is the single most impersonated kind of email there is, and training you to click buttons inside one would be building the phishing lure ourselves. Every message points at your account settings and asks you to act there, where you can see you are on the real site.

Devices are recognised by a long-lived cookie rather than by IP address or browser fingerprint. Those change constantly for ordinary people — a phone moving between wifi and mobile data, a browser updating — and an alert that fires on every commute is one that gets filtered within a fortnight. Clearing your cookies looks like a new device, which is the safe direction to be wrong in.

04Permissions

Access is decided at three levels, each able to override the one above it.

  • Workspace role — viewer, contributor, editor, or admin, setting the default for everything inside.
  • Table access — per person and per table: full, read and create, read only, or no access at all. "No access" removes the table from view entirely rather than showing a locked door.
  • Field access — per person and per field: read-only, or hidden.
The part that matters: a hidden field stays hidden on every path out of the database. It does not reappear through a lookup or rollup on another table, in a report column or aggregate, in ⌘K search results, or in an AI answer. Permissions are resolved once, server-side, and every one of those surfaces reads the same resolved view.

Folder-level access grants or removes a whole group of tables in one action, and a folder someone cannot see is absent rather than greyed out — its name does not appear. Because this is an access rule rather than a copy of the data, relationships across the boundary keep working for the people who are allowed to follow them.

05Encryption, hosting & the browser

RowFold runs on Microsoft Azure in the United States. Traffic is encrypted in transit with TLS, HTTP requests are redirected to HTTPS, and production sends HSTS. The database is Azure Database for PostgreSQL with encryption at rest; file storage is Azure Blob Storage, also encrypted at rest.

Requests that change state carry an antiforgery token that is validated server-side, and the application is rate-limited by endpoint class rather than globally, so a burst against one surface cannot exhaust another.

Every response also carries browser-level hardening: X-Content-Type-Options: nosniff so an uploaded file cannot be sniffed into executable script; a referrer policy that stops workspace, table and record ids leaking in the Referer of outbound clicks; a permissions policy denying geolocation, camera, microphone and payment outright, since nothing here asks for them; and a content-security policy setting object-src 'none', base-uri 'self' and form-action 'self'. Signed-in pages refuse to be framed at all; only the surfaces designed to be embedded on your own site — public forms and the chat widget — are framable, and a widget that names its allowed sites is restricted to them.

Where that policy stops, and why: the content-security policy does not yet restrict script sources. Doing that properly means threading a nonce through every page rather than adding a header, and a policy with 'unsafe-inline' in it would be decoration — it would pass a scanner while blocking nothing. It is on the list as real work, not as a header we forgot.

06Files & attachments

Uploaded files are never written to a publicly served directory. They go to blob storage (or, in local development, to a directory outside the web root), and the only way to read one back is through an endpoint that checks your permission on the owning record first. A file's URL is not a capability: knowing it does not grant access to it.

Attachment metadata is also excluded from every text-based write path in the product — imports, the API, AI edits, and grid pastes cannot construct or alter it. That closes the route by which a crafted value could otherwise be made to point at another account's stored file.

07Public surfaces

Three things answer without a login, each reachable only through an unguessable token rather than by knowing an id: public forms, form file uploads, and inbound email addressed to a workspace mailbox.

Public forms are treated as hostile input by default. Submissions are rate-limited per address, carry a honeypot and an antiforgery token, and — the important part — the server re-validates which fields are eligible and which were conditionally visible. The browser's account of what the form contained is never trusted, so a modified page cannot write to a field the form did not offer. File uploads hand the browser opaque identifiers only; every piece of file metadata is read back server-side at submission, and uploads that are never submitted are swept automatically.

08The API

The public API authenticates with OAuth 2.0 client credentials: a client id and secret are exchanged for a bearer token that expires after an hour. Secrets are shown once at creation and stored hashed, so a leaked database does not yield usable credentials. Requests are rate-limited per credential, and anonymous requests are held to a much lower ceiling than authenticated ones. API access is subject to exactly the same permission resolution as the UI — a token cannot read a field its owner cannot read.

09Deleting & recovering

Deleting a record marks it deleted and moves it to Trash rather than destroying it, so mistakes are reversible by the person who made them. Record changes are captured as events, giving an audit trail of what changed and when. Account deletion and export are covered by the Privacy Policy, including how long content persists in backups.

10What we don't have yet

Read this section first if you are evaluating us for a regulated environment. Everything above ships today. Everything here does not, and we would rather you learn it from us than discover it during procurement.
  • No SOC 2 or ISO 27001 report. We have not completed an audit against either framework. If your procurement process requires one, we are not yet a fit.
  • No third-party penetration test. The application has been reviewed internally and adversarially, but not by an external firm, and we will publish the summary when that changes.
  • No bug bounty programme. We publish a disclosure policy with safe-harbour terms and act on reports (see below), but we do not currently pay for them.
  • No script-source restriction in the content-security policy. Described in section 05 — real work rather than a missing header.
  • No customer-managed encryption keys, and no choice of data region. Everything runs in the United States.
  • No HIPAA, FedRAMP, or similar regime. Do not put regulated health or government data in RowFold.
  • No contractual uptime guarantee. We do not offer an SLA today.

11Reporting a vulnerability

If you believe you have found a security issue, email security@rowfold.com with enough detail to reproduce it. We aim to acknowledge within two business days and to tell you what we intend to do about it, and how quickly, within ten. The same address is published in machine-readable form at /.well-known/security.txt (RFC 9116).

Safe harbour. We will not pursue or support legal action against anyone who reports an issue in good faith, provided you give us a reasonable chance to fix it before disclosing publicly, do not access, modify, or retain data belonging to anyone but yourself, and do not degrade the service for others. Testing against your own account and workspaces is explicitly welcome. If you are unsure whether something is in scope, ask first — we would rather answer the question than have you guess.

Please do not use automated scanners against the production service without telling us; the traffic is indistinguishable from an attack and will simply be rate-limited.

12Contact

Security reports and questions: security@rowfold.com. Privacy and data-subject requests: privacy@rowfold.com. Postal: RowFold Inc., 14 Cedar Ave, Suite 200, Portland, OR 97214, USA.

Related: Privacy Policy · Terms of Service