Files
trumpsignal-backend/deploy/ENCRYPTION_KEY_BACKUP.md
k b941223c88 fix: complete v5 routing — API exposure, rescore persistence, leverage cap, key backup doc
Three plumbing fixes + one ops doc that close the gaps from the audit.

scripts/rescore_v5.py
  Was overwriting only signal/conf/reasoning/sentiment/relevant/
  prefilter_reason/analysis_version. Now also persists target_asset,
  category, expected_move_pct — without these the bot can't route
  rescored posts correctly (would silently fall back to BTC).

app/schemas.py + app/api/posts.py
  TrumpPost response model didn't expose target_asset/category/
  expected_move_pct, so the frontend had no way to display "this
  signal will trade SOL". Added the three fields + mapping in
  _post_to_schema(). Pre-v5 posts return null. No frontend changes
  yet — display work is a follow-up.

app/services/hyperliquid.py
  HL caps max leverage per asset (BTC/ETH 50×, SOL 20×, memes 3-5×).
  set_leverage() always tried to push self._leverage — if user set
  30× and bot routed to TRUMP, HL rejected the order and the trade
  silently dropped. Added _get_max_leverage() (queries meta()'s
  maxLeverage field) and _clip_leverage() that caps to HL's max.
  set_leverage now returns the effective leverage so callers can
  use it for notional sizing if needed.

deploy/ENCRYPTION_KEY_BACKUP.md
  Documented mandatory backup procedure for the symmetric key that
  encrypts every user's HL API key. Lost key = all users' bots dead
  with no recovery. Includes rotation procedure + quarterly test
  step + things-not-to-do list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-08 19:59:30 +08:00

2.9 KiB

ENCRYPTION_KEY backup procedure — DO NOT SKIP

The ENCRYPTION_KEY env var encrypts every user's Hyperliquid API key before it touches the database. If this key is lost or rotated without re-encrypting the existing rows, every active user's bot permanently stops trading — there is no recovery path. This is the single most-load-bearing secret in the project.

What it looks like

ENCRYPTION_KEY=1cf813d6790cc1b1c0981951703ca387d58321d81dc9b5b4982c07487edc478e

A 64-char hex string (32 bytes). Used by app/services/crypto.py via Fernet-equivalent symmetric encryption.

Backup requirements (mandatory before going live)

Store the production value in at least two locations, at least one of which is offline / non-cloud:

1. Password manager (1Password / Bitwarden / KeePass)

  • Item type: "Secure Note"
  • Title: TrumpSignal — ENCRYPTION_KEY (production)
  • Body: the 64-char hex value
  • Add note: "Lost = every user's bot dead. No way to recover."
  • Tag/folder for fast retrieval

2. Offline physical backup

Pick one (or do both):

  • Paper: print the key on a single sheet, store in a locked drawer / safe / safety deposit box. Label: "TrumpSignal encryption key — do not discard, do not photograph, do not type into computers."
  • Hardware key: write to a USB drive that lives offline, kept in the same safe. Label and date it.

3. (Optional) Co-founder / trusted-party split

If multiple humans run the project: split the key (Shamir's Secret Sharing or just give halves to two people) so no single person can walk off with it AND no single person can lose all copies.

Before any rotation

Rotating the key is not free. To rotate:

  1. Generate NEW_KEY.
  2. Decrypt every existing subscriptions.hl_api_key with the old key, re-encrypt with the new key, write back. (Script not shipped — has to be written carefully.)
  3. Only after the migration completes, swap env var and restart.
  4. Update both backup locations with NEW_KEY.
  5. Securely destroy the old key copies after a 30-day cool-off (during which you confirm no users got broken).

If you skip step 2, every existing user's HL key becomes garbage on the new server and their bot silently stops working.

How to test backups (do this once a quarter)

  1. Pull the key out of password manager → match against the env var on the running server.
  2. Pull the offline copy → match against the password-manager copy.
  3. Confirm both match. If any drift, sync immediately — never assume the running server has the "true" copy without verifying.

What NOT to do

  • Don't paste the key into Slack / Discord / email.
  • Don't commit the key to git (.env is in .gitignore, but double-check before any git add -A).
  • Don't share via screenshot — keys can be OCR'd from anywhere.
  • Don't store only on the server — if the server dies, you lose it.
  • Don't rotate "just because" — it's expensive and risky.