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>
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:
- Generate
NEW_KEY. - Decrypt every existing
subscriptions.hl_api_keywith the old key, re-encrypt with the new key, write back. (Script not shipped — has to be written carefully.) - Only after the migration completes, swap env var and restart.
- Update both backup locations with
NEW_KEY. - 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)
- Pull the key out of password manager → match against the env var on the running server.
- Pull the offline copy → match against the password-manager copy.
- 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 (
.envis in.gitignore, but double-check before anygit 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.