1. Introduction
This section is not normative.
Note this is a very early drafting for writing collaboration only
The web is built on a stateless protocol. To provide required functionality, web applications store data locally on a user’s computer. This is used for logged in user sessions that can last for a long time.
In general user agents do not have a secure way of storing data supporting these activities across commonly used operating systems, and actions authenticated by this data may have serious consequences, for example transferring money from a bank account.
This document defines a new API, Device Bound Sessions Credentials (DBSC), that enables the server to verify that a session cannot be exported from a device by using commonly available TPMs, or similar APIs, that are designed for this purpose.
The goal is to provide users with a safe and secure experience, while offering the use cases users are already used to. At the same time we want to ensure that the users privacy is respected with no new privacy identifiers being leaked by this protocol.
1.1. Examples
Device Bound Session Credentials are designed to make users more secure in different situations. Some of the use cases of DBSC are:1.1.1. Signed in session
1.1.2. Device integrity
1.1.3. Device reputation
payment.example.com
could create a session
bound to when users visit commercial site shopping.example.com
. It could
track the reliability of the device over time to decide how likely a
transaction is legitimate. 2. Security Considerations
The goals of DBSC are to reduce session theft by offering an alternative to long-lived cookie bearer tokens and to allow session authentication to be bound to the user’s device. This makes the internet safer for users in that it is less likely their identity is abused, as malware is forced to act locally and thus becomes easier to detect and mitigate. At the same time the goal is to disrupt the cookie theft ecosystem and force it to adapt to new protections long term.As long as the session is valid and was registered to an uncompromised device, a host can know with cryptographic certainty that it is on the same device as the one the session was originally bound to.
In order to ensure this, session private keys should be stored in a way that cannot be exfiltrated by locally running malware, whenever possible.
2.1. Non-goals
DBSC will not prevent temporary access to the browser session while the attacker is resident on the user’s device. The private key should be stored as safely as modern operating systems allow, preventing exfiltration of the session private key, but the signing capability will likely still be available for any program running as the user on the user’s device.DBSC will also not prevent an attack if the attacker is replacing or injecting into the user agent at the time of session registration as the attacker can bind the session either to keys that are not TPM bound, or to a TPM that the attacker controls permanently.
DBSC is not designed to give hosts any sort of guarantee about the specific device a session is registered to, or the state of this device.
3. Privacy Considerations
The goal of the DBSC protocol is to introduce no additional surface for user tracking: implementing this API (for a browser) or enabling it (for a website) should not entail any significant user privacy tradeoffs.Some of the consideration taken to ensure this:
-
Lifetime of a session/key material: This should provide no additional client data storage (i.e., a pseudo-cookie). As such, we require that browsers MUST clear sessions and keys when clearing other site data (like cookies).
-
Implementing this API should not meaningfully increase the entropy of heuristic device fingerprinting signals. In particular, DBSC should not leak any stable TPM-based device identifier.
-
As this API MAY allow background "pings" for performance, this must not enable long-term tracking of a user when they have navigated away from the connected site.
-
Each session has a separate new key created, and it should not be possible to detect that different sessions are from the same device.
3.1. Cookies considerations
It should be impossible for a site to use this API to circumvent the same origin policy, 3P cookie policies, etc. Due to the complexity of current and changing cookie behavior and the tight integration between DBSC and cookies, the current solution is that each user agent should use the same policy for DBSC as it uses for cookies. If the DBSC cookie credential would not apply to a network request based on user settings, applied policies, or user agent implementation details, neither would any of the additional DBSC behavior. This ensures no new privacy behavior due to implementing DBSC.3.2. Timing side channel leak
If third party cookies are enabled it is possible for an attacker to leak whether or not a user is authenticated by measuring how long the request takes as the refresh is quite slow, partially due to the latency of TPM operations.This is mitigated by the allowed_refresh_initiators
field in session
configuration, which can be used to strictly limit the sites that can trigger
DBSC refreshes. This cannot be replaced by existing solutions
(e.g. X-Frame-Options) because the existing solutions only apply after the
request has completed, and DBSC must choose whether to refresh before the
request has started.
4. Alternatives considered
4.1. WebAuthn and silent mediation
5. Server considerations
In order to use DBSC, site owners need to establish two new endpoints: the registration endpoint and the refresh endpoint.
The registration endpoint is contacted asynchronously after the browser receives the Secure-Session-Registration header. This endpoint should:
-
Serve the session config, including a new session id.
-
Persist and associate the request’s public key with the session id.
The refresh endpoint is much more sensitive. This endpoint is contacted every time a request is made with an expired bound cookie, and its response blocks the original request. Failure to respond or restore the bound cookie may cause browser agents to begin denial-of-service prevention mechanisms, or even terminate the session. Both could lead to future requests without bound cookies. The expected behavior of this endpoint is:
-
Look up the public key and recent challenges for the session by id.
-
Validate the Secure-Session-Response header has signed a recent challenge with the correct key. Note that due to network latency and race conditions, it’s possible to receive a signature for an old challenge after issuing a new challenge.
-
Issue new bound cookies.
-
Serve the current session config.
The refresh endpoint is likely to directly leak login state if cross-site
fetches are allowed. Servers can check for a valid Sec-Secure-Session-Id header
to ensure that incoming requests are initiated by the user agent and not a
cross-site request. It’s also recommended to set a narrow CORS policy on this
endpoint, not allowing cross-site origins to make requests with credentials. The
CORS integration has been designed to make this possible by implicitly including
credentials when the deferred request does. For similar reasons, it’s also
recommended that the refresh endpoint refuse to be embedded via the X-Frame-Options
or Cross-Origin-Resource-Policy
headers.
example.com
has two endpoints:
-
/authenticated
will returnAccess-Control-Allow-Credentials
for any requesting origin. -
/refresh
is the the DBSC refresh endpoint.
The site wants DBSC to protect cross-site requests to /authenticated
, and
believes that the risk from timing side channels on this one endpoint are
minimal. If we did not implicitly allow credentials for the refresh request
triggered by the user agent, then /refresh
would be required to return Access-Control-Allow-Credentials
for any requesting origin. Now attackers can
very directly leak login state by fetching /refresh
directly.
By implicitly allowing credentials, the /refresh
endpoint can refuse to ever
return Access-Control-Allow-Credentials
. It will still receive credentialled
requests in the context of a DBSC refresh. Other sites will be unable to
directly fetch the endpoint with credentials, preventing an easy cross-site leak
of login state.
6. Framework
This document uses ABNF grammar to specify syntax, as defined in [RFC5234] and updated in [RFC7405], along with the#rule
extension defined in Section 7 of [RFC9112], and the quoted-string
rule defined in Section 3.2.6 of the same document.
This document depends on the Infra Standard for a number of foundational concepts used in its algorithms and prose [INFRA].
6.1. Session store
The user agent maintains a session store. It is an ordered map from registrable domain to session by id.6.2. Sessions by id
A session by id is an ordered map from session identifier to device bound session for a given registrable domain.6.3. Device bound session
A device bound session is a struct with the following items:- session identifier
-
a string that is a unique identifier of a session on an registrable domain
- refresh URL
-
a string that is representing the URL to be used to refresh the session
- cached challenge
-
a string that is to be used as the next challenge for this session
- session scope
- session credentials
-
a list of session credentials used by the session
- expiration timestamp
-
a moment when this session should be removed.
- session key
-
a key pair used by the session. The private key should be stored in a secure manner, see § 2 Security Considerations.
- allowed refresh initiators
-
a list of strings describing which hosts are allowed to initiate DBSC refreshes due to non-CORS requests. See § 7.3 Identify if a request is allowed to refresh for details.
6.4. Session scope
The session scope is a struct with the following items:- origin
-
The origin this session was registered for.
- include site
-
a boolean indicating if the session applies to an entire site or just an origin.
- scope specifications
-
a list of scope specifications used by the session
6.5. Scope specification
The scope specification is a struct with the following items:- type
-
a string to be either "include" or "exclude", defining if the item defined in this struct should be added or removed from the scope
- host
-
a string defining the domain or domain pattern that must match for this scope specification to apply.
- path
-
a string that defines the path part of this scope specification
6.6. Session credential
The session credential is a struct with the following items:- name
-
a string that defines the name of the credential cookie
- attributes
-
a string that defines the other attributes of the credential cookie
7. Algorithms
7.1. Identify session
Given a URL (url) and session identifier (session identifier), this algorithm returns a device bound session or null if no such session exists.
-
Let domain be the registrable domain of url’s host.
-
Let domain sessions be the user agent’s session store[domain] as a session by id
-
Return domain sessions[session identifier]
7.2. Identify if a URL is in scope of a session
-
Let scope be session’s session scope.
-
If scope’s include site is true, return "exclude" if URL’s origin is not same site with scope’s origin.
-
If scope’s include site is false, return "exclude" if URL’s origin is not same origin with scope’s origin.
-
If the URL matches the session’s refresh URL, return "exclude".
-
for each scope specification in scope’s scope specifications:
-
Return "include".
7.3. Identify if a request is allowed to refresh
-
If session’s session scope’s include site is true, and request’s origin is same site with session’s session scope origin, return "allowed".
-
If session’s session scope’s include site is false, and request’s origin is same origin with session’s session scope origin, return "allowed".
-
for each initiator pattern in session’s allowed refresh initiators:
-
If running § 7.4 Identify if a host matches a pattern on request’s origin’s host and initiator pattern returns true, return "allowed".
-
-
Return "disallowed".
7.4. Identify if a host matches a pattern
-
If pattern equals '*', return true.
-
If pattern starts with '*':
-
If pattern does not start with '*.', return false.
-
Return true if host ends with all but the first character of pattern.
-
-
Return true if host is equal to pattern.
7.5. Identify session needing refresh
-
Let domain be the registrable domain of the request’s url’s host.
-
Let domain sessions be the user agent’s session store[domain] as session by id
-
For each session of domain sessions
-
If session’s expiration timestamp is before the present, remove session from domain sessions and continue.
-
Let id be session’s session identifier.
-
If the tuple (domain, id) is in request’s deferred device bound session ids, continue.
-
Run the steps in § 7.2 Identify if a URL is in scope of a session on request’s URL and session.
-
If the result does not indicate the request is in scope, continue.
-
Run the steps in § 7.3 Identify if a request is allowed to refresh on request and session.
-
If the result is not "allowed", continue.
-
If the result of running § 7.6 Identify missing session credential on request and session’s session credentials is false, continue.
-
Add (domain, id) to request’s deferred device bound session ids.
-
Return session.
-
-
If no session has been identified, return null.
7.6. Identify missing session credential
-
for each credential in credentials
-
If a cookie with credential’s attributes would not be attached to request (see section 5.4 of [COOKIES]), continue.
-
If request’s header list contains a cookie that satisfies all of the following conditions, continue:
-
cookie’s name matches credential’s name
-
All of the following attributes of cookie match those in credential’s attributes: Domain, Path, Secure, HttpOnly, SameSite.
-
cookie’s partition key matches that of credential.
-
-
Return true.
-
-
Return false.
7.7. Cache challenge
Given a response (response), this algorithm updates the cached challenge for a device bound session.
-
Let header name be "
Secure-Session-Challenge
". -
Let challenge list be the result of executing get a structured field value given header name and "list" from response’s header list.
-
If challenge list is null, return.
-
For each (challenge, params) of challenge list:
-
Let session id be null.
-
If params["id"] exists and is an sf-string, set session id to params["id"].
-
If session id is null, continue.
-
Let session be the result of running § 7.1 Identify session given response’s URL and session id.
-
If session is null, continue.
-
Store challenge as session’s cached challenge to be used next time a DBSC proof is to be sent from this device bound session.
7.8. Send request
-
The browser MAY skip this request in order to prevent denial of service for the user or site. For example, this might happen if this session is requesting excessive TPM operations (harming the user) or the refresh endpoint has recently been unreachable (denial of service risk for the site). If the browser chooses to do this, it should perform the steps of § 7.10 Add debug header with originating request, an appropriate token (see options in § 8.5 Secure-Session-Skipped HTTP header field), and session id to indicate this to the site.
-
Let terminate the session be an algorithm with the following steps:
-
If session id is null, return.
-
Remove the session with domain destination’s host’s registrable domain and identifier session id from the user agent’s session store, if such a session if found.
-
-
If originating request’s URL’s origin is not same site with destination’s origin, return.
-
Let signed challenge be null. If challenge is non-null, sign it with key pair and store the result in signed challenge.
-
Create a request for use in HTTP fetch.
-
Set request’s method to "POST".
-
Set request’s URL to destination.
-
Set request’s redirect mode to "follow".
-
If signed challenge is non-null, append the header ("Secure-Session-Response", signed challenge) to request’s header list.
-
If authorization is non-null, append the header ("Authorization", authorization) to request’s header list.
-
Let response be the result of running HTTP fetch for request.
-
If response is a network error, or response’s status is 407 or 429, return.
-
If response’s status is at least 300 and below 400, then return.
-
If response’s status is 403:
-
If session id is null, return.
-
Let session be the result of running the steps of § 7.1 Identify session on destination and session id.
-
If session is null, return.
-
Otherwise, restart this algorithm with the original inputs, except replacing challenge with session’s cached challenge.
-
-
If response’s status is at least 400 and below 500, then terminate the session and return.
-
If response’s status is at least 500, then return. Browsers may choose to trigger a backoff mechanism on subsequent refresh requests on this session, to limit the harm of a temporary outage on the refresh endpoint.
-
If session id is non-null, and response’s body is empty, return.
-
Parse response’s body according to § 8.6 DBSC Session Instruction Format. If parsing fails, terminate the session and return.
-
Let session identifier be the value of key "session_identifier".
-
If the response JSON contains the key "continue", with value "false", terminate the session and return.
-
Otherwise, perform the following validations. If any fail, terminate the session and return.
-
session identifier must be non-empty.
-
If session id is non-null, it must match session identifier.
-
The value of the key "refresh_url" must be non-empty.
-
Let origin be an origin constructed from the value of the key "scope.origin", if present, or the origin of destination if not.
-
origin must be a valid non-opaque origin.
-
Let refresh URL be the result of resolving destination with the value of the key "refresh_url".
-
refresh URL must have scheme HTTPS or be localhost.
-
refresh URL’s origin must be same site with destination’s origin.
-
-
Let destination domain be the registrable domain of destination’s host.
-
If the value of the key "scope.include_site" in response is true, perform the following validations. If any fail, terminate the session and return.
-
origin’s domain must be equal to destination domain.
-
If destination domain is equal to the host of destination, skip all remaining validations.
-
Otherwise, let well known URL be a copy of destination, with the host replaced with destination domain, and the path replaced with "/.well-known/device-bound-sessions".
-
Let well known response be the result of fetching well known URL.
-
well known response’s status must be 200.
-
well known response’s body must be a JSON-encoded list of strings.
-
well known response’s body must include the origin of destination.
-
-
Let existing session be the value of the user agent’s session store[destination domain][session identifier], or null if no such session exists.
-
Let session be a new session with:
-
session identifier set to session identifier.
-
refresh URL set to refresh URL.
-
session scope a new scope with origin origin, include site the value of the key "scope.include_site", and scope specifications the value of the key "scope.scope_specification".
-
session credentials the value of the key "credentials".
-
If existing session is non-null, set session key to existing session’s session key.
-
Otherwise set session key to a newly-generated key pair.
-
allowed refresh initiators the value of the key "allowed_refresh_initiators".
-
-
Call terminate the session to remove the existing session.
-
Set the user agent’s session store[destination domain][session identifier] to session.
7.9. Create session
-
Let header name be "
Secure-Session-Registration
". -
Let registration list be the result of executing get a structured field value given header name and "list" from response’s header list.
-
If registration list is null, return.
-
For each registration entry, params → registration list:
-
If registration entry is not an sf-inner-list, continue.
-
Let algorithm list be an empty list.
-
For each algorithm → registration entry
-
If algorithm represents a crypto algorithm supported in `
Secure-Session-Registration
`, and is supported on this client, add algorithm to algorithm list
-
If algorithm list is empty, continue.
-
If params["path"] does not exist, or is not of type sf-string, continue.
-
Let path be params["path"].
-
Let challenge be null, and Let authorization be null.
-
If params["challenge"] exists and is of type sf-string Set challenge to params["challenge"].
-
If params["authorization"] exists and is a string Set authorization to params["authorization"].
-
Create a key pair for algorithm list.
-
Let endpoint be the result of resolving path relative to the response’s URL.
-
Call § 7.8 Send request with request, key pair, endpoint, null session identifier, challenge and authorization.
-
7.10. Add debug header
-
Let value be an sf-token with value token.
-
Set the sf-parameter "session_identifier" on value to session id.
-
Let skipped header value be the result of running the steps of get a structured field value with header name "Secure-Session-Skipped", type "list", and request’s header list.
-
If skipped header value is null, set it to an empty sf-list.
-
Append value to skipped header value.
-
Run the steps of set a structured field value given ("Secure-Session-Skipped", skipped header value) on request’s header list.
8. DBSC Formats
8.1. `Secure-Session-Registration
` HTTP header field
The ` Secure-Session-Registration
` header field can be used in a response by the server to start a new device bound session on the
client.
`Secure-Session-Registration
` is a List Structured Header [RFC9651]. Its ABNF
is:
Secure-Session-Registration = sf-list
Each item in the list must be an inner list, and each item in the inner list MUST be an sf-token representing a supported algorithm (ES256, RS256). Only these two values are currently supported.
The following sf-parameters are defined:
-
An sf-parameter whose key is "path", and whose value is an sf-string, conveying the path to the registration endpoint. This may be relative to the current URL, or a full URL. Entries without this parameter will be ignored in § 7.9 Create session.
-
An sf-parameter whose key is "challenge", and whose value is an sf-string, conveying the challenge to be used in the session registration.
-
An sf-parameter whose key is "authorization", and whose value is an sf-string. This sf-parameter will be copied into the registration JWT.
Secure-Session-Registration
` from
https://example.com/login.html:
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
HTTP/1.1 200 OK Secure-Session-Registration: (ES256 RS256);path="reg";challenge="cv"
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a" Secure-Session-Registration: (RS256);path="reg2";challenge="cv2";authorization="b"
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg1";challenge="cv1";authorization="a", (RS256);path="reg2";challenge="cv2";authorization="b"
8.2. `Secure-Session-Challenge
` HTTP Header Field
The ` Secure-Session-Challenge
` header field can be used in a response by the server to send a challenge to the client that it expects to
be used in future Secure-Session-Response headers inside the DBSC proof, or to
request a newly signed DBSC proof right away if the status is 403.
`Secure-Session-Challenge
` is a structured header. Its value must be a string.
Its ABNF is:
SecSessionChallenge = sf-stringThe semantics of the item are defined in § 8.2.1 Secure-Session-Challenge structured header serialization.
The processing steps are defined in § 7.7 Cache challenge.
8.2.1. Secure-Session-Challenge structured header serialization
The `Secure-Session-Challenge
` is represented as a Structured Field.[RFC9651]
In this representation, a challenge is represented by a string.
Challenges MAY have an sf-parameter named "id"
, whose value MUST be a String
representing a session identifier. Any other sf-parameters SHOULD be ignored.
Note: The server might need to use this header to request the DBSC proof to be signed with a new challenge before a session id has been assigned. In this case the session ID is optional.
Secure-Session-Challenge
` from
https://example.com/login.html:
HTTP/1.1 403 Forbidden Secure-Session-Challenge: "new challenge"
HTTP/1.1 403 Forbidden Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK Secure-Session-Challenge: "new challenge";id="my session"
HTTP/1.1 200 OK Secure-Session-Challenge: "new challenge";id="my session 1" Secure-Session-Challenge: "another challenge";id="my session 2"
HTTP/1.1 200 OK Secure-Session-Challenge: "c1";id="session 1", "c2";id="session 2"
8.3. Secure-Session-Response
HTTP Header Field
The ` Secure-Session-Response
` header field can be used in the request by the user agent to send a DBSC proof to the server to prove
that the client is still in possession of the private key of the session key.
`Secure-Session-Response
` is a structured
header. Its value must be a string. It’s ABNF is:
SecSessionChallenge = sf-string
This string MUST only contain the DBSC proof JWT. Any sf-parameters SHOULD be ignored.
POST example.com/refresh Secure-Session-Response: "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRic2Mrand0In0.eyJhdWQiOiJodHRwczovL2V4YW1wbGUuY29tL3JlZyIsImp0aSI6ImN2IiwiaWF0IjoiMTcyNTU3OTA1NSIsImp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjZfR0Iydm9RMHFyb01oNk9sREZDRlNfU0pyaVFpMVBUdnZCT2hHWjNiSEkiLCJ5IjoiSWVnT0pVTHlFN1N4SF9DZDFLQ0VSN2xXQnZHRkhRLWgweHlqelVqRUlXRSJ9LCJhdXRob3JpemF0aW9uIjoiYWMifQ.6Fb_vVBDmfNghQiBmIGe8o7tBfYPbPCywhQruP0vIhxgmcJmuNTaMHeVn_M8ZnOm1_bzIitbZqCWEn-1Qzmtyw"
8.4. Sec-Secure-Session-Id
HTTP Header Field
The ` Sec-Secure-Session-Id
` header field can be used in the request by the user agent to request the current session is refreshed,
with the current session identifier as a string argument.
`Sec-Secure-Session-Id
` is a structured header.
Its value must be a string. It’s ABNF is:
SecSessionIdentifier = sf-string
This string MUST only contain the session identifier. Any parameters SHOULD be ignored.
8.5. Secure-Session-Skipped
HTTP header field
The ` Secure-Session-Skipped
` header field can be used in a request to indicate that the request is intentionally missing bound
credentials due to user agent policy.
`Secure-Session-Skipped
` is a List Structured Header [RFC9651]. Its ABNF
is:
Secure-Session-Skipped = sf-list
Each item in the list must be MUST be an sf-token representing a coarse-grained reason for skipping cookie refresh. The only supported values are: "unreachable", "server_error", and "quota_exceeded".
One sf-parameter is defined:
-
An sf-parameter whose key is "session_identifier", and whose value is an sf-string, conveying the identifier of the skipped session.
GET example.com/requires_bound_cookie Secure-Session-Skipped: unreachable;session_identifier=123, quota_exceeded;session_identifier=456
8.6. DBSC Session Instruction Format
The server sends session instructions during session registration and optionally during session refresh. If the response contains session instructions, it MUST be in JSON format.At the root of the JSON object, the following keys can exist:
- session identifier
-
a string representing a session identifier. If this session instructions is sent during a refresh request this MUST be the session identifier for the current session. If not these instructions SHOULD be ignored. If this session instructions is sent during a registration it MUST either be a unique identifier for this registrable domain, or it will overwrite the current device bound session with this identifier for the current registrable domain. This key MUST be present.
- refresh_url
-
a string representing the URL used for future refresh requests. This can be a full URL, or relative to the current request. This key is OPTIONAL; if not present the registration URL will be used for future refresh requests.
- continue
-
a boolean indicating if the session should continue to apply. Registration and refresh endpoints can set this to false to terminate a session. This key is OPTIONAL, and if not present, the default value will be true.
- scope
-
a dictionary of session scope instructions describing the request destinations covered by the session. This field MUST be present.
- credentials
-
a list of session credentials describing the cookies protected by this session. This field MUST be present.
- allowed_refresh_initiators
-
a list of strings describing which hosts are allowed to initiate DBSC refreshes due to non-CORS requests. See § 7.3 Identify if a request is allowed to refresh for details.
{ "session_identifier" : "session_id" , "refresh_url" : "/RefreshEndpoint" , "continue" : false , "defer_requests" : true , // optional and true by default "scope" : { // Origin-scoped by default (i.e. https://example.com) // Specifies to include https://*.example.com except excluded subdomains. // This can only be true if the origin's host is the root eTLD+1. "origin" : "https://example.com" , "include_site" : true , "scope_specification" : [ { "type" : "include" , "domain" : "trusted.example.com" , "path" : "/only_trusted_path" }, { "type" : "exclude" , "domain" : "untrusted.example.com" , "path" : "/" }, { "type" : "exclude" , "domain" : "*.example.com" , "path" : "/static" } ] }, "credentials" : [{ "type" : "cookie" , // This specifies the exact cookie that this config applies to. Attributes // match the cookie attributes in RFC 6265bis and are parsed similarly to // a normal Set-Cookie line, using the same default values. // These SHOULD be equivalent to the Set-Cookie line accompanying this // response. "name" : "auth_cookie" , "attributes" : "Domain=example.com; Path=/; Secure; HttpOnly; SameSite=None" // Attributes Max-Age and Expires are ignored }], "allowed_refresh_initiators" : [ "example.com" , "*.example.com" ] }
8.7. DBSC Session Scope Instruction Format
The server sends session scope instructions in the session instructions during registration and optionally during session refresh.At the root of the JSON object, the following keys can exist:
- origin
-
a string indicating the origin or site that the session applies to. This key is OPTIONAL; if not present, the origin of the URL serving the instructions will be used. This is the registration URL during registration and the refresh URL during refresh.
- include_site
-
a boolean indicating if the session is origin-scoped (false) or site-scoped (true). This key is OPTIONAL; if not present, it will be false (origin-scoped). Note that this takes precedence over any session scope rules in scope specification (see § 7.2 Identify if a URL is in scope of a session).
- scope_specification
-
a list of session scope rules describing modifications to the default scope (the entire origin or site). This key is OPTIONAL; if not present, an empty list will be used.
8.8. DBSC Session Scope Rule Format
The server sends session scope rules in the session scope instructions during registration and optionally during session refresh.At the root of each session scope rule, the following keys can exist:
- type
-
a string indicating whether the rule includes or excludes destinations. This key MUST be present, and the value MUST be "include" or "exclude".
- domain
-
a string indicating the domains that should match the rule. This key MUST be present. This can include wildcards (see § 7.2 Identify if a URL is in scope of a session).
- path
-
a string indicating the path-prefixes that should match the rule. This key MUST be present. See § 7.2 Identify if a URL is in scope of a session for the detailed semantics.
8.9. DBSC Session Credentials Format
The server sends session credentials in the session instructions during registration and optionally during session refresh.At the root of the JSON object, the following keys can exist:
- type
-
a string indicating the kind of credential protected by this session. This key MUST be present, and the value MUST be "cookie".
- name
-
a string indicating the name of the bound cookie.
- attributes
-
a string containing the expected attributes of the protected cookie. See § 7.6 Identify missing session credential for details on how this is used.
8.10. DBSC Proof JWT Syntax
A DBSC proof proof is a JWT that is signed (using JSON Web Signature (JWS)), with a private key chosen by the client. The header of a DBSC proof MUST contain at least the following sf-parameters:- typ
-
a string MUST be "dbsc+jwt"
- alg
-
a string defining the algorithm used to sign this JWT. It MUST be either "RS256" or "ES256" from [IANA.JOSE.ALGS].
The payload of DBSC proof MUST contain at least the following claims:
- aud
-
a string, MUST be the URL this JWT was originally sent to. Example: "https://example.com/refresh.html"
- jti
-
a string, a copy of the challenge value sent in the registration header.
- iat
-
a string, this claim identifies the time at which the JWT was issued. This claim can be used to determine the age of the JWT. Its value MUST be a number containing a NumericDate value.
- key
-
a string defining a JWK as specified in [rfc7517].
In addition the following claims MUST be present if present in
`Secure-Session-Registration
`:
- authorization
-
a string, direct copy of the string from `
Secure-Session-Registration
`, if set there. Note that this string is OPTIONAL to include in the header, but if it is present it is MANDATORY for clients to add the claim in the DBSC proof.
If the DBSC proof is for a refresh request, the following claim MUST be present:
- sub
-
the session identifier, a string.
// Header { "alg" : "ES256" , "typ" : "dbsc+jwt" } // Payload { "aud" : "https://example.com/reg" , "jti" : "cv" , "iat" : "1725579055" , "key" : { "kty" : "EC" , "crv" : "P-256" , "x" : "6_GB2voQ0qroMh6OlDFCFS_SJriQi1PTvvBOhGZ3bHI" , "y" : "IegOJULyE7SxH_Cd1KCER7lWBvGFHQ-h0xyjzUjEIWE" }, "authorization" : "ac" }
Based on this response header from the server:
HTTP/1.1 200 OK Secure-Session-Registration: (ES256);path="reg";challenge="cv";authorization="ac"
received on a response from http://example.com/page.html
9. Changes to other specifications
9.1. Changes to the Fetch specification
This specification requires an update to the HTTP-network-or-cache fetch algorithm. A request has a deferred device bound session ids, a list of tuples consisting of:
-
a domain (a registrable domain).
-
a session id (a string).
-
Run § 7.8 Send request with the returned session’s session key, refresh URL, session identifier, cached challenge, and an empty authorization.
-
Restart HTTP-network-or-cache fetch with the original inputs.
9.2. Changes to the Clear Site Data specification
This specification requires that the Clear Site Data specification sections 4.2.5 "Clear DOM-accessible storage for origin" clear all device bound sessions whose scope matches origin. It also requires an update to 4.2.4 to clear device bound sessions for the site matching the registered domain.
10. IANA Considerations
The permanent message header field registry should be updated with the following registrations: [RFC3864]
10.1. Secure-Session-Challenge
- Header field name
- Secure-Session-Challenge
- Applicable protocol
- http
- Status
- draft
- Author/Change controller
- W3C
- Specification document
- This specification (See § 8.2 `Secure-Session-Challenge` HTTP Header Field)
10.2. Sec-Secure-Session-Id
- Header field name
- Sec-Secure-Session-Id
- Applicable protocol
- http
- Status
- draft
- Author/Change controller
- W3C
- Specification document
- This specification (See § 8.4 Sec-Secure-Session-Id HTTP Header Field)
10.3. Secure-Session-Registration
- Header field name
- Secure-Session-Registration
- Applicable protocol
- http
- Status
- draft
- Author/Change controller
- W3C
- Specification document
- This specification (See § 8.1 `Secure-Session-Registration` HTTP header field)
10.4. Secure-Session-Response
- Header field name
- Secure-Session-Response
- Applicable protocol
- http
- Status
- draft
- Author/Change controller
- W3C
- Specification document
- This specification (See § 8.3 Secure-Session-Response HTTP Header Field)
10.5. Secure-Session-Skipped
- Header field name
- Secure-Session-Skipped
- Applicable protocol
- http
- Status
- draft
- Author/Change controller
- W3C
- Specification document
- This specification (See § 8.5 Secure-Session-Skipped HTTP header field)
10.6. device-bound-sessions Well Known
The Well-Known URI registry should be updated to include /.well-known/device-bound-sessions.
This endpoint must serve a JSON-encoded list of strings for each origin allowed to register a session for the entire site.
https://example.com/.well-known/device-bound-sessions
serves
[ "https://subdomain.example.com" , "https://subdomain.example.com:8000" , ]
Then registration requests can define a site-scoped session only if one of the following is true:
-
The registration endpoint has host
example.com
-
The registration endpoint has origin
https://subdomain.example.com
-
The registration endpoint has origin
https://subdomain.example.com:8000