From 58f0dbf10f06baae7a68739f6e28a9659069caab Mon Sep 17 00:00:00 2001 From: Marcos Caceres Date: Mon, 11 Jul 2016 13:45:59 +1000 Subject: [PATCH 1/9] chore(scope): editorial cleanup --- index.bs | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/index.bs b/index.bs index a2b428b..cd651c0 100644 --- a/index.bs +++ b/index.bs @@ -73,31 +73,25 @@ spec: webidl

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.

From 356e1372eb0ebdf2458f5fd6615e904ec368a829 Mon Sep 17 00:00:00 2001 From: Marcos Caceres Date: Mon, 11 Jul 2016 13:54:45 +1000 Subject: [PATCH 2/9] chore(privacy): editorial cleanup --- index.bs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/index.bs b/index.bs index cd651c0..2270cc4 100644 --- a/index.bs +++ b/index.bs @@ -100,14 +100,15 @@ spec: webidl

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.

From 74ef777b6d88346f1e51b2a14b312736afda818e Mon Sep 17 00:00:00 2001 From: Marcos Caceres Date: Mon, 11 Jul 2016 14:54:08 +1000 Subject: [PATCH 3/9] chore(desc perm request): fixup linking --- index.bs | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/index.bs b/index.bs index 2270cc4..863a968 100644 --- a/index.bs +++ b/index.bs @@ -104,11 +104,11 @@ spec: webidl "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. + 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.

@@ -123,7 +123,7 @@ spec: webidl or other sources this specification hasn't anticipated. -
Powerful feature
+
Powerful feature
A feature of a UA that some code might not be allowed to access, for example because its environment settings object doesn't satisfy @@ -141,16 +141,15 @@ spec: webidl };

- 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: webidl
   

Reading 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 Caceres Date: 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 Caceres Date: 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 Caceres Date: 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

  1. - If |descriptor|'s permission state is not {{"prompt"}}, return - that value and abort these steps. + Let current state be the |descriptor|'s permission + state. +
  2. +
  3. + If current state is not {{"prompt"}}, return + current state and abort these steps.
  4. 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 Caceres Date: 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"}}: +

    +
      +
    1. + If the current settings object is a non-secure context + and |descriptor|.{{PermissionDescriptor/name}} isn't + allowed in non-secure contexts, then return {{"denied"}}. +
    2. +
    3. + 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|. +
    4. +
    5. + 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"}}
      +
      +
    6. +
    -

    - 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: +

    +
      +
    1. + 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|. +
    2. +
    3. + Return the instance of |name|'s extra permission data type that + matches the UA's impression of the user's intent. +
    4. +
    +

    Requesting more permission