Skip to content

Security

chatwire's security model is: gate access at the network layer, use the web UI password as a second layer, and rely on the anti-spam fuse to prevent abuse.

Network access

By default the web UI has no authentication — anyone who can reach the URL can read and send messages. The intended posture is:

  • LAN only — bind chatwire to 127.0.0.1 (default) and don't expose the port externally
  • Tailscale — expose the Mac via Tailscale; only your devices can reach it
  • Cloudflare Access — put chatwire behind a Cloudflare tunnel with an Access policy

Configure the listen address in ~/.chatwire/config.json:

{
  "web": {
    "bind": "127.0.0.1",
    "port": 8723
  }
}

Setting bind to 127.0.0.1 means only requests from the Mac itself can reach chatwire directly. Pair with Tailscale or a reverse proxy for remote access.

Web UI password

Set an optional shared password for the web UI:

Settings → Security → Web UI password

Or during first-run setup (Step 4 of the wizard).

Details: - Single password (not multi-user) - Stored as PBKDF2-SHA256 in ~/.chatwire/config.json (mode 600) - Sessions use signed cookies that expire after 30 days (sliding refresh for active sessions)

Forgot your password? Stop the web agent, edit ~/.chatwire/config.json, remove the web.auth block, and restart. No reset flow needed because the file is already protected by your Mac's user account.

# Find and remove the web.auth block:
nano ~/.chatwire/config.json
# Delete the "auth": {...} section under "web"

# Restart the web agent:
launchctl kickstart -k gui/$(id -u)/dev.chatwire.web

Login rate limiting

The login endpoint has built-in rate limiting — repeated failed attempts are throttled. This is a minor defense against online brute-force; the main protection should be network-layer access control.

API keys

For programmatic access (MCP, scripts, automations), use API keys instead of the session password:

Settings → Security → API Keys → Generate new key

API keys have format cwk_<hex>. Use as a Bearer token:

curl -H "Authorization: Bearer cwk_yourkeyhere" \
  http://localhost:8723/api/conversations

Keys are scoped: - read — read conversations and messages - write — send messages

Revoke a key from Settings → Security → API Keys → click the key → Revoke.

Anti-spam fuse

The fuse prevents runaway outbound sends — protecting your iMessage account if the web UI is compromised or an automation rule goes wrong.

Fuse steps

Step State What you see
0 Normal Nothing
1 Counting Send count tracked
2 Soft cooldown Amber banner, countdown timer
3 Hard cooldown Amber banner, longer countdown
4 Lockout Red warning bar, compose box locked
5 Extended lockout Same, longer cooldown
6 Permanent lockout Unlock code required

Fuse state file

The fuse state is stored in ~/.chatwire/fuse_state.json:

{
  "step": 0,
  "cooldown_until": null
}

Unlocking the fuse

At step 4+, a red LockoutTopBanner appears on every page with: - The current fuse step and cooldown duration - A field to enter an unlock code

The unlock code is stored in ~/.chatwire/lockout.json. Access it from the Mac's terminal:

cat ~/.chatwire/lockout.json

Enter the code in the web UI to reset the fuse to step 0.

To unlock without the web UI:

# Edit fuse_state.json directly:
echo '{"step": 0, "cooldown_until": null}' > ~/.chatwire/fuse_state.json

# Restart the bridge:
launchctl kickstart -k gui/$(id -u)/dev.chatwire.bridge

Configuring fuse thresholds

Fuse thresholds are configured in Settings → Anti-spam. The defaults are tuned for normal personal messaging — lower them if you want a stricter guard, raise them if automation rules legitimately send at a higher rate.

Data exposure warning

On first launch, chatwire shows a dismissable modal explaining which data it accesses:

  • Reads ~/Library/Messages/chat.db (your full iMessage history)
  • Reads Contacts.app (for name resolution)
  • Sends messages via Messages.app

The modal is not shown again after you click I understand. If you want to see it again, clear ~/.chatwire/read_state.db.

Privacy

  • Zero telemetry — chatwire sends no analytics, crash reports, or usage data. No third-party SDKs.
  • Data stays on your Mac — your messages, contacts, and chat.db never leave your machine unless you explicitly configure a relay (Telegram, ntfy, webhook, etc.)
  • Update check — once per day, chatwire fetches api.github.com/repos/allenbina/chatwire/releases/latest to surface new-version notices. Disable by setting UPDATE_CHECK_REPO="" in the launchd agent's environment.

See the privacy policy for full details.

Security audit status

chatwire is in active development and has not undergone a formal third-party security audit. Use it on a trusted network or behind Cloudflare Access / Tailscale. Security improvements are tracked in the GitHub issues.