18987bbd2f
Expose the account-creation surface over the signed control plane:
- POST /invites, GET /invites (pending only), DELETE /invites/{token},
DELETE /users/{signpub}: all admin-only via requireAdmin (default-deny by role).
- POST /register: the wallet-model join path. It is the ONLY allowlist-mutating
route exempt from the admin signature, because the registering identity is not
yet in the allowlist and cannot sign — authorization is the bearer invite token.
It validates both public keys (sign_pub Ed25519, kex_pub X25519, 64-hex) BEFORE
spending the token, fixes handle/role from the invite (no client escalation),
and maps state errors to precise codes (unknown 404, used 409, expired 410,
already-registered 409).
Split isRateExempt (only /healthz) from isAuthExempt (/healthz + POST /register)
so /register skips the admin-signature middleware but stays per-IP rate limited.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>