1. Introduction
This section is non-normative.
The
Storage
Access
API
(SAA)
enables
content
inside
iframe
s
to
request
and
be
granted
access
to
their
client-side
storage,
so
that
embedded
content
which
relies
on
having
access
to
client-side
storage
can
work
in
such
User
Agents.
[STORAGE-ACCESS]
This specification extends the client-side storage available beyond cookies.
2. Extending SAA to non-cookie storage
This
specification
defines
a
method
to
request
access
to
unpartitioned
data
beyond
just
cookies
(
requestStorageAccess(types)
),
and
a
method
to
check
if
cookie
access
has
specifically
been
granted
(
hasUnpartitionedCookieAccess()
).
Alex
visits
https://social.example/
.
The
page
sets
a
some
local
storage.
This
local
storage
has
been
set
in
a
first-party-site
context
.
window. localStorage. setItem( "userid" , "1234" );
Later
on,
Alex
visits
https://video.example/
,
which
has
an
iframe
on
it
which
loads
https://social.example/heart-button
.
In
this
case,
the
social.example
Document
doc
is
in
a
third
party
context
,
and
the
local
storage
set
previously
might
or
might
not
be
visible
depending
on
User
Agent
storage
access
policies.
Script
in
the
iframe
can
call
doc
.
requestStorageAccess(types)
to
request
access.
let handle= await document. requestStorageAccess({ localStorage: true }); let userid= handle. localStorage. getItem( "userid" );
2.1.
Changes
to
Document
dictionary {StorageAccessTypes boolean =all false ;boolean =cookies false ;boolean =sessionStorage false ;boolean =localStorage false ;boolean =indexedDB false ;boolean =locks false ;boolean =caches false ;boolean =getDirectory false ;boolean =estimate false ;boolean =createObjectURL false ;boolean =revokeObjectURL false ;; ;boolean =createBroadcastChannel false ;boolean =createSharedWorker false ; }; [Exposed =Window ]interface {StorageAccessHandle readonly attribute Storage sessionStorage ;readonly attribute Storage localStorage ;readonly attribute IDBFactory indexedDB ;readonly attribute LockManager locks ;readonly attribute CacheStorage caches ;Promise <FileSystemDirectoryHandle >getDirectory ();Promise <StorageEstimate >estimate ();DOMString createObjectURL ((Blob or MediaSource ));obj undefined revokeObjectURL (DOMString );url ); = {});BroadcastChannel createBroadcastChannel (DOMString );name SharedWorker createSharedWorker (USVString ,scriptURL optional (DOMString or SharedWorkerOptions )= {}); };options partial interface Document {Promise <boolean >hasUnpartitionedCookieAccess ();Promise <StorageAccessHandle >requestStorageAccess (optional StorageAccessTypes = {}); };types
Although
requestStorageAccess(types)
lists
types
as
optional,
it
should
be
treated
as
if
OneMemberRequired
(not
yet
supported)
were
applied
to
indicate
the
dictionary
must
have
at
least
one
non-false
argument.
If
requestStorageAccess(types)
is
called
without
providing
types
you
would
actually
be
invoking
requestStorageAccess()
which
does
not
return
a
StorageAccessHandle
.
A
StorageAccessHandle
object
has
an
associated
StorageAccessTypes
types
.
When
invoked
on
Document
doc
,
the
hasUnpartitionedCookieAccess()
method
must
run
these
steps:
-
Return the result of running
hasStorageAccess()on doc .
Note:
Now
that
requestStorageAccess(types)
can
be
used
to
request
unpartitioned
data
with
or
without
specifically
requesting
cookies,
it
must
be
made
clear
that
hasStorageAccess()
only
returns
true
if
first-party-site
context
cookies
are
accessable
to
the
current
document.
As
a
function
name,
hasUnpartitionedCookieAccess()
more
clearly
communicates
this.
For
now
hasStorageAccess()
is
not
considered
deprecated,
but
that
may
be
worth
taking
up
in
future.
When
invoked
on
Document
doc
,
the
requestStorageAccess(types)
method
must
run
these
steps:
-
Let p be a new promise .
-
If types .
allisfalseand types .cookiesisfalseand types .sessionStorageisfalseand types .localStorageisfalseand types .indexedDBisfalseand types .locksisfalseand types .cachesisfalseand types .getDirectoryisfalseand types .estimateisfalseand types .createObjectURLisfalseand types .revokeObjectURLisfalseand types .isBroadcastChannelcreateBroadcastChannelfalseand types .isSharedWorkercreateSharedWorkerfalse:-
Reject p with an "
InvalidStateError"DOMException. -
Return p .
-
-
Let requestUnpartitionedCookieAccess be
trueif types .allistrueor types .cookiesistrue, andfalseotherwise. -
Let accessPromise be the result of running request storage access with doc with requestUnpartitionedCookieAccess .
-
If accessPromise rejects with
reasonr :-
Reject p with r .
-
-
Else:
-
Let handle be a new object of type
StorageAccessHandle. -
Set handle ’s types to types .
-
Resolve p with handle .
-
-
Return p .
2.2.
Changes
to
requestStorageAccess()
Redefine
requestStorageAccess()
to:
-
Return the result of running request storage access with doc and requestUnpartitionedCookieAccess being
true.
Modify
requestStorageAccess()
to
instead
be
the
algorithm
request
storage
access
which
takes
a
Document
doc
and
a
boolean
argument
requestUnpartitionedCookieAccess
.
Modify
requestStorageAccess()
at
step
14.1.1.1.1
to
read:
-
If requestUnpartitionedCookieAccess is
true, then set global ’s has storage access to true.
2.3. Changes to various client-side storage mechanisms
For all of the following getters and methods, consider the following modifications:
-
When attempting to obtain a storage key for non-storage purposes the returned key will use Client-Side Storage Partitioning § relaxing-additional-keying if the tuple does not simply contain an origin .
Clarify client-side storage mechanism changes in more detail. [Issue #19]
2.3.1. Web storage
The
sessionStorage
getter
steps
are:
-
If this ’s types .
allisfalseand this ’s types .sessionStorageisfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running sessionStorage .
The
localStorage
getter
steps
are:
-
If this ’s types .
allisfalseand this ’s types .localStorageisfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running localStorage .
2.3.2. Indexed Database API
The
indexedDB
getter
steps
are:
-
If this ’s types .
allisfalseand this ’s types .indexedDBisfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running
indexedDB.
2.3.3. Web Locks API
The
locks
getter
steps
are:
-
If this ’s types .
allisfalseand this ’s types .locksisfalse:-
Throw an "
InvalidStateError"DOMException.
-
2.3.4. Cache Storage
The
caches
getter
steps
are:
-
If this ’s types .
allisfalseand this ’s types .cachesisfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running caches .
2.3.5. File System
When
invoked
on
StorageAccessHandle
handle
with
StorageAccessTypes
types
,
the
getDirectory()
method
must
run
these
steps:
-
Let p be a new promise .
-
If types .
allisfalseand types .getDirectoryisfalse:-
Reject p with an "
InvalidStateError"DOMException.
-
-
Let directoryPromise be the result of running
getDirectory()onNavigator.storage. -
If directoryPromise rejects with
reasonr :-
Reject p with r .
-
-
Else if directoryPromise resolves with
FileSystemDirectoryHandlef :-
Resolve p with f .
-
-
Return p .
2.3.6. Storage Manager
When
invoked
on
StorageAccessHandle
handle
with
StorageAccessTypes
types
,
the
estimate()
method
must
run
these
steps:
-
Let p be a new promise .
-
If types .
allisfalseand types .estimateisfalse:-
Reject p with an "
InvalidStateError"DOMException.
-
-
Let estimatePromise be the result of running
estimate()onNavigator.storage. -
If estimatePromise rejects with
reasonr :-
Reject p with r .
-
-
Else if estimatePromise resolves with
StorageEstimatee :-
Resolve p with e .
-
-
Return p .
2.3.7. File API
When
invoked
on
StorageAccessHandle
handle
with
StorageAccessTypes
types
and
Blob
or
MediaSource
obj
,
the
createObjectURL(obj)
method
must
run
these
steps:
-
If types .
allisfalseand types .createObjectURLisfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running createObjectURL on
URLwith obj .
When
invoked
on
StorageAccessHandle
handle
with
StorageAccessTypes
types
and
DOMString
url
,
the
revokeObjectURL(url)
method
must
run
these
steps:
-
If types .
allisfalseand types .revokeObjectURLisfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running revokeObjectURL on
URLwith url .
2.3.8. Broadcast Channel
When
invoked
on
StorageAccessHandle
handle
with
StorageAccessTypes
types
and
DOMString
name
,
the
method
must
run
these
steps:
BroadcastChannel(name)
createBroadcastChannel(name)
-
If types .
allisfalseand types .isBroadcastChannelcreateBroadcastChannelfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running new BroadcastChannel with name .
2.3.9. Shared Workers
Modify Shared Workers to define the following:
enum {SameSiteCookiesType ,"all" };"none" dictionary :SharedWorkerOptions WorkerOptions {SameSiteCookiesType ; };sameSiteCookies
The
default
sameSiteCookies
is
all
in
first-party-site
context
and
none
otherwise.
Modify
SharedWorkerGlobalScope
to
have
an
associated
SameSiteCookiesType
sameSiteCookies
.
Modify
new
SharedWorker
to
accept
SharedWorkerOptions
instead
of
WorkerOptions
.
Modify new SharedWorker to add a new step below step 1 as follows:
-
If options .
sameSiteCookiesisallandWindow’s associated document is not first-party-site context , then:-
Throw an "
InvalidStateError"DOMException.
-
Modify new SharedWorker to add a new matching criteria in step 10.2.2 as follows:
-
scope ’s sameSiteCookies equals options .
sameSiteCookies.
Modify Processing Model to add a new step below step 10.4 as follows:
-
Set worker global scope ’s sameSiteCookies to options .
sameSiteCookies.
Note:
The
SameSiteCookiesType
is
used
to
influence
which
cookies
are
sent
or
read
during
fetch
based
on
the
SameSite
cookie
attribute.
all
is
only
available
in
first-party-site
context
and
permits
SameSite
"None",
"Lax",
and
"Strict"
cookies
to
be
included
(if
not
blocked
for
some
other
reason).
none
is
available
in
any
context
and
permits
only
SameSite
"None"
cookies
to
be
included
(if
not
blocked
for
some
other
reason).
Clarify
SharedWorker
usage
of
sameSiteCookies
in
more
detail.
[Issue
#21]
When
invoked
on
StorageAccessHandle
handle
with
StorageAccessTypes
types
,
USVString
scriptURL
,
and
DOMString
or
SharedWorkerOptions
options
,
the
method
must
run
these
steps:
SharedWorker(scriptURL,
createSharedWorker(scriptURL,
options)
-
If types .
allisfalseand types .isSharedWorkercreateSharedWorkerfalse:-
Throw an "
InvalidStateError"DOMException.
-
-
Return the result of running new SharedWorker with scriptURL and options .
3. Security & Privacy considerations
In extending an existing access-granting API, care must be taken not to open additional security issues or abuse vectors relative to comprehensive cross-site cookie blocking and storage partitioning. Except for Service Workers (which will not be supported in this extension) non-cookie storage and communication APIs don’t enable any capability that could not be built with cookie access alone.
For more detailed discussions see The Storage Access API § 6 Privacy considerations and The Storage Access API § 7 Security considerations .