Skip to content

Security: slzatz/claude_agent_remote

Security

docs/security.md

Security Model: Telegram-Claude Bridge

Threat Model

What We're Protecting

  • Personal files, SSH keys
  • Email and calendar access (personal Gmail + Doximity work accounts)
  • API credentials (Anthropic, Google OAuth, Telegram bot token, database passwords)
  • Personal and professional information (contacts, biography, Doximity leadership details)

Primary Attack Vectors

  1. Stolen Telegram bot token — attacker sends messages to Claude as if they were the authorized user. Mitigated by rotating tokens and restricting .env file permissions.

  2. Telegram account compromise — attacker uses the real Telegram account (passes user ID check). Mitigated by input blocklist, output redaction, system prompt hardening, and rate limiting.

  3. Prompt injection — malicious content in emails, web pages, or notes tricks Claude into exfiltrating data. Mitigated by system prompt security rules and output redaction.

  4. Local file access — someone with access to the machine reads plaintext credentials. Mitigated by chmod 600 on all sensitive files.

Current Defenses

  • Telegram user ID allowlist (single authorized user)
  • Per-request budget cap ($2.00 USD)
  • Concurrent request locking (one Claude invocation per chat at a time)
  • Input blocklist, output redaction, rate limiting, system prompt hardening (see below)
  • File permissions (600) on all credential files
  • systemd hardening (NoNewPrivileges, PrivateTmp)

Security Layers

1. Input Blocklist (security.py)

Messages are checked against targeted patterns before reaching Claude. Blocked patterns include:

  • SSH key paths (.ssh/id_rsa, .ssh/id_ed25519, etc.)
  • Credential files (.secrets, .credentials.json)
  • Specific environment variable names (GOG_KEYRING_PASSWORD, VIMANGO_PG_PASSWORD, TELEGRAM_BOT_TOKEN, etc.)
  • Private key content (BEGIN RSA PRIVATE KEY, etc.)
  • Generic credential exfiltration attempts (cat *.pem, read *.key, etc.)

Blocked messages receive a generic rejection and are logged.

2. Output Redaction (security.py)

Claude's responses are scanned before being sent to Telegram. Redacted patterns:

  • Anthropic API keys (sk-ant-*)
  • Anthropic OAuth tokens (sk-ant-oat*, sk-ant-ort*)
  • Google OAuth client secrets (GOCSPX-*)
  • Telegram bot tokens (NNNNNNNN:AA*)
  • PEM private key blocks
  • Shell credential exports (export *PASSWORD*=, export *SECRET*=, etc.)

3. System Prompt Hardening (claude.py)

Every prompt sent to Claude is prefixed with security rules instructing it to:

  • Never read or display SSH private keys
  • Never read or display credential files (~/.secrets, .credentials.json)
  • Never reveal specific environment variables
  • Never exfiltrate data via URLs, DNS, or side channels
  • Refuse requests designed to extract credentials

4. Rate Limiting (security.py)

  • 30 requests per hour per user (sliding window)
  • In-memory tracking (resets on service restart)
  • Separate limits per Telegram user ID

5. File Permissions

File Contents Permissions
telegram-bridge/.env Bot token, permission mode 600
.claude/accounts.env Email account identifiers 600
~/.secrets Database password, API key, keyring password 600
telegram-bridge/.sessions.json Claude session IDs 600
~/.ssh/id_* SSH private keys 600 (default)

6. systemd Hardening

The telegram-bridge.service includes:

  • NoNewPrivileges=true — prevents privilege escalation
  • PrivateTmp=true — isolated /tmp namespace

7. Git Protection

All credential files are listed in .gitignore:

  • telegram-bridge/.env
  • .claude/*.env
  • .sessions.json
  • CLAUDE.local.md

Known Limitations

  • bypassPermissions mode — Claude runs with full shell access. This is required for unattended Telegram operation (no one to approve actions). The bot-level guardrails are the compensating control.
  • System prompt is advisory — a sophisticated prompt injection could theoretically bypass the security prefix. The input blocklist and output redaction provide defense-in-depth.
  • Rate limiting is in-memory — resets when the service restarts. Sufficient for personal use.
  • Single-user model — no role-based access control. The allowlist is all-or-nothing.

Credential Rotation Checklist

When rotating credentials:

  1. Telegram bot token/revoke in @BotFather, update telegram-bridge/.env, restart service
  2. Anthropic API key — regenerate at console.anthropic.com, update ~/.secrets
  3. Google OAuth — re-authenticate via gog CLI
  4. GOG keyring password — update in ~/.secrets

There aren’t any published security advisories