The v1 architecture
At the end of day 3:
titoruns as a non-root OS user with a sudo allowlist- All API credentials live in
/etc/environment.d/openclaw.conf - No inbound ports. Telegram uses outbound long-polling
- Cloudflare access split: D1/R2 via read-only tokens, CRM writes via Worker gated by Cloudflare Access
The initial setup had these constraints: no inbound ports, bounded sudo, read-only D1 and R2 access, per-repo SSH keys at chmod 600, and CRM writes gated by two separate credentials.
The credential problem
All API tokens sat in tito's environment. The agent ran as tito. If the model got tricked, say by prompt injection in fetched content, into printing environment variables, it would find real keys. Markdown rules saying "don't share credentials" are not a control. They are just words the model can be talked around.
The D1 token has a second problem: it's scoped at the account level, not per-database.
The Telegram bot token sits in the URL path (/bot<token>/...), not as an HTTP header, so header-level injection doesn't cover it.
Proposed fix
Two changes came out of the review:
-
Secrets proxy under a separate OS user. Real tokens held by
openclaw-secrets.titogets placeholder values. All outbound HTTP routes through a proxy that injects real credentials per-host. Compromised prompt gets "proxy-managed", not a real key. -
Cloudflare IP allowlist. Pin accepted IPs to the home server so leaked tokens only work from the correct origin.
Neither change was implemented on day 4. Day 8 covers the implementation.
