Skip to content

v1.2.3

Choose a tag to compare

@thebriangao thebriangao released this 01 Jun 06:50
· 11 commits to main since this release

A security-hardening release — no API or tool changes, fully behavior-compatible. Came out of a full codebase security audit.

Secrets at rest

  • Token files (.env + token store) are written 0600 (owner-only), with a chmod repair so files from older versions get tightened.
  • Your Whoop password is removed from .env after a successful login — it was only ever needed for the one bootstrap call.
  • Deploy/rotation secrets are pushed to Fly over stdin (secrets import), not argv — no longer visible in ps//proc.

HTTP auth server

  • OAuth JWTs are signed with a key derived from MCP_AUTH_TOKEN (HMAC), not the token itself.
  • Access tokens are audience-bound (RFC 8707): a token's resource claim must match this server's /mcp URL.
  • Security headers on every response (X-Frame-Options: DENY, nosniff, CSP) — the connector password form can no longer be framed (clickjacking).
  • Connector-password gate gets a global brute-force ceiling (independent of the spoofable per-IP key) and a 16-char + character-class floor for user-chosen passwords.
  • whoop-mcp cloud now verifies the auth gate post-deploy (asserts unauthenticated /mcp → 401).

Traffic realism

  • whoop_compare / whoop_lift_history fan-outs are paced (≤3 concurrent, jittered) instead of one simultaneous burst; whoop_coach_ask polls on a jittered interval, not a fixed 1.000 s metronome.
  • Read-only hosts derive a stable install id from the account email; a boot warning fires if the bundled iOS app version goes stale.

.gitignore now excludes every .env* variant; .dockerignore excludes .env* + the deploy record. Full detail in CHANGELOG.md and SECURITY.md.