feat(auth): session/proxy auth for Wiki.js buttons; drop browser API key
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 2m12s

The wikijs-integration.js embedded a full-privilege API key that was
served to every wiki visitor — it unlocked all 66 authenticated
endpoints, including page/vector deletes and index purges. That key
has been rotated out of service.

The two browser endpoints (/ingest/page, /entity-linking/link-page)
now authenticate via the NPM /library-desk/ proxy location instead of a
key: Authentik forward-auth for external users, LAN bypass for internal,
verified by a trusted proxy marker header. This is safe because
library-desk binds loopback-only, so NPM is the sole path that can set
that header. The browser holds no secret; the script calls same-origin
with credentials. Machine callers (the Scheduler) keep the Bearer key
on the container-network endpoints. verify_api_key now compares in
constant time.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 09:02:02 +02:00
co-authored by Claude Fable 5
parent f5983c379f
commit c5f90cdb4f
8 changed files with 132 additions and 16 deletions
+4 -2
View File
@@ -12,19 +12,21 @@ import pytest
from fastapi.testclient import TestClient
from src.main import app
from src.core.dependencies import verify_api_key
from src.core.dependencies import verify_api_key, verify_browser_request
@pytest.fixture(scope="module")
def client():
"""TestClient with API-key auth stubbed out (no lifespan startup)."""
"""TestClient with auth stubbed out (no lifespan startup)."""
app.dependency_overrides[verify_api_key] = lambda: "test-key"
app.dependency_overrides[verify_browser_request] = lambda: "test-user"
try:
# No context manager: startup/lifespan events are NOT triggered,
# so no connections to external services are attempted.
yield TestClient(app)
finally:
app.dependency_overrides.pop(verify_api_key, None)
app.dependency_overrides.pop(verify_browser_request, None)
QUERY_PARAM_ENDPOINTS = [