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:
2026-05-01 14:59:57 -04:00
parent 4a9c4cc58b
commit 59927b6ad7
2 changed files with 23 additions and 0 deletions
+6
View File
@@ -171,6 +171,9 @@ def enforce_auth():
# Always allow non-API paths and auth namespace
if not path.startswith('/api/') or path.startswith('/api/auth/'):
return None
# Cell peer-sync endpoints authenticate via source IP + WG pubkey — not session
if path.startswith('/api/cells/peer-sync/'):
return None
# Only enforce when auth_manager has been properly initialised and seeded.
# When the user store is empty (file missing or unreadable — typical in
# unit tests and fresh installs), bypass enforcement so pre-auth test
@@ -225,6 +228,9 @@ def check_csrf():
path = request.path
if not path.startswith('/api/') or path.startswith('/api/auth/'):
return None
# peer-sync uses IP+pubkey auth — no session, no CSRF token possible
if path.startswith('/api/cells/peer-sync/'):
return None
token_session = session.get('csrf_token')
if not token_session:
# Session predates CSRF tokens (existing login) — issue a token now so