{% set rfcid = “RFC-0150” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
We describe a new ability for product owners to allow users of their products to opt out of receiving software updates. We describe the policies associated with this mechanism, the ways in which it should be used, and the security mechanisms associated with storing the setting. Finally, we describe how other components on the system may observe whether the system is opted out of updates.
We have a requirement from customers to allow users of Fuchsia devices to opt out of receiving updates. We must satisfy that requirement in a way that is as secure as possible for all users, regardless of their opt-out status.
Facilitator:
Reviewers:
Consulted:
Socialization:
This RFC went through a design phase with the Software Delivery team, the Security and Privacy teams, and customers.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in IETF RFC 2119.
omaha-client
is our production system update checker. It communicates with an Omaha server run by the product owner or a delegate. Together, the Omaha client and server periodically negotiate a system or package version to install.
We propose that a product owner can enable the existence of this feature on a product by statically building in a flag in the Software Delivery configuration.
A new SWD component called update-settings-storage
will serve a FIDL API called fuchsia.update.config.OptOut
to read this option and an API called fuchsia.update.config.OptOutAdmin
to write this option. This API will need to be exposed in the SDK to allow product-level components to toggle the option's value on and off.
The fuchsia.update.config.OptOutAdmin
API must be strictly protected by capability routing and Scrutiny verification, to ensure that no unauthorized components gain access to it.
Reading the value of the opt-out setting using fuchsia.update.config.OptOut
should be allowed to allowlisted components on the system with looser controls than OptOutAdmin
. This will allow components at the system and product level to make decisions based on whether the device is opted out of updates, and provide settings and troubleshooting views of this option.
The component serving the OptOut
API, update-settings-storage
, must persist the value of the opt-out setting across reboots, and must persist the setting in integrity-protected storage. For instance, minfs
storage of this setting without an accompanying hash and signature on the storage would be insecure, and is disallowed.
We propose using hardware tamper-resistant storage (currently the only option on Fuchsia devices is RPMB) to store this opt-out setting. The property we desire from tamper-resistant storage is that it cannot be written to except by a signed Trusted Application, or rogue writes can be detected.
These storage APIs exist on the required products and should be exposed through the Verified Execution Trusted Application (VX TA) which is signed and authenticated via hardware measures at boot.
On each scheduled update check omaha-client
should read from update-settings-storage
using the OptOut
FIDL API, and send the opt-out value to Omaha using the existing updatedisabled
field in the Omaha protocol.
If the system is running on the recovery partition, updatedisabled
should always be false
. Similarly, if the update check was user-initiated, updatedisabled
should always be false
.
If the Omaha server receives an update check with updatedisabled
equal to true
, it should return NoUpdate
for that Omaha Application's response, except for critical updates designated by the product owner.
There is an alternative here, which is to not send any Omaha update checks at all if the device is opted out of updates. However, that alternative denies the product owner metrics on how many users are opted out of updates, and denies the product owner the ability to push critical updates (by overriding updatedisabled
field if required, on the server).
The opt-out must apply to all applications for which omaha-client
is checking for updates, including system updates and single packages.
Implementation will take place between the SWD, firmware, security, and update server teams. The task breakdown is roughly as follows, and should correspond to CL chains to be submitted.
fuchsia.update.config.OptOut
FIDL APIupdate-settings-storage
componentfuchsia.update.config.OptOut
from omaha-client
at update check time, forward to Omaha server as updatedisabled
flag (unless the device is in recovery or the check was user-initiated)fuchsia.update.config
in the SDK, and allowlist both protocols.omaha-client
to count the number of opted-out devicesomaha-client
NoUpdate
for all Application Update Check Requests if updatedisabled
is true for that Application.There should be no noticeable impact on system or update check performance. Update checks are infrequent (on the order of hours), and not particularly latency sensitive.
Our read API for this setting will help reduce possible developer or user confusion, as will Inspect and Cobalt logging of the opt-out state.
This RFC presents no backwards compatibility issues that we know of.
Updates are Fuchsia‘s most important security feature. Without updates, the Fuchsia team cannot patch vulnerabilities in the platform. More importantly, having this code exist on the device at all is a risk to all users whether or not they’ve opted out of updates: if an attacker gains sufficient privileges, they can change the update opt-out setting and increase their chances of persisting forever.
This design attempts to mitigate risk in the following ways:
The following risks still exist:
update-settings-storage
or the VX TA and ask them to modify the settingThe following security improvements are not scoped at this time, but could be considered for future iterations:
This design does not significantly impact user privacy, as all logging or propagation of opt-out status will go through a privacy-protected logging service: either our Crash database via Inspect, or Cobalt.
We'll integration test the update-settings-storage
component, its interaction with omaha-client
, and the final requests to an Omaha server that omaha-client
produces in various states of opt-out.
We'll integration test the RPMB API via the Verified Execution Trusted Application.
We'll also unit test the implementations in each of the components individually.
Finally, we'll engage with the testing teams to ensure that products which enable this feature have end to end testing of their entire integrations, similar to other update features.
We'll need to add documentation to the new FIDL API, as well as to our OTA flow documentation.
We could implement an update-opt out by pushing a ‘tombstone’ build to devices which indicates that it will no longer update.
This has a notable upside:
This also has some notable downsides:
We could avoid some complexity by storing the opt-out value in minfs, which would allow this feature to be deployed to a greater range of products. However, this makes it trivial for an attacker with privilege escalation to persist their attacks indefinitely if they can gain write access to minfs. Gaining write access to minfs is likely substantially easier than modifying the Verified Execution Trusted Application's state, since the VX TA is much smaller than minfs in terms of surface area, and easier to audit.
If a user is opted out, we could modify omaha-client
to not check for updates at all. This has a couple of drawbacks: we can‘t get Omaha-based metrics on how many users are opted out, and a product owner with sufficient authorization can’t ask devices to take critical updates.
The Omaha protocol includes the updatedisabled
flag for essentially this reason: a client device telling the server that it's checking for an update, but that download and installation should not be performed.
The Chrome browser supports disabling updates via enterprise policy. This may be a use case for potential Fuchsia devices, but we have no enterprise policy requirements at the moment.