DE EN

Journal

A strict cookie and a new domain

After EAuth moved to its own domain, signing in to our console led back to the sign-in page. Why a SameSite=Strict cookie does that, and what it means for you.

Samuel Krauss, Founder · · 4 min read

Moving EAuth to eauth.me broke signing in to our own console in a way that looked like nothing at all: you signed in, and landed on the sign-in page again. We found it eight days before the move went live, and fixed it then. The cause is worth writing down, because anybody who signs in with EAuth and keeps a strict session cookie will meet the same thing.

What happened

Signing in to the console goes like this. The console sends you to EAuth, EAuth checks your password and sends you back to the console's callback address with a code. The callback exchanges the code, sets the console's session cookie, and sends you on to the console itself.

The console's session cookie is SameSite=Strict, and so is the dashboard's. A strict cookie is only sent with a request that the same site started. It is never sent when another site starts the navigation, not even for a plain link. That is a deliberate choice for an administrative surface: no page anywhere else can make your browser act in the console while you are signed in.

While EAuth lived on auth.elchi.dev, EAuth and the console were the same site, because a browser decides "same site" by the registrable domain, elchi.dev, not by the full host name. On eauth.me they are not. The navigation back to the callback is now started by eauth.me. The callback set the cookie and answered with a redirect to the console, and the browser sent that next request without the cookie. A redirect from our own server did not change who had started the navigation. The console saw no session and showed the sign-in page.

What we changed

There are three usual answers.

  • Make the cookie Lax. A lax cookie goes along with a top-level navigation from another site, so the redirect would carry it. For most applications that is the right default. For our console and dashboard we wanted to keep strict.
  • Use two cookies, a lax one that only says "someone is signed in" and a strict one for anything that changes something. Solid, and more moving parts than we needed.
  • End the callback on a page of our own. The callback sets the cookie and answers with a small page that moves on by itself. A navigation that page starts is one the console's own site started, so the strict cookie goes with it.

We chose the third. The page has a refresh instruction and a plain link, no script, and it is on screen for as long as one request takes. It only ever sends the browser to a path on the console's own host: anything else it is given becomes the start page, and the check for that is in the code rather than left to the template. The page sends no referrer and is never cached.

The cost is small: the callback answers with a few lines of HTML instead of a redirect, and a browser that ignores the refresh shows a link to click. Giving up strict cookies on the console would have cost more, just less visibly.

If you build on EAuth

Since 3 October 2026, auth.elchi.dev only redirects to eauth.me, so every application signing in with EAuth is on a different site from EAuth. Three things follow.

  1. A strict session cookie behaves like ours did. Set it in the callback and then redirect, and the next request arrives without it. Either use Lax, or end the callback on a page that navigates on.
  2. Whatever you store before sending somebody to EAuth, the state and the PKCE verifier, has to come back on that cross-site navigation. In a cookie, that means Lax. Our SDK keeps them in session storage, which has no such rule: it belongs to the tab, and the tab is the same one that comes back.
  3. Signing out works the same way in the other direction: send the browser to EAuth's end_session_endpoint with the ID token you hold as id_token_hint, and it comes back to the post-logout address you registered. Without the hint, EAuth asks the person before it signs them out, and does not send them on to an address it cannot check.

EAuth's own session cookie is Lax for exactly the first reason: it has to arrive when an application sends somebody to sign in, and that navigation is always started by another site. The forms on EAuth's pages do not rely on that alone. Each carries a token derived from the session, and has to be posted from eauth.me itself.

Sources

  1. Set-Cookie header, SameSite, MDN, read
  2. Cookies: HTTP State Management Mechanism (draft-ietf-httpbis-rfc6265bis), IETF, read
  3. Site (glossary), MDN, read
  4. OpenID Connect RP-Initiated Logout 1.0, OpenID Foundation, read

How can we help?

Call us +41 58 513 63 11 · Weekdays 8 to 18, usually straight away Write to us contact@elchi.dev · A reply within two working days Talk for 15 minutes No commitment, no preparation What does it cost? CHF 6,000. Then CHF 300 a month.