SecurityPermissions

Ubuntu has two systems for controlling whether users and apps can perform particular tasks.

Both systems involve authentication prompts.

Snap interfaces

If an app tries to access any of these interfaces, it should be subject to permission:

Interface

Permission label

Prompt text

unity8-calendar

Calendar

wants to read/change your calendar

Camera

wants to take photos

unity8-contacts

Contacts

wants to read/change your contacts

In-app purchases

wants to offer in-app purchases

Location

wants to track your location

Microphone

wants to use the microphone

Video recording

wants to record video

online-accounts-service

physical-memory-observe

storage-framework-service

“Video recording” should be separate from “Camera” so that:

  • When you use a camera app, having prompted you for access to the camera on first launch, it then prompts you for access to “record video” rather than weirdly “the microphone” when you first access the video function.
  • When you use any app that records only video — such as Periscope or Ustream — it needs to prompt you only once, rather than separately for the camera and microphone.

Therefore, if an app has permission to record video, it should have access to the microphone when (and only when) it is recording video.

(In Ubuntu Touch, sometimes an app needed access only to a single stored item — for example, a single contact or a single photo. In this case, the app accessed it through the content picker, rather than asking for access to all items of that type.)

App labels

So that apps are identified consistently in permission prompts, lists, and elsewhere:

  • Normally, an app label should be the app’s name: in the case of a snap, its title. (“Installed apps:” also lists apps that are not snaps, since people can’t generally be expected to know and remember which are and which aren’t.)

  • If a .deb and a snap of the same app are installed, the app label should end with “ (.deb)” or “ (snap)”: for example, “JazzWriter (.deb)”. (If they have installed both, someone can be expected to understand the difference.)

  • If snaps have identical titles but the publisher is different, the app label should end with the publisher username in brackets: for example, “JazzWriter (Snapcrafters)”.

  • If snaps’ title and publisher are identical but the version number is different, the app label should end with the version number in brackets: for example, “MegaChess (1.0.1)”.

  • In the diabolical case where the title, publisher, and even version number are identical, the version number should be followed by “r” and the revision number: for example, “MegaChess (1.0.1 r67)”.

Permission prompts

All these prompts should take the form of a dialog that contains:

  • the app icon
  • the app label, sanitized and ellipsized if necessary

  • the app ID and publisher ID, in small print.

(The app icon, ellipsized label, app ID, and publisher ID are to protect against one app spoofing a different app.)

The layout of the prompts forms a sentence similar to structure “{app} wants to {do something}”. In some languages it may not be grammatically possible to construct a sentence this way. If so, in that language the prompt text should instead be a complete sentence of its own referring to the app above: “This app wants to {do something}.” Each prompt text string should have a translator note explaining this.

For all these prompts, because you are likely not expecting it, neither button should be default.

For all prompts that show a list of permissions:

  • The list should be a fixed height, scrolling if necessary.
  • To clarify that it does scroll (and so prevent scurrilous permissions hiding below innocuous ones), the height should be such that a line of text is half-clipped at the bottom.

Installing an app with required interfaces

If all the interfaces have installed implementations

This prompt should appear before the software begins to download.

prompt-install-implemented.png

If any of the interfaces do not have installed implementations

This prompt should appear before the software begins to download. In rare cases, this prompt will appear immediately after the previous one.

prompt-install-unimplemented.png

Launching an app with required interfaces, any without an installed implementation

This is the unusual case where you chose “Install Anyway” above, still didn’t install the needed software, and then tried to launch the app regardless. (Or you installed the app while having implementations of all necessary interfaces, and later removed one or more of the implementations.)

prompt-launch-unimplemented.png

This dialog should be parentless, and therefore it should have “Ubuntu” as its title (the entity perceived to be responsible for launching apps).

App tries to use an optional interface at runtime

To prevent an app DoSing you into submission, if it tries to access an interface and you have previously denied it, it should silently be denied again. It’s then up to the app to either do without, or to plead with you to change it with a button for opening the relevant System Settings screen.

If you have not previously denied it, a prompt should open.

If the app does not currently have any windows open, the prompt should be parentless and therefore should have “Ubuntu” as its title. Otherwise, if the app has any windows open, then:

  • if one of them is the focused window, that should be the dialog’s parent;
  • if none of them have input focus, the frontmost window should be the dialog’s parent.

If the interface has an installed implementation

Ubuntu for PC

Ubuntu Touch (retired)

For the first two seconds

prompt-runtime-implemented-initial.png

permission-prompt-service-initial.phone.png

Afterwards

prompt-runtime-implemented.png

permission-prompt-service.phone.png

To avoid clickjacking an “Allow” click, the buttons should be disabled for the first two seconds that the prompt is open. For visual reassurance, a determinate spinner should fill over that two seconds.

If the interface does not have an installed implementation

prompt-runtime-unimplemented.png

As well as launching your snap client to the appropriate search, “Search Ubuntu Store…” should deny the app permission (to avoid blocking its UI for the whole time you are browsing). But the app should automatically be removed from the blacklist, so that it can prompt again, when either (a) 24 hours has passed or (b) you’ve installed any software that provides the interface.

Permission lists

When you make a choice, in any of those prompts, to allow or deny a permission, that app should be added to the relevant access list(s) in System Settings (if it wasn’t there already), with its toggle switch state corresponding to your response. If an app is uninstalled, the setting should be cleared, so that it doesn’t show up in the permission lists (bug 1389775) — and so that, for lower-knowledge users, reinstalling works as a way of correcting a mistaken decision.

“App Permissions”

“App Permissions” is the global list of installed interface permissions, and apps that have access to each.

This list alone could be a minimal implementation, since it at least provides access to each app×permission combination, though some will not be where people expect to find them.

“View by app”

Ubuntu for PC

app-permissions-by-app.pc.png

“View by app” should be the default selection, since for the most privacy- or security-concerning permissions, users are likely to look in the relevant tab (Location, Camera) or panel (Sound, Networking, or Printing) instead once app permissions are integrated there.

When “View by app” is selected:

  • “Installed apps:” should list all detected installed apps, each with its icon and label. If the list takes more than two seconds to load, it should load incrementally if possible, with a spinner above the top right corner. Alternatively, if the list can’t load incrementally, the listbox should be empty for up to two seconds, and then contain a centered spinner and text “Indexing… ({current number of apps})” until loading is complete.

    • app-permissions-by-app-loading-incremental.png app-permissions-by-app-loading-blocked.png

  • “Installed apps:” should always have exactly one app selected, so that the second pane is always “Permissions for {app label}:”. (If the app list is empty, the permissions pane should be both empty and unlabelled.)
  • “Permissions for {app label}:” should list all interfaces that the app has requested access to: first any that have a permission label (sorted alphabetically by label), then any that don’t (sorted alphabetically by interface name), with a separator between the groups if they are both present. Permissions that can be changed should have a switch representing the current state.

    • If the app is unconfined (whether classic, devmode, or .deb), the pane should instead contain centered text: “This app is unconfined. It can access all personal files and system resources.”

      app-permissions-by-app-unconfined.png

  • The caption “Any apps not listed here are unconfined, with access to all personal files and system resources.” covers apps that are not detected because they were built from source, installed in your home folder, and so on.

“View by permission”

Ubuntu for PC

Ubuntu Touch (retired)

app-permissions-by-permission.pc.png

app-permissions.2.phone.png

phone-access-contacts.png

When “View by permission” is selected:

  • “Permissions:” should list all interfaces that have an installed implementation: first any that have a permission label (sorted alphabetically), then any that don’t (sorted alphabetically by interface name), with a separator between the groups if they are both present.

  • The list item for each permission should have a grey summary value, of the form “{number of apps granted}/{number of apps requested}”, for example “7/9 or “0/1”. If no apps have requested access to that property yet, the summary value for the permission should simply be “0”.
  • “Apps that requested this permission:” should list first any that required the permission on install (labelled “Required”), then any that requested the permission at runtime (labelled “Optional”), with a separator between the groups if they are both present. Permissions that can be changed should have a switch representing the current state.
  • The caption “Apps may also request access to Internet accounts.”, and button navigating to Internet Accounts settings, reflects that those are not snap interfaces but that they behave similarly and users likely think of them similarly.

Location permissions

TBD

Camera permissions

TBD

Audio permissions

TBD

Printing permissions

TBD

Why did we take this approach?

Older versions of Android ask you to grant access to every permission an app might need before you install it. This is poor design for two reasons.

First, of all the time you spend with an app, the moment you’re about to install it is the moment when you know the least about it. So it’s the moment when you’re least able to make informed decisions about granting those privileges. And if an app developer can assume that consent will be uninformed, they're more likely to abuse that consent, by asking for privileges they don’t really need.

Second, an app might need a privilege only for an uncommon function that you personally will never use. Asking for that permission before installation would give you the wrong idea about how invasive the app is.

Both these problems are addressed by apps asking for access privileges at the moment they need them. It is still possible that an app might ask for a privilege needlessly, or without enough explanation on launch. But if so, you would likely downrate and/or uninstall it.

PolicyKit

Authentication API

A request for authentication should have:

  • The action that you are trying to perform. This includes a plain-text description of why you are being asked to authenticate, and a group of user accounts that are allowed to perform the action. In PolicyKit, these are specified in .policy files.

  • An optional parent window. This is so that the authentication dialog can be modal to that window.

The prompt

prompt-simple.png prompt-complex.png

The authentication prompt should vary in appearance depending on whether it has a parent window, who you are logged in as, who you need to authenticate as, which authentication methods are required, and whether you previously authenticated unsuccessfully.

Title and placement

If the request for authentication has a parent window, and that window is still open, then the alert should be modal to the parent window (fixing bug 420641 and bug 877265) and should have no title.

Otherwise, the alert should have the title “Authenticate”, and should not be modal to anything (see bug 797960), so it should be minimizable.

Icon

As long as full-screen programs and screenshots are both allowed, it is impossible to style an authentication prompt in a way that prevents spoofing by a program running on your computer. For example, a system-modal shell-integrated prompt could easily be spoofed by taking a screenshot, displaying it full-screen, applying the same visual effects the real prompt does, and embedding an imitation prompt. If a baddie’s unconfined program is running on your computer, you’ve already lost.

What we can do, however, is to reduce the feasibility of spoofing the prompt on a remote Web page. We do this by using something that you know but Web sites don’t: the icon of your Ubuntu user account.

prompt-icon.png

Therefore, the icon for the prompt should be the standard keyring icon, overlaid in its bottom-right quarter with your Ubuntu user account icon.

(This is still subject to the Simon-says problem: you have to notice that the icon is missing to realize that it’s a spoof. But it’s better than nothing.)

After an authentication error, the icon should be the standard error icon, overlaid with your Ubuntu user account icon in the same way.

Primary text

The primary text of the alert should be the message for the action.

Secondary text

Normal prompt

If only password authentication is required

If other authentication is required

If you are in the allowed group

Ubuntu needs you to enter your login password.

Ubuntu needs you to authenticate.

If you aren’t in the allowed group, which is admin (fixing bug 920174)

Ubuntu needs an administrator to authenticate.

If you aren’t in the allowed group, which is anything else (fixing bug 961473)

Ubuntu needs a member of the “{name of group}” group to authenticate.

After incorrect authentication

If only password authentication is required

If other authentication is required

If you are in the allowed group

Your Ubuntu login password was incorrect. Please try again.

Your authentication details were incorrect. Please try again.

If you aren’t in the allowed group, which is admin

Your administrator authentication details were incorrect. Please try again.

If you aren’t in the allowed group, which is anything else

Your “{name of group}” authentication details were incorrect. Please try again.

Credential fields

If you are not in the allowed group, the first control should be “Login name:” (fixing bug 437508). This should be a combo box if you have permission to see the list of user accounts in the allowed group, or a text field if you don’t.

Next should be whichever credential fields are required for the user account, action, or group. “Password:” should be a standard password field. If a fingerprint or smart card can be used either for identification or authentication, “Fingerprint:” or “Smart card:” should be a slowly-animating scanner icon with the text “Scanning…”, replaced by a checkmark icon and the text “Scanned” once it is.

When the prompt opens, the first credential field should be focused, for example the “Password:” field if there is no “Login name:” field.

Details

prompt-details.png

“Details” should always be collapsed by default. Expanding it should reveal a two-column table in small font, of “Vendor:”, “Program:”, and “Action:”, aligned with the credential fields above. Only the “Vendor” value should be a hyperlink to the vendor’s Web site.

Commit buttons

“Cancel” should have Esc as its access key, “Continue” should have Enter. “Continue” should be insensitive whenever you have not provided the appropriate credentials, for example when the “Password:” field is empty.

When you choose “Continue”, all the controls in the prompt should become insensitive while the authentication takes place. If it succeeds, the prompt should close. If it fails, the icon and secondary text should change to their error states, and the controls should become sensitive again.

prompt-error.png

SecurityPermissions (last edited 2018-03-01 12:30:32 by mpt)