fix: whitelist peer-sync endpoint from session auth + CSRF
/api/cells/peer-sync/permissions is called over the WireGuard tunnel by remote cells — they have no session cookie and cannot produce a CSRF token. The endpoint authenticates via source IP (must be in the remote cell's vpn_subnet) and WireGuard public key instead. Without this, the global enforce_auth hook returns 401 before the route handler runs, so all cross-cell permission pushes fail even when the WG tunnel and iptables rules are correct. Also adds a test verifying the route can be reached without a session. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -205,3 +205,20 @@ def test_anon_can_reach_auth_namespace(anon_client):
|
||||
# 401 is expected here but it must originate from the route, not a redirect/block
|
||||
# on a non-auth path. The response should be JSON, not a redirect (3xx).
|
||||
assert r.status_code not in (301, 302, 403)
|
||||
|
||||
|
||||
def test_anon_can_reach_peer_sync_endpoint(anon_client):
|
||||
"""POST /api/cells/peer-sync/* must not be blocked by session auth.
|
||||
|
||||
The peer-sync endpoint authenticates via source IP + WireGuard pubkey.
|
||||
It must not return 401/403 from the global enforce_auth hook — the route
|
||||
handler itself produces any rejection.
|
||||
"""
|
||||
r = anon_client.post(
|
||||
'/api/cells/peer-sync/permissions',
|
||||
json={},
|
||||
content_type='application/json',
|
||||
)
|
||||
# 400 (bad payload) or 403 (IP/pubkey rejected) are acceptable — 401 from
|
||||
# the global auth hook is NOT acceptable because the route has its own guard.
|
||||
assert r.status_code != 401
|
||||
|
||||
Reference in New Issue
Block a user