6.4 KiB
name, description
| name | description |
|---|---|
| decrypt | Decrypts a DM message on localhost by granting temporary compliance extract access, running extract and decrypt CLI commands, then reverting all temporary changes. Use when the user asks to decrypt a message or run the compliance decryption workflow on localhost. |
Decrypt (local debug)
End-to-end workflow for extracting and decrypting one message on localhost. All temporary backend access must be removed when finished.
After decrypt: what to do with the plaintext and files (compare, inspect, report, etc.) comes from the current conversation — not from this skill.
Prerequisites
- Web dev server running at
http://localhost:8301(browser rules default). compliance_keypair.txtat the Web repo root (Web/compliance_keypair.txt).- Python deps for
scripts/compliance/decryption/(cryptography, etc.).
Step 0 — Read the compliance keypair
Read Web/compliance_keypair.txt before any decrypt step. Confirm the private key line exists (line after PRIVATE KEY header, base64).
The decrypt CLI loads compliance_keypair.txt from the current working directory. Always run extract/decrypt with cd to the Web repo root:
cd /path/to/Web
If load_compliance_private_key fails, the file format may need a PRIVATE_KEY=<base64> line (the loader expects that or a 43-char base64 line; 32-byte keys are often 44 chars with padding).
Step 1 — Create a temporary user and capture token
Generate random credentials (username 3–20 chars: letters, digits, -, _; password 5–50 chars, no spaces):
DEBUG_USER="decryptdbg$(openssl rand -hex 3)"
DEBUG_PASS="$(openssl rand -base64 12 | tr -d '/+=' | head -c 16)"
echo "user=$DEBUG_USER pass=$DEBUG_PASS"
Register and save token from the JSON response (not the derived login secret):
REGISTER_JSON=$(curl -sS -X POST "http://localhost:8301/api/register" \
-H "Content-Type: application/json" \
-d "{\"username\":\"${DEBUG_USER}\",\"display_name\":\"DecryptDebug\",\"password\":\"${DEBUG_PASS}\",\"confirm_password\":\"${DEBUG_PASS}\"}")
echo "$REGISTER_JSON"
DEBUG_TOKEN=$(python3 -c 'import json,sys; print(json.load(sys.stdin)["token"])' <<< "$REGISTER_JSON")
echo "token saved (length ${#DEBUG_TOKEN})"
Alternatively export for the CLI: export FROMCHAT_API_TOKEN="${DEBUG_TOKEN}"
Save user.id from the same JSON if needed for debugging.
Step 2 — Temporary compliance extract permission (marker blocks)
GET /api/dm/compliance/extract/{message_id} is restricted to user id 1 in:
backend/services/main/routes/envelope_messaging.py (function extract_message_for_compliance).
Add a temporary bypass between searchable markers (replace DEBUG_USERNAME with the user from step 1):
# TEMP_COMPLIANCE_DEBUG_START — remove after decrypt debug run
_TEMP_COMPLIANCE_DEBUG_USERNAMES = {"DEBUG_USERNAME"}
# TEMP_COMPLIANCE_DEBUG_END
# Security check: only user ID 1 can access this
if current_user.id != 1 and current_user.username not in _TEMP_COMPLIANCE_DEBUG_USERNAMES:
Backend will auto-reload after this change, you don't need to do anything.
To remove later: search the repo for TEMP_COMPLIANCE_DEBUG and delete the marker block + revert the if to only current_user.id != 1.
Step 3 — Extract bundle (online)
From Web repo root, set variables and run (user supplies MESSAGE_ID):
MESSAGE_ID=<message_id>
RANDOM_FOLDER="run_$(openssl rand -hex 4)"
BUNDLE_DIR="/tmp/debug_decrypt/${RANDOM_FOLDER}"
DECRYPT_DIR="/tmp/debug_decrypt/${RANDOM_FOLDER}_dec"
mkdir -p /tmp/debug_decrypt
cd /path/to/Web
python scripts/compliance/decryption/main.py extract \
--server localhost:8301 \
--http \
--token "${DEBUG_TOKEN}" \
--message-ids "${MESSAGE_ID}" \
--out-dir "${BUNDLE_DIR}"
Equivalent using env (no --token flag):
export FROMCHAT_API_TOKEN="${DEBUG_TOKEN}"
python scripts/compliance/decryption/main.py extract \
--server localhost:8301 \
--http \
--message-ids "${MESSAGE_ID}" \
--out-dir "${BUNDLE_DIR}"
Confirm ${BUNDLE_DIR}/bundle.json exists.
Auth flags: use --token (Bearer from register/login), or --username + --password (CLI derives the login secret). Do not pass both.
Step 4 — Decrypt bundle (offline)
Still from Web repo root (compliance_keypair.txt must resolve):
python scripts/compliance/decryption/main.py decrypt \
--bundle-dir "${BUNDLE_DIR}" \
--output-dir "${DECRYPT_DIR}"
Outputs:
${DECRYPT_DIR}/messages/<message_id>/message.decrypted.txt— message plaintext${DECRYPT_DIR}/messages/<message_id>/files/— decrypted attachments${DECRYPT_DIR}/index.html— HTML report
Step 5 — Use decrypted output (conversation-driven)
Follow the user’s request in the current chat for what to do next (e.g. compare hashes, inspect text, verify a specific attachment). This skill stops at producing ${DECRYPT_DIR}; do not assume a fixed post-decrypt task.
Step 6 — Cleanup (required)
-
Remove decrypt dirs:
rm -rf "${BUNDLE_DIR}" "${DECRYPT_DIR}" -
Delete temp user (local SQLite default DB):
sqlite3 backend/data/database.db "DELETE FROM users WHERE username='${DEBUG_USER}';"If your deployment uses another DB, delete the same username there.
-
Remove temporary permission: search
TEMP_COMPLIANCE_DEBUGin the repo, delete the marker block, restore the originalif current_user.id != 1:check, restart backend. -
Do not commit
compliance_keypair.txtor any decrypt output.
Checklist
- [ ] Read compliance_keypair.txt
- [ ] Register DEBUG_USER; save DEBUG_TOKEN from response
- [ ] Add TEMP_COMPLIANCE_DEBUG_* bypass; restart backend
- [ ] extract --token → bundle.json present
- [ ] decrypt → output under DECRYPT_DIR
- [ ] Post-decrypt work per conversation context
- [ ] rm -rf BUNDLE_DIR and DECRYPT_DIR
- [ ] DELETE temp user from DB
- [ ] Remove TEMP_COMPLIANCE_DEBUG markers; restart backend
Reference
- Extract API:
GET /api/dm/compliance/extract/{message_id}(seebundle_extract.py). - Decrypt implementation:
scripts/compliance/decryption/bundle_decrypt.py,crypto.py. - Extract auth:
--token(Bearer), envFROMCHAT_API_TOKEN/FROMCHAT_TOKEN, or--username+ plain--password(CLI callsderive_auth_secretfor login only).
Rules
- NEVER use sleep in any command.
- Set a timeout on EVERY command that may request user input.