One session cookie across every subdomain
Why the session cookie uses __Secure- rather than __Host-, why SameSite=Lax is enough, and the rule it forces on the whole domain.
The app will live at app.pacestreak.com and the API at
api.pacestreak.com. For the app’s requests to carry the session, the
cookie has to be visible to both. That one requirement decides several
things.
Domain=pacestreak.com
A cookie without a Domain attribute is host-only: set by the API, it would
only go back to the API’s exact host. Setting Domain=pacestreak.com makes
it valid for every subdomain.
__Secure-, not __Host-
Cookie name prefixes let the browser enforce rules:
__Host-requiresSecure,Path=/and noDomainattribute.__Secure-requires onlySecure.
__Host- is the stronger lock, but it forbids exactly the attribute we need.
So the cookie is __Secure-, which still guarantees it is only ever set and
sent over HTTPS.
SameSite=Lax is enough
The app and API are different origins but the same site: they share
the registrable domain pacestreak.com. SameSite is about sites, not
origins, so a Lax cookie is sent on the app’s requests to the API. There is
no need for SameSite=None, which would also send it on requests started by
other sites and widen exposure for nothing.
CORS names its origin
Credentialed requests cannot use a wildcard CORS origin; browsers reject
Access-Control-Allow-Origin: * with credentials. The API lists the app’s
origin explicitly.
The rule this imposes
A cookie scoped to the whole domain is readable by every host under it. So
nothing untrusted may ever be hosted under pacestreak.com: no
user-generated subdomains, no third-party page on a vanity subdomain. That is
the price of one cookie, and it is written down so nobody pays it by
accident.
AlzyWelzy
Building PaceStreak. GitHub
Related
Security & PrivacyBuilding auth for an app that holds health data
RS256 access tokens held only in memory, rotating refresh tokens with reuse detection, CSRF on cookie transport, TOTP with replay protection, and the gaps we have written down rather than hidden.
4 min
Security & PrivacyNotification buttons without a session
A habit reminder now has Done and Snooze buttons. The service worker that handles them has no access token, by design, so each button carries a signed, single-purpose link instead.
2 min
Security & PrivacyFixing the dead ends in sign-up and verification
Three real bugs found by using the OTP flow the way a person actually would: a stuck login, a false 'already registered' error, and a confirmation screen that didn't lead anywhere. Plus a status page that finally watches the whole stack.
3 min