# DRE Credential Audit — Jul 8, 2026 Full audit of every key, token, and password across the system. ## Credential Inventory | # | Credential | Location | Type | Test Method | Status | |---|-----------|----------|------|-------------|--------| | 1 | FIRECRAWL_API_KEY | ~/.hermes/.env | API Key | POST to api.firecrawl.dev/v1/search | ✅ | | 2 | CLOUDFLARE_API_TOKEN | ~/.hermes/.env | API Token | GET cloudflare.com/client/v4/user/tokens/verify | ✅ | | 3 | admin-ai api_key | config.yaml (admin-ai provider) | API Key | POST to admin-ai /v1/chat/completions | ✅ | | 4 | PG_DATABASE_PASSWORD | /root/docker/twenty/.env | DB Password | docker exec psql SELECT 1 | ✅ | | 5 | ENCRYPTION_KEY | /root/docker/twenty/.env | Encryption Key | (validated by container health) | ✅ | | 6 | MYSQL_PASS (Apex DB) | config.yaml (mcp_servers.mysql.env) | DB Password | mysql SELECT 1 via SSH tunnel | ✅ | | 7 | g@germainebrown.com IMAP | ~/.config/himalaya/g-germainebrown.pass | IMAP Password | imaplib LOGIN | ✅ | | 8 | shonuff@germainebrown.com IMAP | ~/.config/himalaya/shonuff.pass | IMAP Password | imaplib LOGIN | ✅ | | 9 | iCloud calendar password | ~/.config/himalaya/g-germainebrown-icloud-calendar.pass | App-Specific | imaplib LOGIN to p02-imap.mail.me.com | ❌ Expired — replaced Jul 8 | | 10 | DRE email IMAP (dre@ + collections@) | (no file — used inline in dre-mail-poller.py) | IMAP Password | imaplib LOGIN to heracles.mxrouting.net | ✅ | ## Audit Pattern (Reproducible) ### Step 1: Inventory ```bash # Check .env grep -v "^#\|^$" /root/.hermes/.env | cut -d= -f1 # Check .config password files find /root/.config -name "*.pass" -o -name "*.pwd" -o -name "*.token" # Check docker .env files find /root/docker -name ".env" -exec basename {} \; 2>/dev/null # Check config.yaml grep -E "api_key|password|secret|token|_key|_pass" /root/.hermes/config.yaml | grep -v "skipped\|disabled\|cron_mode" ``` ### Step 2: Test ```bash # Firecrawl curl -s -w "\nHTTP:%{http_code}" -X POST "https://api.firecrawl.dev/v1/search" \ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"query":"test","limit":1}' | tail -1 # Cloudflare curl -s -w "\nHTTP:%{http_code}" -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \ -H "Authorization: Bearer $TOKEN" | tail -1 # admin-ai curl -s -w "\nHTTP:%{http_code}" "https://admin-ai.itpropartner.com/v1/chat/completions" \ -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \ -d '{"model":"deepseek-chat","messages":[{"role":"user","content":"ping"}],"max_tokens":2}' | grep -o "HTTP:[0-9]*" # IMAP password files python3 -c " import imaplib, ssl with open('/root/.config/himalaya/FILE.pass') as f: pw = f.read().strip() ctx = ssl.create_default_context() s = imaplib.IMAP4_SSL('HOST', 993, ssl_context=ctx, timeout=10) s.login('user@domain.com', pw) print('LOGIN OK') s.logout() " # PostgreSQL via docker docker exec twenty-db-1 psql -U postgres -d default -c "SELECT 1 AS test" # MySQL via tunnel mysql -h 127.0.0.1 -P 33060 -u USER -pPASS --skip-ssl -e "SELECT 1 AS test" ``` ### Step 3: Known Issues 1. **iCloud app passwords expire** — Apple app-specific passwords for iCloud Calendar/IMAP must be regenerated at appleid.apple.com whenever they stop working. File: `g-germainebrown-icloud-calendar.pass`. Always test against `p02-imap.mail.me.com:993`. Note: Apple's IMAP rejects app-specific passwords for iCloud mail — use CalDAV PROPFIND to test (`requests.request('PROPFIND', 'https://caldav.icloud.com/', auth=(user, pw))` returns 207 on success). The CalDAV principal URL format is `/1079451706/principal/` with calendar home at `p{xx}-caldav.icloud.com:443/1079451706/calendars/`. 2. **Cron has no session env** — credentials in session-only env vars (`source .env` in terminal) are invisible to cron. Scripts running from cron must use `${VAR:-$(grep ... .env)}` pattern or access a `.pass` file directly. The `CLOUDFLARE_API_TOKEN` was only in session env — added to `.env` on Jul 8 so the service health check cron could use it. 3. **Script-saved tokens get redacted** — when a script with an inline credential value is written to disk (e.g. via `>>>` heredoc or `write_file`), Hermes' secret redaction replaces the actual value with `***`. Verify scripts contain variable references, not inline values. The `service-health-check.sh` had `Authorization: Bearer ***` baked in because of this.** 4. **Caddy file permissions** — new files created with `write_file` default to `-rw-------` (600). Caddy runs as a non-root user and returns 403. Always run `chmod 644` on new HTML files in /var/www/. Both `login.html` and `index.html` needed this fix on Jul 8. ### Child Email Migration (garrison@iamgmb.com + greyson@iamgmb.com) — Jul 8 Migrated both boys' email accounts from SiteGround to MXroute: | Account | Old Server | New Server | Messages | |---------|-----------|-----------|----------| | garrison@iamgmb.com | c1113726.sgvps.net:993 | heracles.mxrouting.net:993 | 324 (5 folders) | | greyson@iamgmb.com | c1113726.sgvps.net:993 | heracles.mxrouting.net:993 | 74 (INBOX only) | **DNS already correct — no changes needed.** MX records pointed to MXroute, SPF included mxroute.com, DKIM configured. SiteGround removal was clean. ### Delegation Model Update — Jul 8 | Level | Before | After | |-------|--------|-------| | Conversation | deepseek-chat (admin-ai) | deepseek-chat (no change) | | Delegation primary | Claude Opus 4.7 | Claude Opus 4.7 (no change) | | Fallback 1 | *(empty)* | **Claude Opus 4.8** (admin-ai) | | Fallback 2 | *(empty)* | Llama 3.2 3B (ollama-local) | Opus 4.8 tested and confirmed working via delegation subagent.