The short version
Mulno records playtests on a tester's own PC and, for a remote playtest, uploads the recording straight to storage — your own bucket (Private mode), or ours (Mulno Cloud), never both, and never to a third bucket. Our servers themselves hold no footage for a Private project unless you explicitly lend us a read key (below); every remote playtest still passes a small amount of metadata — invite codes, session state, byte counts — through our broker so codes can be checked and uploads authorised.
Two storage modes, one promise for each
- Private bucket (your own Amazon S3 or Cloudflare R2). Our servers sign short-lived upload and, if you ask, read URLs; apart from the setup check — which writes a small probe object and tries to read and list it, to prove the key can't — they never read, list or write an object themselves. The one documented exception: on Cloudflare R2, the narrowest available key also lists and reads the whole bucket (R2 has no write-only scope), so we hold a sealed, encrypted working copy of your key to keep signing uploads. You accept that specific risk, by name, before the first upload — see what we store.
- Mulno Cloud (our own Cloudflare R2, one sessions bucket and one builds bucket per region). We are the processor of what is stored there under the DPA: builds and testers' recordings.
- A lent read key (Private storage, opt-in per project, D105): with your explicit acknowledgement, our servers may read a Private project's session files to index them, show them in the browser, answer AI questions over MCP and decode frames for review. Without that acknowledgement, nothing about session content reaches us. Turning it off deletes what we derived.
How a signing key is protected in the browser
A reviewer's browser never holds a long-lived bucket credential in the page that plays back video and reads community-typed text. Credentials are handled by a dedicated signer origin (keys.<domain>, a same-site sibling of the app), never the app's own realm: the app asks the signer for a signed read of one object at a time, over a narrow, fixed message protocol (sign/status/forget, plus putNotes/listNotes for a reviewer's own notes file). A compromised app page cannot pull the credential out through a cross-site request, and the signer only ever signs reads under the one project's own prefix it was built for, and writes and listings of one session's notes file (a write authorisation lasts 60 seconds).
What is encrypted, and how
- Every connection to our servers uses TLS.
- A Private project's bucket credentials, and a lent read key, are encrypted (AES-256-GCM) under keys our servers hold outside the database, bound to that project or campaign. The broker's key rotates without downtime; the api's and the lent-key service's don't yet (after a change, the affected credentials are entered again).
- A campaign's own in-game configuration (consent text, surveys) is encrypted before it reaches us, with a key our servers don't hold; an NDA baked into a build stays in the build. An NDA a studio sets for the launcher to show before download is the exception, and so is the studio's privacy notice for its testers, a second readable text: we store each as readable text, because the launcher has to display them before anything is installed.
Access control
- Every route that reads or changes anyone's data needs a credential — an invite code, an upload ticket, a studio's own token, a signed-in session, a workspace invitation's one-time token, the token in a beta-waitlist e-mail's confirm or leave link, or a key shared only between our own services. The only open routes are the health check, sign-in itself (you give an e-mail address and get a link), joining the beta waitlist (the same: you give an e-mail address and get a link to confirm it), the public keys that verify our entitlement tokens, Paddle's billing webhook (which must carry Paddle's signature), the page Paddle's checkout opens on, a moment link's public preview (which says nothing about the game), the deletion-request form, and these legal pages. The deletion-request form takes only a session ID, which isn't a secret (moment links carry it), so it can never delete anything at once: for a Mulno Cloud session it hides the session and has Mulno's copy deleted 30 days later unless the studio restores it, and it answers the same whether or not the session exists.
- A studio's or workspace's queries are scoped to it: one workspace cannot read another's campaigns, projects or sessions (proven by tests on every workspace-scoped route).
- One page of the web app belongs to Mulno, not to a workspace: the beta waitlist, where we choose whom to let in. Only the accounts named in our server configuration (the owner's, today) can open it, and it shows only the waitlist.
- Each workspace's own audit log records sign-ins, member changes, storage and lent-key changes, and every read our servers make of a Private project's recordings under a lent key (D114), whether by the lent-key signer or a remote MCP client. Reads of a Mulno Cloud project's own storage (indexing its sessions, or answering its members) aren't logged one by one. Access by Mulno's own people outside the product (for example through Cloudflare's dashboard) isn't in that log; it is limited to the owner and made only on your documented instruction.
Minimisation
We design every route to hold the least it needs. For a Private project with no lent key, our database holds ids, states, byte counts, capture-health numbers and the names people type for projects, branches, builds and campaigns (D104) — never footage, events, positions, notes, the Catalog, or a key that can read your sessions. See what we store for the full, per-mode inventory.
Incident response
If we learn of a breach affecting your data, we tell you within 48 hours (D137), with what we then know: the nature of the breach, roughly how many records and of what kind, what we're doing about it, and a contact for more — early enough for your own 72-hour clock to your regulator (GDPR Art. 33; PDPA s.37(4)).
Third parties
See the subprocessor list — Cloudflare (our infrastructure) is our subprocessor of your testers' data; Google keeps our mailbox, which we use only for our own correspondence (requests about a playtest session come through the product, not by e-mail); Paddle handles billing as the seller of record, with your billing contact only; and a speech-to-text provider is used only under a studio's own account and only when a reviewer asks. We give 30 days' notice before adding or replacing a subprocessor that touches personal data processed on your behalf.
Assurance
- A security self-assessment in our own words, organised by the domains of the Cloud Security Alliance's Cloud Controls Matrix, is published: caiq-lite.md. It is not the CSA's CAIQ-Lite questionnaire itself, and not a CSA STAR entry (see that page's opening note).
- Security reviews. Every review of this product's security — the broker, the api, the signer, remote MCP's OAuth — is done at high rigor by Mulno's own AI review agent (Opus, highest reasoning effort) rather than an outside firm today (D122, D135); the review reports and their fixes are tracked before any public sign-up (D113, M3-plan exit criterion 10).
- No SOC 2 or ISO 27001 today. We start toward a certification only once a paying customer's own review requires a specific one (D113) — until then, a Private bucket lets your own security team check our policy directly, rather than take a certificate's word for it.
What isn't finished yet
Being direct about open work, rather than silent about it, matters more to us than a clean page:
- Region. A workspace can choose its data's Cloudflare region for its own rows (APAC, the EU's guaranteed jurisdiction, or US) — but a campaign's records at the broker (the campaign and its name, the workspace's own id, never its name (O6: the api sends the broker no name it doesn't need to), invite-code hashes, sessions and uploads, NDA acceptances, privacy-notice records, capture-health) still live in one Asia-Pacific database today, regardless of the workspace's chosen region, until the broker itself becomes regional. An EU-region workspace can't create a campaign at all today — the api refuses it outright, rather than asking you to weigh the trade-off, until the broker is regional.
- Representatives. Mulno is established in Thailand. No EU or UK representative (GDPR and UK GDPR Art. 27) is named yet. For now new Mulno accounts are offered only to studios in Thailand that we let in from our waitlist (or people invited into a workspace), and in any case accounts aren't offered to people in the EEA or the UK until both are named, and we name both before we open accounts there. For now our Terms also don't allow campaigns aimed at testers in Europe or Worldwide, and the product refuses those audiences. A campaign's audience is still only what the studio says it wants, and we don't check where a tester is, so not inviting testers in the EEA or the UK rests on the studio.
- An outside, human penetration test hasn't been done (D113); the AI review agent's reports are the assurance we can offer until a paying customer's contract requires one.
Contact
Report a security concern, or ask a question this page doesn't answer, at security@mulno.com.
Last updated 2026-10-08: the beta waitlist (its open routes, and the page only the owner can open); new accounts only from it. Before that, 2026-10-04: Mulno Cloud holds testers' recordings as well as builds; the product refuses campaigns aimed at Europe or Worldwide.