Security Guard Report β 2026-03-11
Patrol time: 03:30 AM (America/New_York)
Agent: Security Guard (Claude Opus)
AutoAudit verified: Yes (2026-03-11)
Previous report: 2026-03-10
Executive Summary
Overall threat level: MEDIUM
Improvement trend continues from yesterday's MEDIUM-HIGH. Key changes since last patrol:
-
NEW: api.clawstin.org β Cloudflare Tunnel now exposes the vitals API (port 8765) to the public internet. The API has Bearer token auth on all routes β this is a significant improvement over the unauthenticated static site, but it's a new attack surface.
-
lifeboat-system/ still in workspace β 4th consecutive patrol flagging this. Contains full credential suite (API keys, OAuth tokens, Fernet master key, Cloudflare tunnel secret, rclone Google Drive tokens, Gmail OAuth tokens, Signal key material). All gitignored and owner-read-only, but accessible to any process with workspace read access.
-
Stale FER plist in lifeboat β FER was dismantled in session 17, but `lifeboat-system/launch-agents/clawstin.fer-monitor.plist` persists (confirmed by AutoAudit finding #5).
-
No external threat intelligence β 4th consecutive patrol unable to check NVD/Node.js/macOS advisories (sandbox has no network access).
This patrol identified
8 findings: 1 severity 7, 3 severity 5, 1 severity 3, and 3 severity 1-2.
FINDINGS
SG-2026-03-11-001: Lifeboat-System Credential Directory in Workspace
Severity: 7 (unchanged from yesterday)
Evidence:
```
ls -la /Users/aicomputer/.openclaw/workspace/lifeboat-system/
β 7 subdirectories: cloudflared, den, gmail-tokens, launch-agents, openclaw-config, rclone, signal-data
```
Contents include:
- `den/fernet-key.b64` (61 bytes, -rw-------, master encryption key for credential store)
- `den/creds.enc` (4792 bytes, encrypted credential store β but key is RIGHT NEXT TO IT)
- `openclaw-config/openclaw.json` β contains plaintext API keys:
- `sk-ant-[REDACTED]` (Anthropic, labeled as OPENAI_API_KEY)
- `sk_[REDACTED]` (ElevenLabs)
- `sk-or-[REDACTED]` (OpenRouter)
- `BSA[REDACTED]` (web search API key)
- `gmail-tokens/token-adalsey.json`, `token-krspamgang.json`, `token-clawstinai.json` β Gmail OAuth tokens with refresh tokens
- `gmail-tokens/credentials.json` β Google OAuth client_id + client_secret (`GOCSPX-[REDACTED]`)
- `rclone/rclone.conf` β Google Drive OAuth tokens (access + refresh) for 2 accounts (`pidrive`, `clawstindrive`)
- `cloudflared/2c29ad40-*.json` β Cloudflare tunnel secret (`[REDACTED]`) + account tag
- `cloudflared/cert.pem` β Cloudflare Argo tunnel token/certificate
- `signal-data/` β Signal key material (account 535318)
Mitigating factors:
- All files are `-rw-------` (owner-read-only)
- `lifeboat-system/` is in `.gitignore` β not committed to git
- No git remote configured β workspace isn't pushed anywhere
- Nightly backup uploads to Google Drive as part of lifeboat (encrypted zip)
Remaining risk: Any subagent, tool, or process with workspace filesystem access can read all credentials. The Fernet key stored as a file next to the encrypted store makes encryption security theater β anyone who can read the directory can decrypt everything.
Rubric: Severity 7 β credential storage accessible locally without privilege escalation. Not externally exposed. Downgraded from 9 (initial discovery) because gitignore prevents remote exposure.
Action: Move `lifeboat-system/` out of workspace entirely. Store Fernet key in macOS Keychain only, not as a file.
SG-2026-03-11-002: Cloudflare Tunnel β 4 Services Exposed to Internet (NEW route: api.clawstin.org)
Severity: 5 (downgraded from 8 yesterday; static site accepted; API is auth-protected)
Evidence:
```
cat lifeboat-system/cloudflared/config.yml
β ingress:
- hostname: clawstin.org β localhost:8877 (Python http.server, static site, NO AUTH)
- hostname: voice.clawstin.org β localhost:3334 (NOT RUNNING β no process on 3334)
- hostname: webhook.clawstin.org β localhost:18789 (gateway webhook)
- hostname: api.clawstin.org β localhost:8765 (vitals API β NEW)
- service: http_status:404
```
NEW since last patrol: `api.clawstin.org` routes to the Flask vitals API on port 8765. Added in session 14 (2026-03-10 16:56-18:29) to enable the Clapp iPhone app to work remotely.
API security review (positive):
- Bearer token auth (`require_auth` decorator) confirmed on ALL API routes (grep found auth on lines 214, 226, 248, 301, 328, 544, 562, 675, 743, 758)
- API key loaded from Den (encrypted credential store) at startup
- Returns 401 Unauthorized for missing/invalid tokens
Static site (accepted risk SG-2026-03-10-002):
- Serves via symlinks: vital.json, vital-widget.json, brain-map.html, vital-version.txt, vital-widget-latest.js
- Confirmed no passwords, API keys, or tokens in vital.json/vital-widget.json
- Data exposed: balance ($115.68), metal prices, budget gauges, token usage β operational telemetry only
Rubric: Severity 5. API has proper auth. Static site accepted. voice.clawstin.org is dead (no listener). Main residual risk: brute-force of API key over internet, no rate limiting observed in code.
Action: Consider adding rate limiting to the Flask API (Flask-Limiter or Cloudflare WAF rules).
SG-2026-03-11-003: Chrome Remote Desktop Running (Accepted Risk)
Severity: 3 β Accepted per SG-2026-03-09-005.
Evidence:
```
ps aux | grep remoting_me2me
β PID 1505, running since Sat 07AM
β --host-config=/Library/PrivilegedHelperTools/org.chromium.chromoting.json
β --ssh-auth-sockname=/tmp/chromoting.aicomputer.ssh_auth_sock
```
No change from previous patrol. SSH auth socket in /tmp is part of the accepted risk.
SG-2026-03-11-004: Signal-CLI Daemon on Localhost HTTP (No TLS/Auth)
Severity: 5 (unchanged)
Evidence:
```
ps aux | grep signal
β PID 28240: signal-cli 0.13.24 daemon --http 127.0.0.1:8080 --no-receive-stdout
β Account: +[REDACTED]
```
Signal-CLI HTTP daemon on 127.0.0.1:8080 β any local process can send Signal messages without authentication. No external exposure (not routed via Cloudflare tunnel, bound to localhost only).
Risk: A compromised local process could send arbitrary Signal messages as Clawstin.
Rubric: Severity 5 β localhost-only service, requires local process compromise to exploit.
SG-2026-03-11-005: Vitals API Binds to 0.0.0.0 (LAN + Tailscale Accessible)
Severity: 5 (NEW finding)
Evidence:
```
grep "0.0.0.0" /Users/aicomputer/clawstin-app/server/api.py
β Line 5: "Port 8765, binds to 0.0.0.0 for LAN access."
β Line 788: app.run(host="0.0.0.0", port=8765, debug=False)
ps aux β PID 48237 running api.py
```
The vitals API intentionally binds to all interfaces (0.0.0.0), making it accessible on:
- localhost (127.0.0.1:8765)
- LAN (192.168.1.109:8765)
- Tailscale (100.112.26.36:8765)
- Internet (via api.clawstin.org through Cloudflare)
All routes have Bearer token auth. However, LAN access means any device on the home network could attempt to access or brute-force the API.
Rubric: Severity 5 β intentional design for app access, auth-protected, but broader exposure than strictly necessary.
Action: If Cloudflare tunnel is now the primary remote path, consider binding to 127.0.0.1 and letting Cloudflare handle all external access. Accept as risk if LAN access is still needed for development.
SG-2026-03-11-006: Test/Example Passwords in Fixture Files
Severity: 2 (informational)
Evidence:
```
grep password scripts/test-llc-intake.json
β Line 43: "password": "[REDACTED]" (test value)
grep password PROJECTS/COMPLETE/daad-intake-form.md
β Line 400: "password": "[REDACTED]" (example value)
```
These are test/example passwords in test fixtures, not real credentials. Both files are owner-read-only. The `test-llc-intake.json` is a test payload for an LLC formation flow; `daad-intake-form.md` is a completed project spec with example JSON.
Rubric: Severity 2 β fake test data, no real exposure risk.
SG-2026-03-11-007: Proton Mail Bridge Sentry Key in Process Args
Severity: 2 (unchanged)
Evidence:
```
ps aux | grep proton
β PID 1508 (crashpad_handler): --url=
https://mail-api.proton.me:443/.../sentry_key=[REDACTED]
```
Sentry DSN key visible in process arguments. This is a crash-reporting ingest key with write-only permissions β low risk. Standard behavior for Proton Mail Bridge.
Rubric: Severity 2 β crash reporting only, not exploitable for data access.
SG-2026-03-11-008: Memory MD Files Reference Credential Patterns (Placeholder Only)
Severity: 1 (informational β confirmed false positive)
Evidence:
```
grep sk-ant- memory/2026-03-06-1922.md
β Lines 189, 220, 261: all placeholders ("sk-ant-...", "sk-ant-your-new-key-here")
grep sk-ant- memory/2026-03-06-1839.md
β Lines 301, 304, 314: all placeholders ("sk-ant-your-new-key-here")
grep sk-ant- memory/sessions/2026-03-09-session-03.md
β Line 13: "Redacted sk-ant-api..." β reference to prior redaction work
```
All matches are instruction placeholders or references to prior security cleanup. No actual credential values.
Rubric: Severity 1 β false positive, informational only.
SYSTEM STATUS
| Component | Status | Notes |
|-----------|--------|-------|
| LuLu Firewall | β
RUNNING | PID 1491, since Sat 07AM |
| Tailscale | β
RUNNING | PID 655 (root) |
| Cloudflare Tunnel | β
RUNNING | PID 39944, tunnel `clawstin` |
| Signal-CLI | β
RUNNING | PID 28240, port 8080 (localhost) |
| OpenClaw Gateway | β
RUNNING | PID 28214 (880MB RSS) |
| Proton Mail Bridge | β
RUNNING | PID 1501/1510 |
| Vitals API (8765) | β οΈ CHECK | PID 48237 running but AutoAudit says exit -15 (SIGTERM) |
| Static Site (8877) | β
RUNNING | PID 54626 (vital-server, also exit -15 per launchctl but responding) |
| Chrome Remote Desktop | β
RUNNING | PID 1505 (accepted risk) |
| Nightly Backup | β
OK | Last: 2026-03-11 02:00, lifeboat complete 02:02 |
| Billing Watchdog | β
OK | Running every 5 min, all OK through 03:29 |
| Brain Map (8766) | β οΈ NOT RUNNING | No process found on port 8766 |
| World-writable files | β
NONE | `find workspace -perm -002` returned empty |
| Stray creds in /tmp | Unable to verify | Sandbox blocked find in /tmp |
| Full disk encryption | Unable to verify | fdesetup blocked by sandbox |
| npm audit | Unable to run | Sandbox blocked |
| pip outdated | Unable to run | Sandbox blocked |
| External threat intel | Unable to check | No network access β 4th consecutive patrol |
| Git remote | NONE | No remote configured; local repo only |
| OpenSSL | Unable to verify | Sandbox blocked |
LaunchAgent Highlights
- `clawstin.vitals-api` (PID 48237): exit -15 β flagged by AutoAudit
- `clawstin.vital-server` (PID 54626): exit -15 but responding on 8877
- `clawstin.cloudflared` (PID 39944): running normally
- `clawstin.fer-monitor`: stale plist in LaunchAgent list + lifeboat (FER dismantled session 17)
COMPARISON WITH 2026-03-10
| Finding | 03-10 | 03-11 | Change |
|---------|-------|-------|--------|
| SG-001: Lifeboat creds in workspace | 7 | 7 | No change (4th consecutive) |
| SG-002: Cloudflare tunnel exposure | 8 | 5 | β Static site accepted; new API is auth-protected |
| SG-003: Chrome Remote Desktop | 3 | 3 | Accepted risk, no change |
| SG-004: pip outdated | 5 | β | Unable to verify (sandbox blocked) |
| SG-005: Signal-CLI localhost HTTP | 5 | 5 | No change |
| SG-006: LaunchAgent failures | 3 | β | Operational, not re-flagged |
| SG-007: Proton sentry key in ps | 2 | 2 | No change |
| NEW: api.clawstin.org exposed | β | 5 | New (auth-protected, Cloudflare) |
| NEW: Vitals API binds 0.0.0.0 | β | 5 | New (intentional for app) |
| NEW: Test passwords in fixtures | β | 2 | Informational |
THREAT LANDSCAPE (External)
Unable to check external sources. Sandbox environment has no network access. This is the 4th consecutive patrol without external threat intelligence coverage.
Sources NOT checked:
- NVD (NIST) β nvdcve-1.1-recent.json
- Node.js Security Advisories
- macOS Security Bulletins
- OpenClaw GitHub advisories
- Signal-CLI GitHub issues
Recommendation: Ghost should manually check `
https://nvd.nist.gov` and `
https://nodejs.org/en/security` periodically, or enable network access for Security Guard.
RISK ACCEPTANCE CROSS-REFERENCE
| Finding | Matches Accepted Risk? | Notes |
|---------|----------------------|-------|
| SG-003: Chrome Remote Desktop | β
SG-2026-03-09-005 | Permanent accept |
| SG-002: Static site (clawstin.org) | β
SG-2026-03-10-002 | Accepted 2026-03-10, review 2026-09-10 |
| SG-001: Lifeboat creds | β Not accepted | Recommend Ghost review for acceptance or remediation |
| SG-004/005: Signal-CLI + API 0.0.0.0 | β New | May warrant acceptance if intentional |
RECOMMENDATIONS (Priority Order)
1.
Move lifeboat-system/ out of workspace β 4th patrol flagging this. The Fernet master key next to the encrypted store is security theater. Move to `~/.openclaw/lifeboat-system/` or `/Users/aicomputer/lifeboat-system/` (outside workspace tree). Store Fernet key in macOS Keychain only.
2.
Add rate limiting to vitals API β api.clawstin.org is now internet-facing. Consider Flask-Limiter or Cloudflare WAF rate limiting rules to prevent brute-force.
3.
Accept or remediate 0.0.0.0 binding β If Cloudflare tunnel is the primary remote path, bind to 127.0.0.1. If LAN access is still needed, accept as risk.
4.
Enable network access for Security Guard β 4 consecutive patrols without external threat intelligence is a blind spot.
5.
Clean stale FER plist from lifeboat β `lifeboat-system/launch-agents/clawstin.fer-monitor.plist` references a dismantled system.
PATROL METADATA
- Commands run: ~50
- Commands blocked by sandbox: ~19
- Findings: 8 (1Γsev7, 3Γsev5, 1Γsev3, 3Γsev1-2)
- Critical alerts (9-10): NONE β no Signal alert required
- Report written: 2026-03-11 ~03:32 AM ET
- Next patrol: 2026-03-12 03:30 AM ET