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 =
BroadcastChannel false ;boolean =
SharedWorker 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 BroadcastChannel (DOMString );
name SharedWorker SharedWorker (USVString ,
scriptURL optional (DOMString or SharedWorkerOptions )= {}); };
options partial interface Document {Promise <boolean >hasUnpartitionedCookieAccess ();Promise <StorageAccessHandle >requestStorageAccess (StorageAccessTypes ); };
types
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.
all
isfalse
and types.cookies
isfalse
and types.sessionStorage
isfalse
and types.localStorage
isfalse
and types.indexedDB
isfalse
and types.locks
isfalse
and types.caches
isfalse
and types.getDirectory
isfalse
and types.estimate
isfalse
and types.createObjectURL
isfalse
and types.revokeObjectURL
isfalse
and types.BroadcastChannel
isfalse
and types.SharedWorker
isfalse
:-
Reject p with an "
InvalidStateError
"DOMException
. -
Return p.
-
-
Let requestUnpartitionedCookieAccess be
true
if types.all
istrue
or types.cookies
istrue
, andfalse
otherwise. -
Let accessPromise be the result of running request storage access with doc with requestUnpartitionedCookieAccess.
-
If accessPromise rejects with
reason
r:-
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.
all
isfalse
and this’s types.sessionStorage
isfalse
:-
Throw an "
InvalidStateError
"DOMException
.
-
-
Return the result of running sessionStorage.
The localStorage
getter steps are:
-
If this’s types.
all
isfalse
and this’s types.localStorage
isfalse
:-
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.
all
isfalse
and this’s types.indexedDB
isfalse
:-
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.
all
isfalse
and this’s types.locks
isfalse
:-
Throw an "
InvalidStateError
"DOMException
.
-
2.3.4. Cache Storage
The caches
getter steps are:
-
If this’s types.
all
isfalse
and this’s types.caches
isfalse
:-
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.
all
isfalse
and types.getDirectory
isfalse
:-
Reject p with an "
InvalidStateError
"DOMException
.
-
-
Let directoryPromise be the result of running
getDirectory()
onNavigator
.storage
. -
If directoryPromise rejects with
reason
r:-
Reject p with r.
-
-
Else if directoryPromise resolves with
FileSystemDirectoryHandle
f:-
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.
all
isfalse
and types.estimate
isfalse
:-
Reject p with an "
InvalidStateError
"DOMException
.
-
-
Let estimatePromise be the result of running
estimate()
onNavigator
.storage
. -
If estimatePromise rejects with
reason
r:-
Reject p with r.
-
-
Else if estimatePromise resolves with
StorageEstimate
e:-
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.
all
isfalse
and types.createObjectURL
isfalse
:-
Throw an "
InvalidStateError
"DOMException
.
-
-
Return the result of running createObjectURL on
URL
with obj.
When invoked on StorageAccessHandle
handle with StorageAccessTypes
types and DOMString
url, the revokeObjectURL(url)
method must run these steps:
-
If types.
all
isfalse
and types.revokeObjectURL
isfalse
:-
Throw an "
InvalidStateError
"DOMException
.
-
-
Return the result of running revokeObjectURL on
URL
with url.
2.3.8. Broadcast Channel
When invoked on StorageAccessHandle
handle with StorageAccessTypes
types and DOMString
name, the BroadcastChannel(name)
method must run these steps:
-
If types.
all
isfalse
and types.BroadcastChannel
isfalse
:-
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.
sameSiteCookies
isall
andWindow
'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 SharedWorker(scriptURL, options)
method must run these steps:
-
If types.
all
isfalse
and types.SharedWorker
isfalse
:-
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.