I built Birdcage because I wanted to access my claw from anywhere without handing auth to a third party or punching holes in my home network.
Birdcage sits on a VPS and handles auth + reverse proxying. The connection back home runs over WireGuard — the VPS only sees opaque packets. The agent manages its own WireGuard interface, discovers endpoints via STUN, and falls back to relay when direct UDP fails.
Auth uses PBKDF2 with adaptive proof-of-work on brute force, JWT dual-token pattern with sliding session expiry, and WireGuard key rotation on a configurable interval. Single binary, pure Go, no CGO.
Pretty sure all those are covered, upon more careful review. PRs open!
Edit: The create account I hadn't thought of for the email enum. Thanks!
Edit 2: Fixed up two schema issues identified and the last mitigated already via call: await passwords.rejectPasswordWithConstantTime(validatedData.password)
Birdcage sits on a VPS and handles auth + reverse proxying. The connection back home runs over WireGuard — the VPS only sees opaque packets. The agent manages its own WireGuard interface, discovers endpoints via STUN, and falls back to relay when direct UDP fails.
Auth uses PBKDF2 with adaptive proof-of-work on brute force, JWT dual-token pattern with sliding session expiry, and WireGuard key rotation on a configurable interval. Single binary, pure Go, no CGO.