THESIS docs
v1.1.0
Live demo Get help
● Ship · Secrets at rest

Secrets and backups
what is encrypted, and how to recover.

What ADMIN_SECRET_KEY protects, what happens if you lose or change it, how to recover, and what to back up on a Node server or on Vercel with Postgres.

01What ADMIN_SECRET_KEY encrypts

Which terminal

The commands on this page are written for the shell of macOS and Linux (bash or zsh). On Windows, run them in WSL (Windows Subsystem for Linux, Ubuntu) or Git Bash: commands such as cp, openssl, set -a && . ./.env and multi-line curl with \ do not work as written in PowerShell or cmd. The node and pnpm commands work in any of them.

ADMIN_SECRET_KEY is a 32-byte key (64 hex characters, or base64) that you set in the environment. It is never stored in the database. The Admin Kit uses it to encrypt the secrets you save in the console before they reach storage (packages/admin-kit/server/crypto.ts):

Stored valueHow it is protected
Anthropic API key saved under IntegrationsEncrypted: AES-256-GCM, a fresh random 12-byte IV for every save, the setting's name bound as associated data (a ciphertext cannot be moved to another field). Write-only in the console: it can be replaced or tested, never read back.
Webhook signing secret (Notifications)Encrypted the same way.
Each member's two-factor (authenticator) secretEncrypted the same way.
PasswordsNot encrypted but hashed with scrypt and a per-user salt. They do not depend on ADMIN_SECRET_KEY.
Sign-in sessions, setup codes, two-factor recovery codesOnly a SHA-256 hash is stored; ADMIN_SETUP_TOKEN is compared by its SHA-256 hash in constant time and is never stored. They do not depend on ADMIN_SECRET_KEY.
Pro plan sign-in cookies (users' browsers)Signed with a key derived from ADMIN_SECRET_KEY (server/app.ts); nothing is stored on the server.
Ordinary settings, including the builder and pay-to addressesStored as plain values; addresses are masked in the console, the audit log and history. Only the owner can reveal one.

An ANTHROPIC_API_KEY set in the environment is not stored at all; it stays in your host's environment settings.

Encrypted rows live in the secrets table (SQLite file) or mk_admin_secrets (Postgres), as ciphertext, IV and tag. Someone who copies the database without the key cannot read them.

02If the key is lost or changed

The server still starts, and these keep working: the owner and team accounts and passwords, open admin sessions, every ordinary setting, the audit log and history.

What stops working, and what the server log says:

AffectedLog line or symptomFix
Anthropic key saved in the console[admin] secret "integrations.anthropicApiKey" cannot be decrypted: was the secretKey changed? AI chart reading turns off; Status → Anthropic API key accepted fails.Owner: Integrations → paste the key again → Save changes → Test connection. Or set ANTHROPIC_API_KEY on the server.
Webhook signing secret[admin] secret "notify.webhookSecret" cannot be decrypted: … when an alert is sent.Owner: Notifications → enter the secret again (and the same secret on the receiving side).
Two-factor sign-in[admin] two-factor secret of <email> cannot be decrypted: was the secretKey changed? The authenticator code is refused.Sign in with one of your recovery codes (they are hashed, not encrypted, so they still work). Then in Security & alerts turn two-factor off (password plus a recovery code) and set it up again. If two-factor is required for your role, the owner turns that requirement off first. A team member without recovery codes: the owner removes them under Team and adds them again.
Pro plan usersThey appear signed out.Nothing to do: they sign in again with their wallet. Their plan is read from your address's Hyperliquid ledger, so no payment is lost.
No way to read old secrets without the old key

There is no master key and no recovery service. If the old key is gone, the encrypted values are gone; you enter them again. Put the old value back (if you still have it) to read them.

The two-factor recovery path above is implemented in packages/admin-kit/server/kit.ts.

03Changing the key on purpose

  1. PrepareHave the Anthropic key and the webhook secret at hand (from your Anthropic account and the receiving system; the console cannot show them). Make sure everyone with two-factor has recovery codes, or turns two-factor off first.
  2. Make a new key
    openssl rand -hex 32
  3. Replace itIn .env (then restart the server) or in Vercel's environment variables (then redeploy). Store the new value in your password manager.
  4. Enter the secrets againIntegrations (Anthropic key), Notifications (webhook secret); set up two-factor again where needed.
  5. CheckStatus → Re-run checks: Anthropic API key accepted is green again.

Change it at once if it may have leaked. Because someone with both the key and a copy of the database could decrypt the stored secrets, also create a new Anthropic key in your Anthropic account and a new webhook secret.

04Backups

WhatWhereHow to back it up
ADMIN_SECRET_KEY and the rest of .envYour server or Vercel's environment settingsA password manager. Never git, never a support message.
Admin database (Node server, SQLite)THESIS_DATA_DIR (default ./data): admin.sqlite and, while the server runs, admin.sqlite-wal and admin.sqlite-shmThe database runs in WAL mode, so copy the whole folder with the server stopped:
cp -R data "thesis-data-$(date +%F)"   # with the server stopped
Aggregate countersTHESIS_DATA_DIR/stats.json, or Vercel BlobOptional: counters only. Included when you copy the data folder.
Admin database (Postgres, required on Vercel)Tables mk_admin_* in the database at DATABASE_URLYour provider's own backups or restore points (see the provider's documentation), or a dump with the PostgreSQL client tools:
pg_dump "$DATABASE_URL" -t 'mk_admin_*' > "thesis-admin-$(date +%F).sql"
Settings onlyThe consoleOwner: Export / Import → Export downloads thesis-admin-<date>.json with every ordinary setting. It holds wallet addresses in clear (keep it private) but no secrets, accounts, audit log or history. Import shows a preview first and never imports secrets.
Users' strategies, journals, alert settingsEach user's own browserNot on your server, so you cannot back them up. Users can export strategies and the journal (CSV) from the desk.

A backup of the database is only useful together with the same ADMIN_SECRET_KEY; without it you restore everything except the encrypted secrets. Test a restore once on a copy before you rely on it.