Copyright © 2015 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and document use rules apply.
The Permissions API allows a web application to be aware of the status of a given permission, to know whether it is granted, denied or if the user will be asked whether the permission should be granted.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at http://www.w3.org/TR/.
This document was published by the Web Application Security Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-webappsec@w3.org (subscribe, archives). All comments are welcome.
Publication as a First Public Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 August 2014 W3C Process Document.
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, and RECOMMENDED are to be interpreted as described in [RFC2119].
This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.
Implementations that use ECMAScript to expose the APIs defined in this specification MUST implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [WEBIDL].
The following concepts and interfaces are defined in [HTML]:
Promise objects are defined in [ECMASCRIPT].
This section is non-normative.
This document goal is to specify an API that will help developers to handle permissions on the Web platform. Web APIs have different ways to deal with permissions. The [notifications] API allows developers to request a permission and check the permission status explicitly. Others might only expose the status to web pages. Some, like [geolocation-API] will keep the page unaware of the permission associated with the feature.
Being able to know whether an API call is going to prompt is mandatory in order to provide a good user experience. Unfortunately, more often than not, those prompts can't be controlled by the developers.
The API specified in this document is meant to provide the tools so that web applications can improve their user experience when permissions are involved.
The solution described in this document is meant to be extensible but isn't meant to be applicable to all the current and future permissions available in the web platform. If you are working on a specification that has a permission model that wouldn't fit in the model described in this document, please contact the editors or file an issue. We would love to hear about it.
The initial intent of this document was to allow web applications to request and revoke permissions explicitly in addition of query the permission status. This is an aspect of the specification that was controversial thus removed from the current document in a spirit of incremental changes: settling on a small API that can be improved.
enum PermissionName {
"geolocation",
"notifications",
"push-notifications",
"midi-sysex"
};
The PermissionName
enum defines the list of known
permissions. These permissions are meant to be associated with a use
case instead of one API. Thus, some permissions have a 1:1 relationship
with an API while some others might include more than one API or even a
subset of an API.
For example, push-notifications is exposing the ability for a web page to use push messages in order to show notifications. Implementations might associate it with full usage of the Push API and the Notifications API while others will force the callers to use the Push API only in order to use the Notifications API.
Specifications are welcome to request a new name to be added to this registry instead of trying to monkey patch it.
The geolocation
permission is the permission associated with the usage of the
[geolocation-API].
The notifications
permission is the permission associated with the usage of the
[notifications] API.
The push-notifications
permission is the permission associated with the usage of the
[push-api] in order to show notifications using the [notifications]
API.
The midi-sysex
permission
is the permission associated with the usage of sysex messages in the
[webmidi] API.
dictionary Permission {
required PermissionName name;
};
A Permission
dictionary MUST contain a name
field which represents the
permission's identifier.
If a permission has to be defined by more than its name, it is
RECOMMENDED to inherit from Permission
dictionary and add
new fields.
type
and value
fields.
enum PermissionState {
"granted",
"denied",
"prompt"
};
The steps to retrieve the permission state of a global
object for a given permission
are as follows:
permission
but
will prompt the user to know whether the call should succeed or fail,
the user agent MUST return prompt
.
permission
without prompting the user, the user
agent MUST return granted
.
permission
and MUST return denied
.
How the user agent decides whether a global object is allowed or not to access some features is left as an implementation details. However, the implementation MUST be consistent and not return different values unless something happened (user action, expiration).
It is RECOMMENDED for implementations to use the origins of the Document or Worker when making security decisions. Other factors MAY also apply like whether the permission is associated with a [powerful-features] or whether the Document is embedded.
[Exposed=(Window,Worker)]
interface PermissionStatus : EventTarget {
readonly attribute Permission
permission;
readonly attribute PermissionState
status;
attribute EventHandler onchange;
};
The steps to update the status of a
PermissionStatus
instance are as follow:
PermissionStatus
instance
being updated.
permission
attribute then set the result of those steps to the status
attribute.
The steps to create a PermissionStatus for a given
permission
are as follow:
PermissionStatus
instance.
permission
attribute to
permission
.
The permission
attribute
MUST return the
it was initially set to
at the object creation.
Permission
The status
attribute MUST return the latest value that was set while running the
update the status steps on the current instance.
The onchange
attribute is an
event handler whose corresponding event handler event
type is change
.
Whenever the user agent is aware that the status
of
a PermissionStatus
instance has changed, it MUST
asynchronously run the following steps:
PermissionStatus
for which the status
has
changed.
change
at
permission-status.
[Exposed=(Window,Worker)]
interface Permissions {
static Promise<PermissionStatus
> query ((Permission
or PermissionName
) permission);
};
When the
query()
method is invoked, the user agent MUST run
the following steps:
permission
argument if
permission
is of type Permission
, otherwise,
create a Permission
instead for which name
is
set to the permission
argument value.
This section is non-normative.
This example uses the Permissions API to decide whether local news should be shown using the Geolocation API or a button offering that feature should be added.
<script> Permissions.query('geolocation').then(function(result) { if (result.status == 'granted') { showLocalNewsWithGeolocation(); } else if (result.status == 'prompt') { showButtonToEnableLocalNews(); } // Don't do anything if the permission was denied. }); </script>
This example is using the notifications
permission for a
chat application to show a notification button depending on the
permission status.
<script> function updateNotificationButton(permission) { document.getElementById('chat-notification-button').disabled = (permission.status == 'denied'); } Permissions.query('notifications').then(function(result) { updateNotificationButton(result); result.addEventListener('change', function() { updateNotificationButton(this); }); }); </script>
Thanks to Adrienne Porter Felt and Jake Archibald for their early support and help.