1. Introduction
For now, see the explainer .
See
https://garykac.github.io/procspec/
This
spec
is
an
early-stage
draft.
Missing
details
and
remaining
TODOs
are
called
out
with
Issue:
blocks.
2. Security considerations
3. Privacy considerations
4. Framework
4.1. Observer store
The
user
agent
maintains
an
observer
store
.
It
is
a
set
of
weak
references
to
DeviceBoundSessionsObserver
objects.
The
store
is
initially
empty.
When an observer has been reclaimed by garbage collection, it must be removed from the store.
4.2. Registration buffer and store
The user agent maintains a registration attempts store . It is a map from storage key to registration buffer . The store is initially empty.
Should we make this a formal storage endpoint ?
A
registration
buffer
is
a
list
of
DeviceBoundSessionRegistrationReport
s.
Each
buffer
is
initially
empty.
User agents should put a reasonable limit on the number of attempts stored in each buffer and their time-to-live.
5.
The
DeviceBoundSessionsObserver
interface
This interface can be used to observe device bound sessions and registration attempts.
[Exposed =Window ,SecureContext ]interface {DeviceBoundSessionsObserver constructor (DeviceBoundSessionsObserverCallback ,callback optional DeviceBoundSessionsObserverOptions = {} );options undefined observe ();undefined disconnect ();sequence <DeviceBoundSessionsReport >takeRecords (); };callback =DeviceBoundSessionsObserverCallback undefined (sequence <DeviceBoundSessionsReport >,reports DeviceBoundSessionsObserver );observer
A
DeviceBoundSessionsObserver
has
an
associated
callback
(a
DeviceBoundSessionsObserverCallback
)
and
an
associated
options
(a
DeviceBoundSessionsObserverOptions
).
DeviceBoundSessionsObserver(
callback
,
options
)
constructor
is
called:
DeviceBoundSessionsObserver
observer
of
a
list
of
DeviceBoundSessionsReport
s
reports
:Queue a global task on the networking task source given observer ’s relevant global object to run these steps:
If observer store does not contain observer , then return.
Invoke observer ’s callback with « reports , observer » and "
report", and callback this value observer .
Callers of this algorithm must verify that observer is allowed to know about reports under the user agent’s current policies, notably storage partitioning.
5.1.
DeviceBoundSessionsObserverOptions
dictionary
dictionary {DeviceBoundSessionsObserverOptions AbortSignal signal ; };
signal, of type AbortSignalThe
abortevent stops the observer from receiving further reports.
5.2.
observe()
method
observe()
is
called:
If signal exists and is aborted ,
https://dlaliberte.github.io/bikeshed-intro/index.htmlthen return.If observer store contains this , then return.
Append a weak reference to this to observer store .
If signal exists , then add the following abort steps to signal :
Call this ’s
disconnect().
Let reports be the result of collecting past reports for this .
DeviceBoundSessionsObserver
observer
:Let environment be observer ’s relevant settings object .
Let observer key be the result of running obtain a storage key for non-storage purposes given environment .
Let reports be a new list .
If registration attempts store [ observer key ] exists , then set reports to a clone of registration attempts store [ observer key ].
For each sessions by id of session store ’s values :
For each session of sessions by id ’s values :
If determine session visibility given environment and
https://speced.github.io/bikeshed/session does not return "visible", then continue .Let session report be the result of creating an established session report given session .
If reports contains a
DeviceBoundSessionRegistrationReportregistration such that registration [session] exists and equals session report , then continue .Append session report to
getreports .
Return reports .
5.3.
disconnect()
method
disconnect()
is
called:
Remove this from observer store .
User
agents
may
want
to
also
clean
up
previously
set
up
abort
steps
and
remove
garbage-collected
references
from
the
store.
5.4.
takeRecords()
method
takeRecords()
is
called:
Let reports be the result of collecting past reports for this .
Let observer key be the result of running obtain a storage key for non-storage purposes given this ’s relevant settings object .
Remove registration attempts store [ observer key ].
Return reports .
5.5. Report types
enum {DeviceBoundSessionsReportKind ,"session" };"registration" dictionary DeviceBoundEstablishedSessionReport {required DeviceBoundSessionsReportKind type ;required DOMString sessionOrigin ;required DOMString sessionId ;required DOMString refreshUrl ;required DOMHighResTimeStamp creationTime ; };dictionary DeviceBoundSessionRegistrationReport {required DeviceBoundSessionsReportKind type ;required DOMString registrationUrl ;required boolean success ;required DOMHighResTimeStamp endTime ;DeviceBoundEstablishedSessionReport session ;DOMString reason ;unsigned short code ;DOMString providerUrl ;DOMString providerSessionId ; };typedef (DeviceBoundSessionRegistrationReport or DeviceBoundEstablishedSessionReport );DeviceBoundSessionsReport
5.5.1. Registration attempt report
A
DeviceBoundSessionRegistrationReport
represents
the
outcome
of
the
multi-stage
process
started
by
process
a
session
registration
.
See
§ 7.1
Changes
to
the
DBSC
specification
.
type, of type DeviceBoundSessionsReportKindMust be
"registration".registrationUrl, of type DOMStringThe serialized registration endpoint URL to which the registration request was sent.
success, of type booleanTrue if the registration attempt resulted in an established device bound session ; false otherwise.
endTime, of type DOMHighResTimeStampThe duration from the Unix epoch to the coarsened wall time when the registration process concluded.
Using the wall clock meansendTimeis not monotonic across registration reports. For example, system clock changes could modify the apparent order of reports.An alternative would be to compute these timestamps using the estimated monotonic time of the Unix epoch here.
This would in turn have the drawback of inconsistent timestamps between a successful registration report’s
endTimeand itssession[creationTime].session, of type DeviceBoundEstablishedSessionReportThe
DeviceBoundEstablishedSessionReportfor the newly created device bound session , present whensuccessis true.reason, of type DOMStringA human-readable or categorical description of why the registration attempt failed, present when
successis false.Replace the free-form string with a WebIDL enum of standardized failure reasons.
code, of type unsigned shortThe HTTP status code received from the registration endpoint, present when the attempt failed due to an HTTP response status.
providerUrl, of type DOMStringFor a federated session registration attempt, the serialized provider URL specified in the `
Secure-Session-Registration` header.providerSessionId, of type DOMStringFor a federated session registration attempt, the provider session identifier specified in the `
Secure-Session-Registration` header.
Let report be a
DeviceBoundSessionRegistrationReportwith:typeregistrationUrlThe URL serializer of registration URL .
successsuccess .
endTimeThe duration from the Unix epoch to the current coarsened wall time .
If resulting session was given, then set report [
session] to the result of creating an established session report given resulting session .If reason was given, then set report [
reason] to reason .If code was given, then set report [
code] to code .If provider URL was given, then set report [
providerUrl] to the URL serializer of provider URL .If provider session id was given, then set report [
providerSessionId] to provider session id .Report report with resulting session (if given).
DeviceBoundSessionRegistrationReport
report
given
an
optional
device
bound
session
resulting
session
:Let registration key be the storage key of report .
For each observer of observer store :
Let environment be the relevant settings object for observer .
Let observer key be the result of running obtain a storage key for non-storage purposes given environment .
If observer key equals registration key , then inform observer of « report », and continue .
If resulting session was not given, then continue .
If determine session visibility given environment and resulting session does not return "visible", then continue .
If registration attempts store [ registration key ] does not exist , then set registration attempts store [ registration key ] to a new registration buffer .
Append report to registration attempts store [ registration key ].
DeviceBoundSessionRegistrationReport
registration
is
defined
as:
Let url be the result of running the URL parser on
your specification.registration [registrationUrl].Let origin be url ’s origin .
Let site be obtain a site given origin .
Return a storage key whose origin is origin and top-level site is site .
5.5.2. Established session report
A
DeviceBoundEstablishedSessionReport
represents
a
device
bound
session
.
Note
that
DeviceBoundSessionRegistrationReport
also
contains
a
session
:
if
an
observer
is
informed
of
an
established
session
via
a
(buffered)
DeviceBoundSessionRegistrationReport
,
it
must
not
be
informed
of
the
same
session
a
second
time
via
a
DeviceBoundEstablishedSessionReport
.
type, of type DeviceBoundSessionsReportKindMust be
"session".sessionOrigin, of type DOMStringThe serialized origin of the device bound session ’s session scope .
sessionId, of type DOMStringThe device bound session ’s session identifier .
refreshUrl, of type DOMStringThe serialized refresh URL of the device bound session .
creationTime, of type DOMHighResTimeStampThe duration from the Unix epoch to the device bound session ’s creation time .
Let report be a new
DeviceBoundEstablishedSessionReportdictionary with:typesessionOriginThe serialization of an origin given session ’s session scope ’s origin .
sessionIdsession ’s session identifier .
refreshUrlThe URL serializer of session ’s refresh URL .
creationTimeThe duration from the Unix epoch to session ’s creation time .
Return report .
DeviceBoundEstablishedSessionReport
a
equals
another
DeviceBoundEstablishedSessionReport
b
if
all
of
the
following
are
true:
a [
sessionOrigin] is b [sessionOrigin].a [
creationTime] is b [creationTime].Note: In [dbsc-1] , a device bound session is keyed in the session store by its site and session identifier . Comparing
creationTimealso distinguishes a session from a later registration that overwrote the same session identifier .
6. Session reports visibility
Let url be environment ’s creation URL .
If url is not session ’s refresh URL :
If the result of running determine if a URL is in scope with url and session is false, then return "hidden".
If environment has storage access , then return "visible".
Return "hidden".
Consider making this a WPT instead.
Given the following (incomplete) session definition:
{ "session_identifier" : "session_id" , "refresh_url" : "/refresh" , "scope" : { "origin" : "https://example.com" , "include_site" : true , "scope_specification" : [ { "type" : "exclude" , "domain" : "sites.example.com" , "path" : "/" }, { "type" : "exclude" , "domain" : "*.example.com" , "path" : "/static" } ] }, "credentials" : [{ "type" : "cookie" , "name" : "auth_cookie" , "attributes" : "Domain=example.com; Path=/; Secure; HttpOnly; SameSite=Strict" }] }
The
following
table
illustrates
whether
session_id
is
visible
to
various
execution
environments:
| Creation URL | Storage access | Visible? | Reason |
|---|---|---|---|
https://example.com/account
| Top-level window |
true
|
In
scope
of
session_id
,
has
storage
access.
|
https://sub.example.com/app
| Top-level window |
true
|
Also
in
scope
of
session_id
,
by
its
include_site
. |
https://example.com/refresh
| Top-level window |
true
| Refresh URL bypasses scope check. |
https://example.com/refresh
| Embedded without storage access |
false
|
No
access
to
1P
example.com
storage.
|
https://sites.example.com/a
| N/A |
false
|
URL
matches
the
sites.example.com/
exclusion
rule.
|
https://app.example.com/static/index.html
| N/A |
false
|
URL
matches
the
*.example.com/static
exclusion
rule.
|
7. Changes to other specifications
7.1. Changes to the DBSC specification
Avoid deep monkey-patching here: open a PR against [dbsc-1] , then remove this section.
In device bound session , add the following item:
- creation time
The current coarsened wall time at which this session was created.
In process a session registration :
Modify the step that checks if key pair is "
failure" to record a registration attempt on failure.Pass provider URL and provider session id as additional optional inputs to send a request .
Note: The next two changes mention "if session id is null" to send a report only when send a request creates a new session. When that algorithm runs for a refresh, session id is known.
In send a request :
Accept an optional provider URL and an optional provider session id to adequately construct a federation attempt report when applicable.
If session id is null, then:
Whenever returning early due to a network error or an invalid HTTP status code, record a registration attempt .
Pass provider URL and provider session id to create a session .
In create a session :
Accept an optional provider URL and an optional provider session id .
After setting the expiration timestamp , also set creation time .
Whenever invoking terminate the session and returning (cf. the last "credential" loop), if session id is null, then record a registration attempt with an appropriate failure reason , code , etc.
When adding a session to the session store , if session id is null, then record a registration attempt (successful, passing session ).