w3c / permissions

Permissions API
https://www.w3.org/TR/permissions/
Other
107 stars 51 forks source link

Semantic Permission Bundles #191

Open tomayac opened 5 years ago

tomayac commented 5 years ago

In https://github.com/w3c/deviceorientation/pull/68#discussion_r265404566, @cdumez wrote the following:

[A]ll I can say is that I find the terms "accelerometer", "gyroscope" and "magnetometer" confusing when it comes to [the DeviceOrientation Event] specification. As in it is not obvious which string relates to which event.

Has there been any previous discussion around specifying a semantic grouping of lower-level permissions to form higher-level permission "bundles" (in lack of a better term)? For example, for motion sensors access, the permission an app would request could potentially just be "motion-sensors" rather than all of "accelerometer", "gyroscope", and "magnetometer"?

This would arguably be more intuitive both for developers needing motion sensor data (but maybe unaware of the underlying sensor mechanics) as well as for end users who would need to make a decision when prompted.

User agents could already now present such lower-level access requests grouped (as outlined in https://github.com/w3c/permissions/issues/92#issuecomment-216825056), however, this requires the user agent to recognize that certain permissions belong together (in the code, they could be requested parallelly or serially, or maybe with navigator.permissions.requestAll()), and different user agents might handle this differently, which may be either good or bad, depending on one's viewpoint.

Looking at the permission registry, another candidate for permission bundles could be ("camera" + "microphone" = "camera-microphone"). Or—maybe more visionary and with a to-be-bikeshed name—also ("background-fetch" + "background-sync" + "persistent-storage" + "clipboard" = "web-application").

I reckon that this is somewhat orthogonal to the static method approach DeviceMotionEvent.requestPermission() from @cdumez' https://github.com/w3c/deviceorientation/pull/68 in the concrete case, and more aligned with what @reillyeon commented on in https://github.com/w3c/deviceorientation/issues/57#issuecomment-447129020.

(CC: @anssiko) (Related issue: https://github.com/w3c/permissions/issues/92)

marcoscaceres commented 3 years ago

@tomayac, @anssiko, @reillyeon I'd be interested in maybe just handing the device API/DAS ones for now.

I wonder if the sensor ones should be bundled into a single permission? Or is there a strong use case for having them separate?

anssiko commented 3 years ago

As for sensors, I recall the consensus of the group was that bundling to a single permission would regress in terms of privacy protections, albeit it'd improve developer ergonomics. So the high-level use case would be privacy. This was quite a complex issue and it was extensively discussed. I put this to the TPAC agenda https://github.com/w3c/devicesensors-wg/issues/47 so we can have another discussion.

Here's an example that I hopefully got right. A user might be OK to grant permission to accelerometer and gyroscope, but not magnetometer given it could theoretically disclose the user's location. What follows is that the page could use relative orientation (a fusion of accelerometer and gyroscope), but not absolute orientation (a fusion of accelerometer, gyroscope and magnetometer). See https://w3c.github.io/motion-sensors/#fusion-sensors for a mapping table from fusion to physical sensors.

This is explained in https://w3c.github.io/sensors/#permission-api using different words.

If such a permission bundle would be defined, would its permission state be transitive to low-level permission states? In both directions? There are probably a bunch of other design considerations that need to be looked into.

WebKit implements the accelerometer, gyroscope and magnetometer policy-controlled features (was feature policies) that map 1-on-1 to the permission registry names, and Chrome also ships these.

tomayac commented 3 years ago

Sensors are complex, as @anssiko pointed out. Perspectively, on the Chrome team, we have been talking about the possibility of having concepts like "Productivity APIs" (file system, clipboard, fonts,…) or "Communication APIs" (camera, microphone) and others that could be bundled together. Not sure to what extent this needed to be spec'ed, or to what extent this could just be something apps can ask for and the UA would then display in a combined prompt with maybe opt-out options so by default users could accept the whole bundle, but also have individual control. I recall @aarongustafson had ideas along these lines, too…

reillyeon commented 3 years ago

I don't have a particularly strong opinion on whether or not the permissions for the motion and orientation sensors should be bundled together. From a practical standpoint I think the most important action we should take here is to specify which permissions are requested by the DeviceOrientationEvent.requestPermission() and DeviceMotionEvent.requestPermission() methods. The only open question I see that is raised by trying to specify the behavior of those methods is whether DeviceOrientationEvent.requestPermission() requests "magnetometer" or not. One option is that it does, but if "magnetometer" is denied then the overall request can still succeed but the deviceorientationabsolute event is not available.

marcoscaceres commented 3 years ago

@anssiko wrote

As for sensors, I recall the consensus of the group was that bundling to a single permission would regress in terms of privacy protections, albeit it'd improve developer ergonomics. So the high-level use case would be privacy. This was quite a complex issue and it was extensively discussed. I put this to the TPAC agenda w3c/devicesensors-wg#47 so we can have another discussion.

Discussing at TPAC sounds great... and yeah, it's a hard problem for the reasons you outline.

Basically, @tomayac summed it up nicely with:

could potentially just be "motion-sensors" rather than all of "accelerometer", "gyroscope", and "magnetometer"

I'm wondering, in Chrome, what permission UI does "motion sensors" control?: motion sensor selector

@tomayac wrote:

Not sure to what extent this needed to be spec'ed, or to what extent this could just be something apps can ask for and the UA would then display in a combined prompt with maybe opt-out options so by default users could accept the whole bundle, but also have individual control.

Yeah, this is the core of my question... as a developer, do I want to .query() for each of the device sensors, or just for "motion-sensors"? I'm kinda torn here, as I see advantages/disadvantages to both. But basically, if "motion-sensors" enables and disables all the APIs, then one could query({name: "motion-sensors"}), and then call .requestPermission() on the appropriate API.

However, AccelerometerPermissionDescriptor seems to have specific requirements like highAccuracy and highFrequency... are those surfaced in a Permissions UI? (I'm sorry, I'm not able to check these things myself - I'm lacking an Android mobile device).

@reillyeon wrote:

The only open question I see that is raised by trying to specify the behavior of those methods is whether DeviceOrientationEvent.requestPermission() requests "magnetometer" or not. One option is that it does, but if "magnetometer" is denied then the overall request can still succeed but the deviceorientationabsolute event is not available.

Agree. This is also what I'm trying to understand.

reillyeon commented 3 years ago

I'm wondering, in Chrome, what permission UI does "motion sensors" control?: motion sensor selector

This question seems backwards to me. This is a screenshot of the permissions UI. The question is what APIs it controls. As implemented in Chromium it corresponds to the union of "accelerometer", "gyroscope" and "magnetometer". The mapping in Chromium between the Permission API concepts and the internal representation of permissions is here.

marcoscaceres commented 3 years ago

This question seems backwards to me.

I know, please stay with me 😅 I got myself an Android device.

If I visit the generic-sensor-demos, it runs the demos without any permission prompts and there doesn't seem to be any means for a user to disable individual access to those APIs via "site settings".

Is that correct or am I missing something?

The question is what APIs it controls. As implemented in Chromium it corresponds to the union of "accelerometer", "gyroscope" and "magnetometer". The mapping in Chromium between the Permission API concepts and the internal representation of permissions is here.

Got it:

CreatePermissionDescriptor(PermissionName::SENSORS);

So, just to be sure: does that mean that if a user hypothetically grants permission to "accelerometer", they also implicitly grant access to "gyroscope" and "magnetometer"?

If yes, then "motion-sensors" might be appropriate here.

But, if permission to generic sensors is just blanket "granted" without any permission prompt (and there is no way for the user to disable these APIs via UI), then maybe we don't need these permissions at all? (as they relate to this API, not to Permissions Policy)

reillyeon commented 3 years ago

So, just to be sure: does that mean that if a user hypothetically grants permission to "accelerometer", they also implicitly grant access to "gyroscope" and "magnetometer"?

Correct, the Chromium implementation treats these permissions as a single bucket.

If yes, then "motion-sensors" might be appropriate here.

Yes, I think specifying these as a single permission bundle is fine. In theory the threat model for each of them is slightly different but I don't expect that to be easy to explain to users and so browsers are unlikely to differentiate. It only seems more future-proof to keep them separate (and define the mapping to high-level concepts).

But, if permission to generic sensors is just blanket "granted" without any permission prompt (and there is no way for the user to disable these APIs via UI), then maybe we don't need these permissions at all? (as they relate to this API, not to Permissions Policy)

Chromium grants the "motion-sensors" permission by default and the UI you posted a screenshot above allows the user to change that default from "allow" to "block". Was is missing in the Chromium implementation (tracked by issue 947112) is an implementation of the requestPermission() methods which would allow a site to request permission to use the "motion-sensors" permission if the user changed the default to "prompt" (which is not currently a selectable option since the API is missing).

tomayac commented 2 years ago

A good candidate for such a semantic permissions bundle would be a videoconferencing permission, consisting of camera, microphone, and notifications. I see so many apps in the VC space request those permissions separately, which causes user confusion, but of course is necessary for the VC app to let users talk and be notified of incoming calls.

I imagine a prompt UI where the permissions would be presented together under a label like “video conferencing” and could be accepted with one click, but where the prompt UI would still allow users to unselect individual permissions they don’t want to grant.

jan-ivar commented 2 years ago

I see arguments here for prompt bundling, not necessarily permission bundling.

A good candidate for such a semantic permissions bundle would be a videoconferencing permission, consisting of camera, microphone, and notifications. I see so many apps in the VC space request those permissions separately

I think you mean you see separate prompts, because sites don't request permission to camera and microphone, they request camera and microphone. The prompt-on-use mental model is the antithesis to up-front bundling, and generally better.

Camera and microphone requests can already be bundled in getUserMedia.

I think we need to be careful about separating UX from API, and not have the former drive the latter. Specifically, we should first examine whether user agents can solve prompt bundling without requiring changes in API or model. For instance:

const [stream, permission] = await Promise.all([
  navigator.mediaDevices.getUserMedia({video: true, audio: true}),
  Notification.requestPermission()
]);

...seems a detectable pattern to any user agent that wishes to experiment with prompt bundling today, even calling it "video conferencing" if they think this is a good idea. Backward and forward compatible even!

But even before that, we should ask whether prompt bundling is a good thing in the first place. We already know most people don't read prompts, and that the rate drops the more text is in them. So any bundling here would result in notifications piggybacking on camera and microphone in practice for many users.

Another, perhaps more intuitive solution to the double-prompt problem is to push back on sites' perceived need to request notification permission upfront in the first place. It's a bad time to ask the user who is merely trying to get into the room (maybe a few minutes late even!)

They only care about notifications later when e.g. someone pings them in chat. That's arguably the most relevant time to ask the user permission (if the user agent thinks it is needed). If the web platform is pushing sites to ask early, we should perhaps address that instead?

tomayac commented 2 years ago

Specifically, we should first examine whether user agents can solve prompt bundling without requiring changes in API or model. For instance:

const [stream, permission] = await Promise.all([ navigator.mediaDevices.getUserMedia({video: true, audio: true}), Notification.requestPermission() ]);

That’s an interesting idea; paired with Promise.*() (like, for example, Promise.any()), it could be made as forgiving or not to the denial of individual promises as the app deems necessary. Not sure how feasible it would be to actually detect such patterns in practice, but I’m acknowledgedly not an expert there. It seems not impossible for sure.

They only care about notifications later when e.g. someone pings them in chat.

If the site hasn’t asked for permission, some users may never even see that they are being pinged.

jan-ivar commented 2 years ago

Not sure how feasible it would be to actually detect such patterns in practice

Queue a task and count requests? The important part isn't the promises, but that the APIs are invoked on the same task:

navigator.mediaDevices.getUserMedia({video: true, audio: true});
Notification.requestPermission();

If the site hasn’t asked for permission, some users may never even see that they are being pinged.

Can't the UA ping them about the permission request?