AttestoPhoenix.BrowserState (AttestoPhoenix v1.1.0)

Copy Markdown View Source

The OP browser-state cookie (OpenID Connect Session Management 1.0 §3.2).

Session Management binds the RP-visible session_state value to an opaque browser-scoped value at the OP origin — the OP User Agent state — so the check_session_iframe can recompute the hash purely in the browser. The spec's constraints shape the cookie exactly:

  • the iframe's JavaScript must read it, so it is not HttpOnly (§3.2);
  • the iframe is embedded cross-site (in the RP's page), so the cookie is SameSite=None; Secure or the browser would not send it to — or expose it inside — the third-party iframe context;
  • it is a __Host--prefixed cookie: the browser then rejects it unless it is Secure, Path=/, and carries no Domain attribute, so a sibling/parent-domain origin cannot inject or shadow it and logout (which expires the host cookie) fully clears it;
  • it changes when the End-User's login state at the OP changes: this module mints it when an authorization response is issued (login) and expires it at the end-session endpoint (logout), and rotates it whenever the login binding changes, so a recomputed session_state flips to changed.

The value is OP-owned and login-bound: it is not a bare random string but the integrity-protected random . login_tag . mac minted by Attesto.SessionState.mint_browser_state/2. ensure/3 only reuses an incoming cookie whose MAC verifies under the OP secret and whose login tag still matches the current authorization's login binding; otherwise it mints a fresh value. That defends two things at once: an injected/forged cookie cannot forge unchanged (its MAC will not verify), and a re-auth / account switch rotates the state (its login tag no longer matches) so earlier RP session_state values become changed (Session Management 1.0 §3.2).

The cookie name and lifetime come from AttestoPhoenix.Config's session_management: [browser_state_cookie: ..., browser_state_cookie_max_age: ...]; the OP secret is session_management: [browser_state_secret: ...] (required when session management is enabled).

Summary

Functions

The request's browser-state cookie value, or nil.

Ensure the OP browser-state cookie exists and is current for login_binding.

Expire the browser-state cookie (logout — §3.2: the OP browser state changes when the End-User's login state does). A subsequent check_session_iframe recomputation hashes over the empty state and yields changed.

Functions

current(conn, config)

@spec current(Plug.Conn.t(), AttestoPhoenix.Config.t()) :: String.t() | nil

The request's browser-state cookie value, or nil.

ensure(conn, config, login_binding)

Ensure the OP browser-state cookie exists and is current for login_binding.

Reuses the incoming cookie only when it is a value this OP minted (MAC verifies under the configured secret) that is still bound to the current login state; otherwise mints a fresh value and sets the response cookie. login_binding is a stable string derived from the current authorization's resolved login identity (subject / auth_time / sid). Returns {conn, value}.

expire(conn, config)

Expire the browser-state cookie (logout — §3.2: the OP browser state changes when the End-User's login state does). A subsequent check_session_iframe recomputation hashes over the empty state and yields changed.