Privacy
Who holds what, and for how long
Written from what the code does rather than from a template — every entry below was read out of the file that implements it, and the file is named. It is deliberately specific in the places a policy is usually vague, because the vague places are the ones that matter.
Three sections, because there are three different answers to “who has this”. Read the one that applies to you; the boundaries between them are real.
Section 1
This website
We are responsible for this section.
There are no cookies, no analytics, no tracking scripts and no third-party requests of any kind — not as a policy we promise to keep, but as a description of what the pages load. The only thing this site ever asks you for is an email address for the Android beta, and only if you choose to give one.
Your email address
The one thing this site asks anybody for. It is stored so it can be pasted into the Google Play tester list, which is the only way Play accepts testers for a closed test. It is not mailed to — this site cannot send email at all — it is not sold, and it is used for nothing else.
How longUntil the beta ends, or until you askA removal erases the address itself rather than flagging the row: what is left behind is a date and the fact that a removal happened, which is what lets us answer “did you action my request” without keeping the thing you asked us to let go of.
The wording you agreed to, and when
The exact sentence beside the checkbox is stored with the row, along with the date. A record of consent that cannot reproduce the words somebody actually agreed to is not a record of consent, and the wording can change over time.
How longFor the life of the row
A one-way hash of your IP address — never the address
The form has to survive a script, and the cheapest defence is a limit per source. What is stored is a salted SHA-256 of the address, with the salt held in the server’s environment rather than in the database — so a copy of the file, on its own, cannot be turned back into a list of who signed up from where. Rate limiting works perfectly well against a hash. Identifying somebody does not.
How longWith the row; the rate-limit log is pruned after 48 hoursA removal blanks the hash along with the address. Separately, the record of attempts the limiter counts against prunes itself on every write.
Your browser’s user-agent string, truncated
The browser identifies itself on every request anyway; this one is kept beside the signup because it is the only signal that separates a person from a script after the fact. It is truncated, because the column is a signal rather than a transcript.
How longWith the row; blanked on removal
The web server’s access log
Ordinary reverse-proxy logging, the same as any web server keeps: the IP address the request came from, the path, the user agent and the time. It is read when something is broken or being attacked, and it is not aggregated, profiled or joined to anything else. Nobody analyses this traffic, because there is nothing here that would benefit from it (D9, D30).
How longShort-term operational retention, then rotated awayThe log belongs to the reverse proxy on the host rather than to this application, so it is the proxy’s rotation that governs it. The site is on DNS-only records: no CDN or edge provider terminates the connection, so this log is the whole of it.
Section 2
The Android app
We operate no server the app talks to.
This is the part that makes the app unusual, and it is worth reading rather than skimming. The app ships pointed at nothing: on first run it asks for the address of a Runic Gateway site and nothing else in the app works until one is entered and validated. That site is run by whoever runs that community. Everything you do in the app happens between your phone and their server, and there is no account with us, no service of ours in the middle, and no copy of anything on our side — because we do not operate one.
Your sign-in tokens
When you sign in to a deployment, the app keeps the access and refresh tokens it was issued, plus the username, role and account id they belong to. They are held in encrypted storage on the device (AES-256-GCM through Jetpack Security) and are sent to exactly one place: the deployment that issued them.
How longOn the device until you sign outSigning out clears them; uninstalling the app removes them with it.
The trusted-device token, if you asked for one
Ticking “trust this device” during two-factor sign-in stores an opaque token so the deployment can skip the second factor next time. It lives in its own encrypted store, deliberately separate from the session, because it has to outlive a sign-out to be worth anything — and the deployment holds only a hash of it, so the copy on your phone is the only usable one.
How longOn the device until it expires or you revoke itThirty days, and revocable at any time from the deployment’s Trusted Devices screen, which is also where it can be revoked if the phone is lost.
The address of the deployment you chose
The app ships pointed at nothing and asks for an address on first run. That address is stored in ordinary preferences rather than encrypted storage — it is not a secret, it is the equivalent of a bookmark — and it is what every other screen in the app talks to.
How longOn the device until you change it or uninstall
Push registration, if you turn notifications on
Push is off until you enable it. When you do, the app mints a random, unguessable topic name on the notification relay the deployment nominates, and registers that topic’s URL with the deployment so it has somewhere to send a nudge. What actually travels through the relay is content-free — a stream name and a reference, never the message — and the app then fetches the real content over its authenticated connection to the deployment. A leaked topic name therefore reveals nothing, which is the reason the relay needs no account and holds nothing about you.
How longUntil you turn push off, sign out, or uninstallSigning out or disabling push unregisters the device with the deployment and discards the topic. The relay retains whatever its own operator configures it to; if the deployment points at a relay it does not run, that relay is a third party to both of us, and it still only ever sees a tickle.
Everything you read and post in the app
Forum posts, Team activity, character and shard information, notification preferences: all of it is a live read or write against the deployment. Apart from the notification snapshot described in the next entry, nothing is cached for offline use and nothing is duplicated anywhere else — the app with no signal is an app with almost no content, which is a limitation and also an accurate description of where the data lives.
How longHeld by the deployment, under its operator’s policy
A snapshot of your notifications, so the inbox opens without a signal
The app keeps the most recent notifications it has already fetched — at most thirty, and only the first page — on the device, so opening the inbox shows you what you had rather than a spinner. It is a copy of what the deployment already sent you and it is refreshed from there; nothing is written here that was not read from your own account. It is scoped to the account that fetched it, so a second person signing in on the same phone is never shown the first one’s messages.
How longUntil you sign out, or the thirty are pushed out by newer onesSigning out deletes the snapshot outright. It lives in the app’s ordinary preference store rather than the encrypted one — sign-in tokens are the thing that store is for — which is worth stating plainly: on a device where someone has root, these are readable, and they are notification bodies rather than credentials.
No analytics, no crash reporting, no advertising
There is no third-party SDK in the app at all — no Firebase, no Crashlytics, no advertising identifier, no measurement library. That is checkable rather than claimed: it is what the dependency list and the manifest say, and a build that gained one would gain permissions with it.
How longNothing to retain
Section 3
Self-hosted deployments
The operator of that deployment is responsible, not us.
Runic Gateway is software people install on their own machines. If you play on a community that runs it, your account lives on their server, under their control and their policy — this page is not it. What follows is an inventory of what the software collects, so that an operator can see plainly what they are taking on, and a player can see what to ask their operator about.
Account records
A username, a password hash, an optional email address, the role, and — where the operator has enabled it — a two-factor secret and single-use recovery codes. The time and IP address of the last sign-in are stored on the account row.
How longSet by the operator; nothing expires on its own
Sessions, devices and revocations
Web sessions, mobile refresh tokens, trusted devices and the revocation list. A trusted-device row keeps a hash of the token, a device label, a truncated user agent and the times it was created and last used.
How longTrusted devices expire after 30 days; refresh tokens rotate
An audit log, with IP addresses on it
Administrative and security-relevant actions are logged with the acting account, what was done, and the IP address it came from. This is the record a moderator relies on, and it is also the most sensitive thing in the database.
How longKept until the operator removes it
Bot scoring and temporary IP bans
Scanner traffic and failed logins raise a score against the source address, and a high enough score bans it from the site for an hour. Worth stating precisely because it is better than it sounds: that score lives in memory in the running process, not in the database, and it decays after half an hour of quiet — a restart forgets every address it was watching.
How longIn memory only; scores decay, bans last an hour
Everything posted on the site
Forum threads and replies, uploads, wiki revisions, moderation actions, warnings, reports and appeals — with the account that made each one. Where the operator has connected Discord, some of that crosses into Discord and is then also subject to Discord’s own terms.
How longOperator-configured; some sweeps run on a retention windowSoft-deleted forum uploads and Team activity have retention windows an admin sets; most other content is kept until somebody removes it.
Notifications, and the record of what was sent
An operator can have the site notify people about things that happen on it — on the site, by email, by push — so an address is now used for more than getting into an account. Each member chooses this per notification and per channel, and email and push are both off until they ask for them. Alongside that the site keeps a delivery log: what fired, which account, which channel, whether it arrived, and a one-way hash of the address rather than the address. Addresses that bounce or are reported as spam go on a suppression list, which stores the same hash plus a masked form (`d***@example.com`, never the local part) so an operator can see what was suppressed without the list becoming a second address book.
How longThe delivery log is kept for a period the operator sets (180 days by default) and then swept; the suppression list does not expireA nightly sweep removes delivery-log entries, finished items from the send queue and the per-person rate-limit rows once they pass the horizon the operator has set for each — the defaults are 180 days for the log and 30 for the other two. Two things deliberately do not expire. An item still waiting to be sent is never swept however old it is, because it is a message the site still intends to deliver. And the suppression list is permanent by design: it records a standing decision to stop mailing an address, and ageing an entry out would mean mailing an address that already bounced or asked to be left alone. An operator can remove an entry from it deliberately, one at a time. Deleting an account detaches its rows from it rather than deleting them — a delivery history stops naming a person, and a suppressed address stays suppressed.
Who took part in a scheduled event
Where the operator runs scheduled events, a run can count who took part — kept as the name the game module knows a participant by, a score, and a rank, linked to a site account where one is linked and left unlinked where it is not. That is what the published results table renders, and what a signed-in person sees as their own event history. Beside it the site records what each run did: which step ran, what it created or borrowed in the game world, whether the undo succeeded, and which staff account started, paused or cancelled it.
How longA run's diagnostic log is swept after 90 days; the run itself and its participants are kept until the operator removes themThe log that answers "why did this run stall" is deleted 90 days after a run reaches a terminal state, and only then — a run still in flight keeps every line it has, however old, because the question it answers is still open. The run, its steps, what it created and its participant list are not swept: they are the record of what was done to a shared world, and deleting one silently would unmake an audit. Deleting an account detaches its participation rows rather than removing them — the result table keeps the score and stops naming a person.
Game data from the connected server
Where a game module is installed, information about characters, guilds, houses and the in-game economy flows from the game server to the site through the bridge. Which of it is visible to the public is the operator’s decision, made in the admin panel — the bridge itself forwards, and the site decides.
How longOperator-configured
Section 4
Removing your address, and asking questions
This applies to section 1 only — the beta list.
We hold one piece of information about you and it is the address you typed into the beta form. Ask for it to be removed and it will be erased rather than marked: what stays behind is a date and the fact that a removal happened, so we can confirm we did it without keeping the thing you asked us to let go of.
By email
Say which address to remove. There is no form to fill in and no account to prove — knowing the address is all that is needed, because it is all that is stored.
whitlocktech@gmail.comOn Discord
The same request works in the community Discord, which is generally the faster of the two.
Join the Discord
One consequence of erasing rather than flagging, stated because it is the honest reading and not a caveat we would rather you missed: afterwards the list cannot tell your address from one it has never seen. Asking twice gets the same answer as asking about a stranger, and signing up again later is an ordinary new signup.
Section 5
Changes to this page
If what the software collects changes, this page changes with it in the same release — the entries above are generated from a single inventory in the source, so a change to what is stored and a change to what this page says are the same edit. The date at the top is the last time that happened. This site sends no email at all, so there is no notification to send you when it does; the page itself is the record.