From 58f0dbf10f06baae7a68739f6e28a9659069caab Mon Sep 17 00:00:00 2001
From: Marcos Caceres This section is non-normative.
- This document's goal is to specify an API that will help developers to
- handle permissions on the Web platform. Web APIs have different ways to
+ This document specifies a model and an API to query and request permissions
+ to powerful features 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 when they try to use the API,
+ request a permission and check the permission status explicitly.
+ Others expose the status to web pages when they try to use the API,
like the [[geolocation-API]] which fails if the permission was not
granted without allowing the developer to check beforehand.
- Being able to know whether an API call is going to prompt is useful in
- order to provide a good user experience. Unfortunately, more often than
- not, those prompts can't be controlled by developers.
+ The Permissions API provides tools for developers to control when permission
+ prompts are shown and to relinquish permissions that are no longer needed.
- 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 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. Working Groups that are creating specifications
+ whose permission model doesn't fit in the model described in this document
+ should contact the editors by
+ filing an issue.
This section is non-normative.
- Permission states can be used as an element of fingerprinting by
- websites. Usually websites could already have access to the information
- but often through actually using the API which could lead to a
- permission request UI if the permission was not already granted. Thus,
- even though this API doesn't expose new fingerprinting data to
- websites, it makes it easier for them to have discreet access to it.
- Therefore, implementations are encouraged to have an option for users
- to block (globally or selectively) the querying of permission states.
+ An adversary could use a permission state as an element in creating a
+ "fingerprint" corresponding to an end-user. Although an adversary can
+ already determine the state of a permission by actually using the API, that
+ often leads to a permission request UI being presented to the end-user (if
+ the permission was not already granted). Thus, even though this API doesn't
+ expose new fingerprinting information to websites, it makes it easier for an
+ adversary to have discreet access to this information. Thus, implementations
+ are encouraged to have an option for users to block (globally or
+ selectively) the querying of permission states.
- Each powerful feature has one or more aspects that websites can - request permission to access. To describe these requests, each feature - defines a subtype of {{PermissionDescriptor}} to be its permission - descriptor type. + Each powerful feature has one or more aspects that + websites can request permission to access. To describe these aspects, + each feature defines a subtype of {{PermissionDescriptor}} to be its + permission descriptor type.
-- The {{"midi"}} feature has two aspects: access to normal messages, and - access to system exclusive messages. Thus, its permission descriptor type + The {{"midi"}} feature has two aspects: access to normal messages, and + access to system exclusive messages. Thus, its permission descriptor type is:
@@ -160,8 +159,8 @@ spec: webidl
The {{"bluetooth"}} feature lets sites request to access whatever - Bluetooth devices are close to to the user's device. Thus, its descriptor - type is: + Bluetooth devices are close to to the user's device. Thus, its + permission descriptor type is:
dictionary BluetoothPermissionDescriptor : PermissionDescriptor { @@ -203,13 +202,13 @@ spec: webidlReading the current permission state
- |descriptor|'s permission state is one of {{"granted"}}, - {{"prompt"}}, or {{"denied"}}, indicating respectively if the calling - algorithm should succeed without prompting the user, show the user a - prompt to decide whether to succeed, or fail without prompting the user. - The UA must return whichever of these values most accurately reflects the - user's intent, except that if the current settings object is a - non-secure context and + |descriptor|'s permission state is one + of {{"granted"}}, {{"prompt"}}, or {{"denied"}}, indicating respectively + if the calling algorithm should succeed without prompting + the user, show the user a prompt to decide whether to succeed, or fail + without prompting the user. The UA must return whichever of these values + most accurately reflects the user's intent, except that if the current + settings object is a non-secure context and
|descriptor|.{{PermissionDescriptor/name}}
isn't allowed in non-secure contexts, then the UA must return {{"denied"}}. Subsequent uses of |descriptor|'s permission state with the same From 5a9d3636c7cf338c69fba025ea0362ab3e6ffb3d Mon Sep 17 00:00:00 2001 From: Marcos CaceresDate: Mon, 11 Jul 2016 15:10:33 +1000 Subject: [PATCH 4/9] chore(reading current state): editorial fixes --- index.bs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/index.bs b/index.bs index 863a968..a648190 100644 --- a/index.bs +++ b/index.bs @@ -204,11 +204,19 @@ spec: webidl |descriptor|'s permission state is one of {{"granted"}}, {{"prompt"}}, or {{"denied"}}, indicating respectively - if the calling algorithm should succeed without prompting - the user, show the user a prompt to decide whether to succeed, or fail - without prompting the user. The UA must return whichever of these values - most accurately reflects the user's intent, except that if the current - settings object is a non-secure context and + if the calling algorithm should: +
+ ++
+ +- succeed without prompting the user ({{"granted"}}),
+- show the user a prompt to decide whether to succeed ({{"prompt"}}), or
+- fail without prompting the user ({{"denied"}}).
++ The UA returns whichever of these values most accurately reflects the user's + intent, except that if the current settings object is a + non-secure context and
|descriptor|.{{PermissionDescriptor/name}}
isn't allowed in non-secure contexts, then the UA must return {{"denied"}}. Subsequent uses of |descriptor|'s permission state with the same From 54f4a81c5ebda7ab61651f2229a4011ef718c974 Mon Sep 17 00:00:00 2001 From: Marcos CaceresDate: Mon, 11 Jul 2016 15:13:39 +1000 Subject: [PATCH 5/9] fix(Requesting more perm): RFC2119 words in note --- index.bs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index a648190..5fb3f0d 100644 --- a/index.bs +++ b/index.bs @@ -249,8 +249,9 @@ spec: webidl Requesting more permission
- The algorithms in this section may wait for user input, so they should not - be used from other algorithms running on the main thread. + Spec authors, please note that algorithms in this section can wait for + user input; so they shouldn't be used from other algorithms running on + the main thread.
From 4e294dc08198bf2a4ef80a5173786bb9e48ce42e Mon Sep 17 00:00:00 2001 From: Marcos CaceresDate: Mon, 11 Jul 2016 15:18:02 +1000 Subject: [PATCH 6/9] chore(request perm to use): use an explicit variable --- index.bs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/index.bs b/index.bs index 5fb3f0d..93fad1e 100644 --- a/index.bs +++ b/index.bs @@ -262,8 +262,12 @@ spec: webidl
- - If |descriptor|'s permission state is not {{"prompt"}}, return - that value and abort these steps. + Let current state be the |descriptor|'s permission + state. +
+- + If current state is not {{"prompt"}}, return + current state and abort these steps.
- Ask the user's permission for the calling algorithm to use the From 1b197a7787b85bcce64b0feca590a1ef9626d6d3 Mon Sep 17 00:00:00 2001 From: Marcos Caceres
Date: Mon, 11 Jul 2016 15:43:54 +1000 Subject: [PATCH 7/9] chore(reacting-to-revocation): link to feature --- index.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/index.bs b/index.bs index 93fad1e..43249ac 100644 --- a/index.bs +++ b/index.bs @@ -331,10 +331,10 @@ spec: webidl Reacting to users revoking permission
- When the UA learns that the user no longer intends to grant permission for - a realm to use a feature, it must queue a task on the - Realm's settings object's responsible event loop to run that - feature's permission revocation algorithm. + When the UA learns that the user no longer intends to grant permission + for a realm to use a feature, it must queue a task + on the Realm's settings object's responsible event loop to + run that feature's permission revocation algorithm.
From 4e2c6eef11caec01f3ae547640d72a51a3350eea Mon Sep 17 00:00:00 2001 From: Marcos CaceresDate: Wed, 20 Jul 2016 18:11:57 +1000 Subject: [PATCH 8/9] refactor: rephrase algo step as if statement --- index.bs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/index.bs b/index.bs index 43249ac..91afe11 100644 --- a/index.bs +++ b/index.bs @@ -275,9 +275,10 @@ spec: webidl - If the user grants permission, return {{"granted"}}; otherwise return - {{"denied"}}. Depending on the details of the user's interaction, the - UA may also treat this as new information about the user's - intent for other realms with the same origin. + {{"denied"}}. If the user's interaction indicates they intend this + choice to apply to other realms, then treat this as new information + about the user's intent for other realms with the same + origin.
This is intentionally vague about the details of the permission UI @@ -314,9 +315,10 @@ spec: webidl
- If the user chose an option, return it; otherwise return {{"denied"}}. - Depending on the details of the user's interaction, the UA may also - treat this as new information about the user's intent for other - realms with the same origin. + If the user's interaction indicates they intend this choice to apply + to other realms, then treat this this as new information about + the user's intent for other realms with the same + origin.
This is intentionally vague about the details of the permission UI From c9838be7de57b795bf5a7a2390ab41df9a67b978 Mon Sep 17 00:00:00 2001 From: Marcos Caceres
Date: Wed, 20 Jul 2016 18:27:17 +1000 Subject: [PATCH 9/9] fix(permission state): make this an explicit algorithm --- index.bs | 102 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/index.bs b/index.bs index 91afe11..ea0667e 100644 --- a/index.bs +++ b/index.bs @@ -201,49 +201,73 @@ spec: webidl Reading the current permission state
-- |descriptor|'s permission state is one - of {{"granted"}}, {{"prompt"}}, or {{"denied"}}, indicating respectively - if the calling algorithm should: -
++-+ A |descriptor|'s permission state is + the result of the following algorithm, which returns one of + {{"granted"}}, {{"prompt"}}, or {{"denied"}}: +
++
-- + If the current settings object is a non-secure context + and
+|descriptor|.{{PermissionDescriptor/name}}
isn't + allowed in non-secure contexts, then return {{"denied"}}. +- + If there was a previous invocation of this algorithm with the same + |descriptor| and current settings object, returning + |previousResult|, and the UA has not received new information about + the user's intent since that invocation, return |previousResult|. +
+- + Return whichever of the following options most accurately reflects the user's + intent for the calling algorithm: +
++
+- succeed without prompting the user
+- {{"granted"}}
--
+- succeed without prompting the user ({{"granted"}}),
-- show the user a prompt to decide whether to succeed ({{"prompt"}}), or
-- fail without prompting the user ({{"denied"}}).
-- show the user a prompt to decide whether to succeed
+- {{"prompt"}}
-- The UA returns whichever of these values most accurately reflects the user's - intent, except that if the current settings object is a - non-secure context and -
+|descriptor|.{{PermissionDescriptor/name}}
isn't allowed - in non-secure contexts, then the UA must return {{"denied"}}. - Subsequent uses of |descriptor|'s permission state with the same - current settings object must return the same value, unless the UA - receives new information about the user's intent. -- fail without prompting the user
+- {{"denied"}}
+- Safari is the only known UA that returns different results from this - algorithm for different settings objects with the same origin. We should - test which of the several - possible settings objects it uses. -
++ Safari is the only known UA that returns different results from this + algorithm for different settings objects with the same origin. We should + test which of the several + possible settings objects it uses. +
+- Some powerful features have more information associated with them - than just a {{PermissionState}}. For example, - {{MediaDevices/getUserMedia()}} needs to determine which cameras - the user has granted the current realm permission to access. Each - of these features defines an extra permission data type, and then a - {{PermissionName}} |name|'s extra permission data is the - instance of that type matching the UA's impression of the user's intent. - Subsequent uses of |name|'s extra permission data must return the - same value, unless the UA receives new information about the user's - intent. -
+++ Some powerful features have more information associated with them + than just a {{PermissionState}}. For example, + {{MediaDevices/getUserMedia()}} needs to determine which cameras + the user has granted the current realm permission to access. Each + of these features defines an extra permission data type. If a + {{PermissionName}} |name| names one of these features, then |name|'s + extra permission data is the result of the following + algorithm: +
++
+- + If there was a previous invocation of this algorithm with the same + |name| and current settings object, returning + |previousResult|, and the UA has not received new information about + the user's intent since that invocation, return |previousResult|. +
+- + Return the instance of |name|'s extra permission data type that + matches the UA's impression of the user's intent. +
+Requesting more permission