Authentication (account API)

The dashboard session-cookie auth model, the 8s timeout, origin enforcement, and sanitized error forwarding for /dashboard/api/dashboard/* routes.

The account-management API (/dashboard/api/dashboard/*) authenticates with the dashboard session cookie — the same cookie issued during passwordless login. The proxy reads the cookie, injects it as the X-Session-Token header, and forwards the request to the backend. The public-API key (X-API-Key) is not accepted on any account-management route.

Every route under /dashboard/api/dashboard/* requires the session cookie. The full route catalog — grouped by resource (User, Apps, Credentials, Groups, Notifications, Billing, Configuration) — is in Account API reference.

When you authenticate via the passwordless flow (send /signin from Signal, SimpleX, or Session; receive an 8-character code; enter it at the access-code page), the backend issues a session token and sets it as an HTTP-only cookie named session.

A missing or expired session cookie returns 400 { success: false, error: "Session token is required" }. Every account-management route requires the cookie; there is no anonymous read access.

The proxy forwards the session cookie value as the X-Session-Token header to the backend. The cookie value is the session token — the proxy moves it from one HTTP mechanism to another so the backend’s auth middleware can match it. No re-wrapping, no decryption, no intermediate transformation.

Request timeout

Outbound calls to the backend time out at 8 seconds. A backend response exceeding 8 seconds returns 504 Gateway Timeout. Network failures (DNS, connection refused) return 502 Bad Gateway. Both are returned as JSON { error: "..." } with a sanitized message — never raw exception text or stack traces.

Allowlist-only routing

Every writable route is an explicit entry on the proxy’s allowlist. Requests to paths outside the allowlist return 404. The proxy has no ?url= passthrough, no OPTIONS handler, and no catch-all. The route catalog is documented in Account API reference.

Origin enforcement

POST, PUT, and DELETE requests must be same-origin. The proxy checks the Origin header against the request host and returns 400 { error: "Cross-origin requests are not allowed" } on mismatch.

A missing Origin header is permitted — non-browser clients (scripts, CI workers) that omit Origin pass the check. Scripts that send Origin: https://privacyflow.app (or omit it) work fine.

Error forwarding

The proxy forwards backend JSON error bodies verbatim when parseable — real messages like "name is required" or "credential not found" reach the client. Non-JSON responses are replaced with a generic "Backend request failed (status)" message. HTTP status codes pass through: a backend 404 returns 404 to the client.

Scripting the account-management API

  1. Authenticate once via the passwordless flow and capture the session cookie. The cookie is HTTP-only — capture it from the dev-tools Application → Cookies panel or from the Set-Cookie response header during sign-in.
  2. Send the cookie as a Cookie: session=... header on every call to /dashboard/api/dashboard/*.
  3. Re-authenticate on 400 { error: "Session token is required" } or any 401. Cookies expire; there is no refresh token.

List apps

SESSION='session=xyz123abc...'
curl -s "https://privacyflow.app/dashboard/api/dashboard/apps" \
  -H "Cookie: $SESSION" \
  -H "Accept: application/json"

Returns the items[] array with one entry per app.

Create an app

curl -s -X POST "https://privacyflow.app/dashboard/api/dashboard/apps" \
  -H "Cookie: $SESSION" \
  -H "Origin: https://privacyflow.app" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support — Signal",
    "protocol": ["signal"],
    "deliveryType": "poll",
    "status": "active"
  }'

POST, PUT, and DELETE require the Origin header set to the dashboard host (or any same-origin value). Content-Type: application/json is required on all POST/PUT/DELETE requests, including those with an empty body.

Session security

The session cookie carries full dashboard authority — app creation, credential rotation, billing, and account mutations. Public-API keys are scoped to the messaging surface (/api/v1/*) and have no path into /dashboard/*.

Treat the session cookie as a long-lived privileged credential:

  • Store it in a secrets manager, not in source control or logs.
  • Scope it to the smallest set of scripts that require account mutations.
  • Rotate it (sign out + re-authenticate) on any suspected exposure.

Warning

The session cookie grants the same authority as a dashboard login. A leaked cookie allows an attacker to create credentials, delete apps, modify billing, and rotate account state. Rotate immediately on exposure.

Last updated: