This policy explains how Sway SRL handles personal data in openshield. It follows articles 13 and 14 of the General Data Protection Regulation (GDPR).
Who is responsible
Sway SRL, Clos des Colombes 23, 1342 Limelette, Belgium (enterprise number BE1037531992) is the data controller for the data described in "Data we handle as controller". Write to contact@sway.events for any question about personal data. The legal notice of the terms gives the company's VAT number, register and hosting.
For the images and texts, and the fraud prevention events, that our customers send to the API, Sway SRL is a processor acting on the customer's instructions. See "Content our customers send us".
Content our customers send us
A customer sends images and texts to the API to have them moderated. The customer decides what is sent and is the controller of that content. We process it only to return the moderation result, under the data processing agreement.
- Content is checked in memory and forgotten when the answer is sent. We keep no copy, no thumbnail, no excerpt and no hash of it, in logs or anywhere else.
- Once an organization has topped up its balance, the advanced reading sends a text that the first check sends to review, cut to 4,000 characters and with the
contextsent with it, to TypeSafe AI, Inc. (United States), whose decision model answers with probabilities. Images, and the texts of an organization that has never topped up, are never sent. TypeSafe AI processes it as our sub-processor in the United States, under the standard contractual clauses of its data processing agreement. It states that it does not train its models on what it receives, and its agreement lets it keep that data as long as needed to provide its service. The texts and contexts it receives are therefore not covered by "forgotten when the answer is sent". - We do not use content to train models.
- The decision journal keeps the result of each check, never the content itself. A customer may attach a short reference of its own choosing to a check (the
reffield), which is kept in the journal. Customers should not put personal data in it.
Fraud prevention
A customer that turns fraud prevention on sends events about its own users to the API: a sign-up, a login, a payment, a message. The customer decides what an event holds and is its controller; we process it under the data processing agreement, only to return the customer's decision and run its rules.
- Each customer's events are kept in an instance of its own, on our servers in Germany, never mixed with another customer's.
- The customer sends the context of its end users: IP address,
User-Agent, language, country, device identifier and attributes. The customer must not put special categories of personal data in the attributes. - An email address, a phone number, an IP address and a device identifier are replaced by keyed pseudonyms before any rule sees them, and the raw values are not stored. A browser's
User-Agentis read for the browser, the system and signs of automation, then dropped. - From the IP address we add network data: the operator and country (IPtoASN dataset), and whether it is a Tor exit, a VPN or a data centre. We also check whether an email domain is disposable. The lists are mirrored daily on our server, and the instances reach nothing outside it.
- Events, decisions and cases are kept 30 days until the customer first tops up its balance and 90 days after, then deleted from the instance (the encrypted backups follow within 30 days, see below). A customer can export or erase what is kept about one person at any time, through
/fraud/v1/subjects/{id}/exportandDELETE /fraud/v1/subjects/{id}. - Nothing of it is sent to a third party except the sub-processors listed below, and it is not used to train models.
- Webhooks of an instance are checked by our gateway, signed again with the customer's own secret and delivered by a Cloudflare Worker to the https address the customer set.
- Rules other than the core blocklists start in shadow. By default, a shadow rule starts acting automatically once at least 30 days of history exist and it is reliable. For that, our decision model, provided by TypeSafe AI, reviews pseudonymized timelines of up to 10 accounts the rule hit. It sees event types, times, the pseudonymized email, the IP network prefix and lists, the country, the decisions and the rule ids, never a raw email address or IP address. It answers a probability and keeps nothing.
If a customer's fraud prevention made a decision about you, that customer is the one to ask: openfraud keeps a statement of the reasons for each decision, and the customer can show it to you and review it.
If you appear in content or events that one of our customers sent, that customer is the one to ask. We help the customer answer you.
Data we handle as controller
| Data | Why | Legal basis (GDPR article 6) | How long |
|---|---|---|---|
| Account: email address, name if you give one, password (kept only as a hash), sign-in method, two-factor secret | To create your account, sign you in and protect it | Contract (6.1.b) | While the account exists |
| Acceptance records: for each document you accept (the terms and the privacy policy when you create an account; the terms and the data processing agreement when an owner first tops up a balance; the acceptable use rules are a section of the terms, and records of the acceptable use policy from when it was a separate document are kept too), your user id, the organization for a top-up, the document and its version, the date and time, and the full IP address you used. Deleting an account or an organization does not delete these records: they are our proof of what was accepted | To prove what you accepted and when | Contract (6.1.b) and legal obligation (6.1.c) | The duration of the contract plus 10 years, in line with Belgian accounting and tax law |
Abuse checks: when you create an account, sign in or type a wrong password, create an API key, use Try it, or pay, what happened goes to our own fraud prevention (our openfraud instance, on our servers in Germany, separate from the one any customer uses): your user id, your organization's id, your email address, the IP address, the browser's User-Agent and language, the country Cloudflare reports, and for a payment its amount. The email and IP address are replaced by keyed pseudonyms, the User-Agent is read then dropped. It never refuses a sign-up or a sign-in. When it flags an account, the free monthly use of the organizations the account owns is paused (no free euros, no Try it) until one top-up or until we review it; paid use works as before |
To spot accounts made in bulk, or used, to abuse the free use | Legitimate interest in preventing fraud (6.1.f) | Events: 365 days, so that a pattern that returns after months is still seen. A pause: until it is lifted |
| Sessions: the IP address and the browser of each device signed in, and when | To show you where you are signed in and to protect the account | Legitimate interest in security (6.1.f) | Until the session expires, 7 days after your last activity, or until you sign out |
| Organization: name, members and their roles, invitations, balance and its history, request limits tier, automatic top-up and alert settings | To run the service for your team | Contract (6.1.b) | While the organization exists |
| API keys: name, scopes, creation and last use. The key itself is kept only as a hash | To authenticate calls to the API | Contract (6.1.b) | Until the organization is deleted |
| Billing: customer, payment and subscription records at Stripe, invoices, billing address and VAT number if you give them. If you turn on automatic top-ups, Stripe keeps your card so that we can charge it the amounts you set; we keep only a reference to it, never the card number. Card data stays with Stripe | To bill you, collect payment and meet accounting and tax duties | Contract (6.1.b) and legal obligation (6.1.c) | 10 years, as Belgian accounting law requires (article III.86 of the Code of Economic Law) |
| Usage counters: checks per hour, key, workflow and kind. No content | Quotas, billing and usage charts | Contract (6.1.b) | While the organization exists |
| Decision journal: for each check, the time, request id, key, kind, workflow and version, decision, reasons with scores and thresholds, duration, size and your reference. Never the content, never the IP address or browser of the customer's users | The journal feature, support and proof of what the service answered | Contract (6.1.b) and legitimate interest in service records (6.1.f) | 7 days until the organization first tops up, 30 days after |
| Audit log: who did what in the dashboard (action, target, time) with the network prefix of the IP address (the first 24 bits of an IPv4 address, the first 48 bits of an IPv6 address, never the full address) | Accountability and security | Legitimate interest in security (6.1.f) | While the organization exists |
| AI agents (MCP server): for each agent you connect, the agent's name and the address of its metadata or its registration (redirect addresses), what you allowed and when, and its access and refresh tokens, kept only as hashes. For each tool call an agent makes, the time, the tool, who made it (your user id and the agent, or the API key), the outcome and its duration. Never what the agent sent or received | To let your agents act for you, show you what they did, and stop them | Contract (6.1.b) and legitimate interest in security (6.1.f) | Connections: until you or an owner or admin disconnect the agent, or the organization is deleted; tokens: until they expire (10 minutes, 30 days for a refresh token). Calls: 90 days |
| Abuse prevention: rate-limit counters (a keyed hash of your IP address, the route and the start of the time window, never the address itself) kept in our database, and the signals Turnstile uses to tell a person from a bot (processed by Cloudflare) | To keep the service available and protect forms from abuse | Legitimate interest in security (6.1.f) | Our counters: deleted a day after their window began (a minute at most). Turnstile's: as long as Cloudflare's own settings keep them, then deleted |
| Network data (opt-in): for customers who turn it on, pseudonyms of an IP network (/24 or /48) and of a device, a registered email domain that is not a free mailbox provider, and a network operator, taken from accounts the customer labelled fraud or legitimate, and combined across customers into lists that give only a value and a tier (no count, no customer) | To spot networks, devices and email domains that several customers saw behind fraud, and to give them back to the customers that share theirs | Legitimate interest in preventing fraud (6.1.f, recital 47). Balancing test, in short: the purpose is real and narrow (account farms, stolen cards, credential stuffing), only a pseudonym or a public domain and a label are used, never a raw identifier, an account or an event; a value is published only when 3 customers and 10 accounts agree, with at least 80 % fraud and none above half; nothing identifies a person or a customer; it is opt-in for customers and ends with 90 days of silence; a person may object at contact@sway.events. We get the labels from our customers, not from you; each customer that shares says so in its own privacy policy, and we answer your requests about the combined lists, whatever our role is held to be towards that customer (the essence of our arrangement with them is available at the same address) | Entries: deleted when no nightly run has confirmed them for 90 days; a customer's contribution leaves at the next run after it opts out |
| Messages: the emails you send to contact@sway.events, and the transactional emails we send you (verification, sign-in link, invitation, billing and security notices) | To answer you and to run your account | Contract (6.1.b) and legitimate interest (6.1.f) | As long as needed to answer you and keep a record of the exchange |
| Contact form: the name, email address, company (if you give one), topic, message and country (from your connection) you send through the contact page. They go by email to our support mailbox and nowhere else; we send nothing back unless a person answers you | To answer you | Legitimate interest in answering the people who write to us, or steps at your request before a contract (6.1.f or 6.1.b) | Until the exchange ends, then at most 12 months. Cloudflare sends the email and Turnstile checks the form, as listed under sub-processors |
| Analytics (only if you accept them): on the public pages, the pages you view, the links and buttons you click, your browser, device type, language and approximate location (country and city, from your IP address, which is not kept), the page that sent you, and a masked recording of the page (what moved on screen, never what you type, which is hidden before it leaves your browser). A random identifier ties your visits together. Addresses lose their query string, and any key, credential or email address is cut out before an event leaves your browser. Nothing is captured in the dashboard or on the sign-in pages | To understand how the public pages are used and to improve them | Consent (6.1.a), given in the cookie preferences bar and withdrawn there at any time | Events: 1 year. Recordings: 30 days. Withdrawing your consent deletes the identifier from your browser at once |
Copies of the databases are kept as backups for 30 days, in Cloudflare's EU jurisdiction, to restore the service after an incident; they are then deleted. The same holds for the fraud instances on our server in Germany: every night a copy of their databases and of the server's configuration is encrypted before it leaves the server, and stored for 30 days in Cloudflare's EU jurisdiction. A deletion, and the end of a retention period, therefore reach the backups within 30 days.
We use analytics only if you accept them, and never advertising trackers or profiling. The "Cookies" section below lists what your browser stores.
Who receives it
- Our sub-processors, who help us run the service and are bound by data protection terms: Cloudflare (hosting, databases, file storage, email, bot protection), Hetzner (the checking server, and the fraud instances), TypeSafe AI (the advanced reading of texts, once an organization has topped up, and the review of fraud rules), proxycheck.io (whether an IP address is a VPN, a proxy or a Tor exit, once an organization turns the VPN and proxy facts on) and Stripe (payments and tax). The list of sub-processors, in the annex of the data processing agreement, says what each one does and where.
- PostHog, Inc., our processor for the analytics of the public pages, for visitors who accept them. It handles no data of our customers, so the data processing agreement does not list it.
- Authorities, when the law requires us to hand data over.
We do not sell personal data.
If you choose to sign in with GitHub or Google, that provider tells us your email address and name and learns that you signed in to openshield. It acts as an independent controller under its own privacy policy.
What each sub-processor sees
- Content (images and texts) sent to the API passes through Cloudflare, which delivers the request, and is checked in memory on the Hetzner server. We do not store it anywhere.
- Once an organization has topped up, a text sent to review is also sent, cut to 4,000 characters and with its
context, to TypeSafe AI in the United States. TypeSafe AI states that it does not train its models on it; its data processing agreement lets it keep it as long as needed to provide its service. - Fraud prevention events and decisions pass through Cloudflare, which relays the fraud API calls and delivers the re-signed webhooks. They are stored, pseudonymized, in the customer's own instance on the Hetzner server in Germany, for 30 days until the customer first tops up and 90 days after.
- Fraud rule review: TypeSafe AI, in the United States, receives pseudonymized timelines of up to 10 accounts a rule hit (event types, times, pseudonymized email, IP network prefix and lists, country, decisions and rule ids), never a raw email address or IP address. It answers a probability and keeps nothing.
- VPN and proxy facts: once an organization turns them on, the IP address of each fraud event it sends (and nothing else of the event) goes to proxycheck.io, which answers whether the address is a VPN, a proxy or a Tor exit, the kind of line it sits on, who runs it and when it was last seen. proxycheck.io says that a query made from Europe is handled on its servers in Europe, that it stores the address a query comes from (our server's) for at most 24 hours, and that it keeps a positive detection of a looked-up address for up to a year after our last use of its service. The answer is kept for 24 hours in the memory of our server, never stored.
- Account, organization and usage data is stored in Cloudflare's databases in the European Union.
- Payment data is handled by Stripe. We never see a card number.
- Error reports say what failed in our code or in a page of the site, never with the content checked, an API key, a cookie or a request body. A report from your browser carries only the error, the page's path, and your browser and system with their versions, never your IP address, which is not kept. They go to a server of ours at Hetzner in Germany.
- Analytics, for visitors who accept them, reach PostHog through openshield.dev's own address, which keeps your session cookie and passes on only your IP address, your browser and your language. PostHog stores them in its EU cloud, in Frankfurt, Germany.
Transfers outside the European Union
Account, organization, usage and journal data is stored in the European Union: the databases and the file storage are created in Cloudflare's EU jurisdiction. The checking server and the fraud instances, with their events, decisions and cases, are on our server at Hetzner in Germany, in the European Union.
The website, the dashboard and the front door of the API are delivered through Cloudflare's global network, and a request is handled in the Cloudflare location closest to the visitor. That location can be outside the European Union, because Cloudflare reserves regional pinning of this layer for its enterprise plans.
Cloudflare, Inc., Stripe and PostHog, Inc. are United States companies; the analytics are stored in PostHog's EU cloud, in Germany, and any access to them from outside the European Union relies on the standard contractual clauses of PostHog's data processing agreement. TypeSafe AI, Inc. is one too, and handles in the United States the texts of the advanced reading and the pseudonymized timelines of the fraud rule review, described in "Content our customers send us"; that transfer relies on the standard contractual clauses of its data processing agreement. The transfers to them rely on the EU-U.S. Data Privacy Framework, to which each of them says it is certified, with the standard contractual clauses of their data processing terms as the fallback if the certification lapses. Write to us for a copy of these safeguards.
Your rights
You can ask us, free of charge, for:
- access to the data we hold about you, and a copy;
- correction of data that is wrong;
- erasure of your data;
- a limit on how we use it;
- your data in a portable format;
- to stop a use that rests on our legitimate interest (the right to object).
Write to contact@sway.events. We may ask you to prove who you are. We answer within one month, as article 12 of the GDPR sets. An organization's owners can also export their workflows, journal and usage from the dashboard at any time, and the fraud data kept about one person through the fraud API.
For account data that sits in an organization, the organization's owners may also act on it.
Complaints
If you think we handle your data unlawfully, write to us first so we can put it right. You may also complain to the Belgian data protection authority, the Autorité de protection des données (in Dutch, Gegevensbeschermingsautoriteit), Rue de la Presse 35, 1000 Brussels, contact@apd-gba.be. Its website is autoriteprotectiondonnees.be (French) and gegevensbeschermingsautoriteit.be (Dutch). You may also complain to the authority of the country where you live or work.
Automated decisions
We take no decision about you that rests only on automated processing and has legal or similarly significant effects (article 22 of the GDPR). Our own abuse checks never refuse a sign-up or a sign-in. When they pause an account's free use, the billing page says so, one top-up gives it back at once, and you can ask us to review the pause at support@openshield.dev: a person looks at it. openshield returns a moderation result, and with fraud prevention a fraud decision, to our customers. The decisions about content and about people are theirs. Under article 22 of the GDPR, a customer must offer human review before such a decision relies only on automated processing, and a way to contest it. openfraud provides a statement of reasons and an appeal route for that.
Security
Connections are encrypted. Passwords and API keys are stored as hashes. Account owners must turn on two-factor authentication before topping up a balance. The systems that make up the service talk to each other through signed requests. Fraud prevention uses keyed pseudonyms for email addresses and IP addresses, and one isolated instance per organization, with its own derived key and admin token, on an internal network with no internet access.
If a personal data breach concerns data we hold as controller and is likely to put you at risk, we notify the Autorité de protection des données within 72 hours of becoming aware of it, and we tell you without undue delay when the risk to you is high. For data we hold as processor, the data processing agreement applies.
Cookies
openshield uses what the service needs to work, what you ask for by using a control, and analytics only if you accept them. There is no advertising. Cookies that are strictly necessary need no consent under Belgian and European rules; the analytics ones do, and are set only after you accept them.
A visitor who only reads the public pages, and does not accept analytics, receives no cookie at all.
What is stored
| Name | What it is for | When it is set | How long |
|---|---|---|---|
better-auth.session_token (on the production site, with the prefix __Secure-) |
Keeps you signed in. Not readable by scripts. | When you sign in | Up to 7 days |
better-auth.two_factor (same prefix rule) |
Remembers that your password was accepted while you enter your two-factor code | During sign-in, for accounts with two-factor authentication | A few minutes |
better-auth.state (same prefix rule) |
Protects a sign-in with GitHub or Google against forgery | While you sign in with GitHub or Google | A few minutes |
om-theme |
Remembers the light or dark theme you chose in the dashboard | When you use the theme control | 1 year |
admin-sidebar-mode |
Remembers how you set the dashboard's side menu | When you change that setting | 1 year |
ph_<project>_posthog (a cookie, and the same name in local storage) |
Analytics: the random identifier that ties your visits together, and the current session | Only after you accept analytics | 1 year, or until you withdraw your consent |
The three sign-in cookies are strictly necessary. The two preference cookies store a choice you made, hold no identifier and are never sent to anyone else: we treat them as necessary to provide the setting you asked for. The analytics entries need your consent: the PostHog library is not even loaded before you give it.
Your cookie choice
The public pages show a cookie preferences bar until you make a choice: accept all, reject non-essential, or open the preferences and choose by category. The essential category is always on. The analytics category is off unless you switch it on. It covers PostHog, described above, and nothing else. Rejecting it, or switching it off later, stops the analytics and deletes their identifier from your browser.
Your choice is one entry in your browser's local storage, named om-cookie-choice. It holds the categories you accepted, the date and a version number, and it never leaves your browser. It expires after 6 months, when the bar asks again. The "Cookie preferences" link in the footer of every public page opens the bar again, so you can change your mind at any time.
Browser storage of the bot check
The sign-up, sign-in, password reset and magic link forms, and the Try it console, use Cloudflare Turnstile to tell a person from a bot. When the check runs, Turnstile stores one entry in your browser's local storage, under the Cloudflare domain challenges.cloudflare.com (cf.turnstile.u). Cloudflare states that the signals Turnstile uses are strictly necessary to detect and block bots, and does not use them to identify or profile people. See Cloudflare's Turnstile privacy addendum.
Controlling them
You can delete these cookies and this storage in your browser's settings at any time. Without the session cookie you are signed out. Without the others, the dashboard falls back to its defaults, and the cookie preferences bar asks again.
Changes
The version date is at the top of this page. When a change matters to you, we tell the owners of each organization by email before it takes effect.