← Chrome 147 reference · Device Bound Session Credentials
DBSC protocol reference · refresh exchange
Refresh exchange
The browser-blocking renewal flow that runs when an applicable declared cookie is missing. It carries an existing DBSC session ID, so terminal failures remove that existing client session rather than merely declining a new registration.
Wire sequence
1. Browser sees required sid absent for /account; it defers /account.
2. POST /dbsc/refresh
Sec-Secure-Session-Id: "session-42"
3. 403 Secure-Session-Challenge: "c2";id="session-42"
4. Browser retries POST /dbsc/refresh
Sec-Secure-Session-Id: "session-42"
Secure-Session-Response: "<refresh dbsc+jwt; no jwk; jti=c2>"
5. 200 Set-Cookie: sid=new-short; ... [optional replacement JSON]
6. Browser retries deferred /account with sid=new-short.Server inputs
Load state by Sec-Secure-Session-Id. First request may have no proof if there is no cached challenge. Issue a fresh 403 challenge or accept a valid cached-proof response. Verify the JWS with the registration public key; refresh proofs must not include a JWK. Retain a bounded set of recent nonces for concurrent/racing refreshes.
Outputs
A successful 2xx response sets every protected cookie that is currently missing/expired. It may have an empty body, preserving config, or a replacement JSON instruction body. A 403 asks for a proof only when it includes a usable challenge. Other response categories have lifecycle effects below.
Status, retries, and recovery
| Item | Requirement / behavior |
|---|---|
| Network error / 407 / 429 / 5xx | Draft treats as non-terminal; the existing session remains and the user agent may back off. Current Chromium has a transient refresh retry feature/implementation; no server may assume an exact retry count or delay. |
| 403 | A usable challenge can trigger a proof retry, but its grammar and session mapping are unresolved. The Editor’s Draft ordinary-response cache algorithm needs id to select a session; Chromium accepts a bare list member and Chrome guidance shows one. That cache-path id rule is not a settled universal 403 requirement; test enabled Chrome behavior. |
| Other 4xx | Draft terminates and removes the existing DBSC client session identified by Sec-Secure-Session-Id. Use only for deliberate revocation/terminal errors. |
| 3xx | Draft returns without updating session; redirect following is part of fetch setup, but do not use redirect chains as proof semantics. |
| Empty 2xx body | For refresh only, valid no-config-change in current Chromium; cookies may still be renewed. |
| Invalid JSON / continue false | Terminates and removes the existing client DBSC session; clear/revoke matching server state according to your logout policy. Unlike registration, this path has a non-null session ID. |
Context
Refresh is same-site with the originating deferred request and implicitly uses that request’s context/credentials. Keep CORS narrow and do not allow cross-origin credentialed direct calls; the draft’s implicit credentials design lets the refresh endpoint avoid broad Access-Control-Allow-Credentials. Reject framing with a suitable policy as the draft recommends.
Concurrency, proactive refresh, and replay
Browsers may refresh proactively, not only at expiry. The draft recommends only one pending refresh per session, but servers must still tolerate duplicates, delayed proofs for a recent challenge, and a signed-proof retry after transient failure. A terminal refresh outcome calls terminate with the existing non-null ID and removes that browser-held session; only network/407/429/3xx/5xx outcomes leave it in place. Atomically consume/challenge-track per session; issue replacement cookie tokens safely under concurrent refreshes.
Complete worked exchange
POST /dbsc/refresh HTTP/1.1
Host: app.example
Sec-Secure-Session-Id: "session-42"
HTTP/1.1 403 Forbidden
# Identified form: needed by the Editor’s Draft ordinary-response cache path;
# not a settled universal 403 grammar requirement.
Secure-Session-Challenge: "c-991";id="session-42"
POST /dbsc/refresh HTTP/1.1
Host: app.example
Sec-Secure-Session-Id: "session-42"
Secure-Session-Response: "<JWT typ=dbsc+jwt; alg=ES256; jti=c-991; signature=...>"
HTTP/1.1 200 OK
Set-Cookie: sid=rotated; Path=/; Max-Age=600; Secure; HttpOnly; SameSite=Lax
Cache-Control: no-store
# Empty body: retain existing instructions; Chrome retries the deferred request.
# Terminal refresh failure, unlike registration:
HTTP/1.1 401 Unauthorized
# The browser removes DBSC session "session-42". It does not retain or replace it.Compatibility
| Item | Requirement / behavior |
|---|---|
| Chrome | DBSC availability, not page-layout support: ChromeStatus lists DBSC as in development, with Chrome desktop milestone 145. Its Android milestone is null/unknown; availability remains controlled by implementation and feature configuration. |
| Firefox | No signal; the Mozilla standards-position issue is the public evidence, not an implementation commitment. |
| Safari | No signal; the WebKit standards-position issue is the public evidence, not an implementation commitment. |
| Other engines | Unknown. The W3C document is an Editor’s Draft, not a final interoperable Recommendation. |
Security and privacy
Challenge freshness and signature validation are mandatory server controls. Short cookie lifetimes set the theft window. Do not turn timing or distinct error bodies into a cross-origin login oracle. A companion bootstrap cookie is an optional deployment fallback, but must have narrower recovery privileges and its own theft risk assessment.
Primary sources: algorithms · challenge · response · sessionid · chrome · chromium · Chromium challenge parser · retry · security. External sources open in a new tab.