PHOENIX
A phoenix of flame wrapped around a colossal round iron vault door set in a dark cliff, one golden eye watching outward

Chapter four

Security

Phoenix holds the tie between your Discord account and your wallets, so it is built to give away as little as possible: it asks for little, keeps less, seals what it keeps, and makes bots pay at every door.

The first promise

What Phoenix never asks for

Your seed phrase, your private key, or an approval to spend, and it never sends your wallet a transaction to approve. Phoenix proves you hold a wallet with one signed message. If you would rather not connect your wallet, you can instead send a tiny amount from it to itself yourself, or put a code in its OpenSea bio: the coins never leave your wallet, and nothing ever goes to anyone else's address. Anyone asking for more is not Phoenix.

From Discord, Phoenix asks for two things only: who you are, and the list of servers you are in. It never asks to read your messages, join servers for you, or act as you. Linked Roles, if you turn it on, asks Discord for one more thing: to update what Discord shows about your Phoenix connection.

Your data at rest

Sealed on our own server

  • One encrypted file. Everything Phoenix keeps lives in one file on our own server, encrypted with AES-256-GCM under a key made from a secret that lives only in the server's settings. On disk, no name, Discord id or wallet address can be read.
  • Tamper shows. Every save is sealed with a fresh random number, and the seal covers the whole file. If even one byte is changed, or the key is wrong, Phoenix refuses to open it and stops rather than guess.
  • No Discord login token kept. Phoenix reads your name and server list once, then hands the Discord login token straight back to be cancelled. If you turn on Linked Roles, Phoenix keeps that one connection's token, sealed, until you turn it off.
  • No outside services. Phoenix's pages load nothing from anywhere else: no trackers, no analytics, no outside fonts or scripts. Holdings are read from the chains themselves, not from another verification service. The only other service Phoenix's server asks is OpenSea, and only to read a bio when someone proves a wallet that way.
  • Passkeys keep only a public key. A passkey's secret half never leaves your device; Phoenix keeps the public half, which can check a signature but never make one.
  • Short in the history. Wallets appear only shortened in your account's history.
  • Recovery codes kept only as fingerprints. Your authenticator's key is sealed in the file with everything else, and your ten recovery codes are kept only as one-way fingerprints (SHA-256), so not even the file holds them. Phoenix shows them to you once and never again.
Signing in

Sessions that cannot be borrowed

  • Two-factor on every account. Signing in with Discord is only the first step. Phoenix then asks for the six-digit code from your authenticator app (or a passkey you added), every time, for everyone, owners included, with no switch to turn it off. A stolen Discord login alone gets nobody in. Until the code is in, the sign in opens nothing but the code step, and it runs out after ten minutes.
  • A code works once, and guessing is slow. Each code is good for 30 seconds and only once, so a code seen over your shoulder is already spent. After five wrong codes Phoenix makes the next try wait, longer each time, and twenty wrong codes in a day stop that account's codes for up to a day: guessing a six-digit code at that pace would take decades.
  • A new authenticator signs out the rest. Moving two-factor to a new phone needs your current code (or a recovery code), and signs you out on every other device.
  • A cookie scripts cannot read. Your sign in is a long random code in a cookie marked HttpOnly and Secure, tied to this site alone.
  • It runs out. A sign in lasts at most twelve hours, and ends after two hours of not being used.
  • Every change is checked twice. Anything that changes your account needs a second secret code from the page and must come from Phoenix's own site, so another site cannot act for you while you are signed in.
  • A sign in finishes where it started. It has to come back to the same browser within ten minutes, so nobody can slip you into their account.
  • Discord's calls are proven. Every call from Discord to Phoenix's bot carries Discord's Ed25519 signature, and Phoenix refuses any that is unsigned, badly signed, or more than five minutes old.
Keeping bots out

A price at every door

  1. A puzzle before every link Built

    Before each wallet link, your browser solves a proof of work: it searches for a number that, mixed with a code from our server, gives a hash starting with 18 zero bits. One person waits a moment; a farm linking thousands of wallets pays for every single one. Each puzzle is tied to your sign in and works once.

  2. Messages that work once Built

    The message you sign is written by our server for you alone and is spent after one try or ten minutes, whichever comes first. A copied signature is worthless.

  3. Limits on how fast Built

    Sign ins are limited per place, and puzzles and links per Discord account. Going too fast gets a polite "wait a few minutes".

  4. A picture check and an account age gate Built

    Pressing Verify in a server starts a picture check drawn fresh for every try: five bent, tilted letters and digits to type, three tries, then a wait. A server can also turn away Discord accounts younger than it likes. A person gets through in seconds; a script that presses buttons does not. A very good picture reader could, which is why the real wall is the wallet proof and your two-factor.

Your control

Yours to take out or wipe

From your dashboard you can download everything Phoenix holds on you, sign out on every device, or delete your Phoenix account, which leaves nothing on you behind, not even your id in Phoenix's history. The member's guide shows where.

Watching the watchers

Admins on the record

  • Admins need two locks on Discord too. Phoenix's admins and owners must have Discord's own two-factor turned on as well as Phoenix's, or the admin panel stays shut to them. An admin who comes from Shadows of the Corn needs the game's two-factor on their game account too, so a stolen game password never makes anyone a Phoenix admin.
  • Every admin action is written down. Locking someone out, signing them out, unlinking a wallet, resetting someone's two-factor, adding or removing an admin: each goes on Phoenix's audit trail, and on the person's own history. So do two-factor being turned on, moved, a recovery code used, and new codes made.
  • Checked on every click. Whether someone is an admin is asked again on every request, never remembered. When Shadows of the Corn takes away someone's admin role, their Phoenix admin goes with it on their next click.
  • Nobody acts on an owner, and only an owner acts on an admin.
  • Counts, never names. Phoenix's admins have an Activity page that shows how Phoenix is used, day by day: sign ins, wallets linked, checks, roles given and taken. It holds numbers only, never a name, an id or an address.
Tested

Checked on every change

Phoenix has its own suite of automated checks, run on every change alongside the rest of Shadows of the Corn's security checks. Among them: the file on disk shows nothing readable, one changed byte locks it, a sign in cannot be forced from another browser, a Discord sign in alone opens nothing, a code works once and guessing is slowed, an admin without Discord's two-factor is turned away, every change needs its codes, a signature from the wrong wallet is refused, a used message cannot be used again, an admin cannot act on another admin, a chain that does not answer never takes a role away, a spreadsheet can never run a cell of a holder snapshot, a cloned passkey is refused, and Phoenix changes no role and posts nothing in a server until both its switches are on.

Staying safe

How to spot a fake

  • It asks for your seed phrase, a private key, or to "connect and approve".
  • Your wallet shows a spending approval, or a transaction you did not start yourself, instead of a plain message. A send to itself goes only to the same address it comes from.
  • The address bar is not Phoenix's. Today Phoenix lives at phoenixcheck.net/phoenix/.
  • The message you are asked to sign names a different site, or does not name your Discord account.
  • Someone sent you a direct message with a link to verify. Phoenix does not do that.
  • Someone asks you for your six-digit code or a recovery code. Phoenix's admins never do; you type them only on Phoenix's own sign in page.

If you see any of these, close the page and tell the people who run your server.