clawshell 0.2.1

A security privileged process for the OpenClaw ecosystem.
# ClawShell Configuration
version = "0.2.1"

# Log level: trace, debug, info, warn, error
log_level = "info"

[server]
host = "127.0.0.1"
port = 18790

[upstream]
openai_base_url = "https://api.openai.com"
openrouter_base_url = "https://openrouter.ai/api"
anthropic_base_url = "https://api.anthropic.com"

# Virtual-to-real API key mappings
# Multiple virtual keys can map to the same real key.
# The "provider" field determines which upstream to use ("openai", "openrouter", or "anthropic").
# Defaults to "openai" if not specified.

[[keys]]
virtual_key = "vk-alice-001"
real_key = "sk-your-real-openai-key-here"
provider = "openai"

[[keys]]
virtual_key = "vk-bob-002"
real_key = "sk-your-real-openai-key-here"
provider = "openai"

[[keys]]
virtual_key = "vk-service-003"
real_key = "sk-another-real-key"
# Uses the default rate limit and provider (openai) when not specified

[[keys]]
virtual_key = "vk-claude-001"
real_key = "sk-ant-your-real-anthropic-key-here"
provider = "anthropic"

# Data Loss Prevention (DLP)
# Each pattern has a name, a regex, and an action.
# action = "redact" (default): Reject the request with 400 Bad Request.
# action = "redact": Replace matches with [REDACTED:<name>] and forward.
# scan_responses: When true, upstream responses are also scanned and PII is redacted.
[dlp]
scan_responses = false
patterns = [
    { name = "ssn",             regex = '\b\d{3}-\d{2}-\d{4}\b',                             action = "redact" },
    { name = "visa_card",       regex = '\b4[0-9]{12}(?:[0-9]{3})?\b',                       action = "redact" },
    { name = "visa_mastercard", regex = '\b(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14})\b',   action = "redact" },
    { name = "mastercard",      regex = '\b5[1-5][0-9]{14}\b',                               action = "redact" },
    { name = "amex_card",       regex = '\b3[47][0-9]{13}\b',                                action = "redact" },
]

# Runtime statistics persistence
# ClawShell counts total requests served, upstream prompt/completion/total
# tokens (from non-streaming responses), and per-sender email-filter
# activity, and exposes them at GET /admin/stats (loopback-only).
[stats]
persist_path = "/etc/clawshell/stats.json"

# Email read endpoint
# If enabled, set exactly one mode:
# - mode = "allowlist" with non-empty allow_senders and empty deny_senders
# - mode = "denylist" with non-empty deny_senders and empty allow_senders
[email]
enabled = false
default_max_results = 50

# mode = "allowlist"
# allow_senders = ["alice@example.com", "@trusted.org"]
# deny_senders = []
#
# mode = "denylist"
# allow_senders = []
# deny_senders = [
#   "@aexp.com",
#   "@alert.chase.com",
#   "@americanexpress.com",
#   "@bac.com",
#   "@bankofamerica.com",
#   "@bofa.com",
#   "@capitalone.com",
#   "@citibank.com",
#   "@citi.com",
#   "@citicorp.com",
#   "@cs.usbank-email.com",
#   "@e.chase.com",
#   "@e.bankofamerica.com",
#   "@email.pnc.com",
#   "@em.truist.com",
#   "@gs.com",
#   "@info.citi.com",
#   "@marcus.com",
#   "@notification.capitalone.com",
#   "@notify.wellsfargo.com",
#   "@pnc.com",
#   "@pncbank.com",
#   "@td.com",
#   "@tdbank.com",
#   "@truist.com",
#   "@usbank.com",
#   "@wellsfargo.com",
#   "@welcome.aexp.com",
# ]

# [[email.accounts]]
# virtual_key = "vk-email-001"
# email = "bot@gmail.com"
# app_password = "abcd efgh ijkl mnop"
# imap_host = "imap.gmail.com"
# For Outlook preset, use:
# imap_host = "imap-mail.outlook.com"
# For other providers, enter the provider IMAP host manually.
# imap_port = 993