Migrated from ADR-0029 on 2026-05-02 per ADR-0047. Source file retained with deprecation banner at
docs/adr/0029-openclaw-adoption.md.
LLMOPS-0001 — OpenClaw as Self-Hosted AI Gateway¶
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-04-12 |
| Author | Ben Peries |
| Sources | ADR-0029 |
Context¶
Archon Phase 3 requires a self-hosted AI gateway to serve conversational AI capabilities via Telegram without routing queries through external cloud APIs directly from the host. The platform has an existing Ollama deployment on the CanEast AI Node node (REDACTED) and access to cloud inference APIs (DashScope/Bailian, Groq).
Three options were evaluated:
| Option | Assessment |
|---|---|
| Direct API calls from Telegram bot code | Maximum control; prompt injection risk entirely in application code; high maintenance (provider API changes → code changes) |
| OpenClaw (self-hosted AI gateway) | Purpose-built Telegram + multi-provider AI; config-driven provider switching; Docker-based; no persistent container state |
| Managed AI gateway (LiteLLM, PortKey) | Heavy infrastructure for a homelab bot; not Telegram-native; no advantage over OpenClaw |
Decision¶
Adopt OpenClaw (ghcr.io/openclaw/openclaw) as the self-hosted AI gateway for Archon
conversational agents. Initial deployment: openclaw-archonagent1 (@cae_archonagent_bot)
on the CanEast AI Node node.
Rationale:
- OpenClaw is the only purpose-built Telegram + multi-provider AI gateway evaluated — purpose fit reduces custom code surface area.
- Config-driven model routing (
openclaw.json) decouples provider changes from code changes — updating primary model requires a config file swap, not a redeployment. - Secrets are never written to disk — all API keys injected via
${VAR_NAME}at runtime via Infisical; container runs withuser: 1000:1000. - Image digest pinning (APPSEC-0001) and Grype scan before upgrades mitigate supply chain risk consistent with APPSEC-0001.
- Multi-bot architecture is supported:
openclaw-archonagent1(conversational) andopenclaw-sentinel(alerting) run as independent containers with separate Telegram bot tokens.
Two-bot architecture¶
| Container | Bot | Role |
|---|---|---|
openclaw-archonagent1 |
@cae_archonagent_bot | Conversational (CHATOPS) |
openclaw-sentinel |
@caneast-alertbot | Alerting (ALERTING) |
See OBS-0001 for the routing rule: Alertmanager sends only to SentinelBot; archonagent queries only OpenClaw. No crossover.
Prompt injection risk assessment¶
| Threat | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Telegram user jailbreak via crafted message | Low (allowlist enforced) | Medium | TELEGRAM_ALLOWED_USERS restricts to known numeric user IDs |
| Malicious content in external documents | Low (no external fetch configured) | High | Default config has no web-fetch or file-upload tools |
| Model exfiltrates secrets via crafted tool call | Low (no secrets in model context) | High | API keys injected as env vars, never passed to model context |
| Adversarial model provider (compromised endpoint) | Very low | High | Provider URL pinned in config; digest-pinned container |
Residual risk accepted. Bot is private (allowlist-only), has no web-fetch tools, and secrets never enter the model context.
Constraints¶
- Secrets via Infisical only (IAM-0001). No API keys in
openclaw.json. All keys via${VAR_NAME}env var syntax resolved at runtime. - Image digest pinned before production deployment. Grype scan required before upgrading
to a new digest. Image:
ghcr.io/openclaw/openclaw. (APPSEC-0001) openclaw.jsonon Windows host only —C:\homelab\openclaw-archonagent1\data\openclaw.json. Never committed to git.openclaw.json.exampleis the committed template.- Tool access: No external web-fetch, file-upload, or code-execution tools without a superseding ADR documenting the expanded threat model.
- Future bots: Any new Telegram bot must declare its role (ALERTING or CHATOPS) in its ADR and must not perform functions belonging to the other role (see OBS-0001).
Consequences¶
Positive:
- Conversational AI available via Telegram without custom bot code
- Provider fallback chain: model outages are transparent to users
- Config-driven model upgrades — provider changes require only openclaw.json update, not
a code change
- Foundation for Phase 6 multi-persona scenario queries via separate bot tokens
Negative:
- OpenClaw is a relatively new project — upstream API stability not guaranteed
- Windows host bind mounts (C:\homelab\...) create a platform dependency: config managed
manually on the Windows host, not via Ansible
- Image digest pinning requires manual update procedure before each upgrade
References¶
- OBS-0001 — IT observability stack (Telegram bot routing rule: SentinelBot = ALERTING only)
- IAM-0001 — Infisical for secrets (API keys injected via env vars)
- APPSEC-0001 — Grype scanning and image digest pinning
- LLMOPS-0002 — AI operations agent plane (multi-backend LLM strategy)
docs/reference/openclaw-config.md— OpenClaw configuration reference- WI-150 — OpenClaw adoption ADR
- WI-151 — Image digest pinning + Grype scan