949 lines
67 KiB
HTML
949 lines
67 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" prefix="og: https://ogp.me/ns#">
|
|
<head>
|
|
<meta charset="utf-8"/>
|
|
<title>Usage guide | GrapheneOS</title>
|
|
<meta name="description" content="Usage instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
|
<meta name="theme-color" content="#212121"/>
|
|
<meta name="color-scheme" content="dark light"/>
|
|
<meta name="msapplication-TileColor" content="#ffffff"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
<meta name="twitter:site" content="@GrapheneOS"/>
|
|
<meta name="twitter:creator" content="@GrapheneOS"/>
|
|
<meta property="og:title" content="GrapheneOS usage guide"/>
|
|
<meta property="og:description" content="Usage instructions for GrapheneOS, a security and privacy focused mobile OS with Android app compatibility."/>
|
|
<meta property="og:type" content="website"/>
|
|
<meta property="og:image" content="https://grapheneos.org/opengraph.png"/>
|
|
<meta property="og:image:width" content="512"/>
|
|
<meta property="og:image:height" content="512"/>
|
|
<meta property="og:image:alt" content="GrapheneOS logo"/>
|
|
<meta property="og:site_name" content="GrapheneOS"/>
|
|
<meta property="og:url" content="https://grapheneos.org/usage"/>
|
|
<link rel="canonical" href="https://grapheneos.org/usage"/>
|
|
<link rel="icon" href="/favicon.ico"/>
|
|
<link rel="icon" sizes="any" type="image/svg+xml" href="/favicon.svg"/>
|
|
<link rel="mask-icon" href="{{path|/mask-icon.svg}}" color="#1a1a1a"/>
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
|
|
{{css|/main.css}}
|
|
<link rel="manifest" href="/manifest.webmanifest"/>
|
|
<link rel="license" href="/LICENSE.txt"/>
|
|
{{js|/js/redirect.js}}
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<nav id="site-menu">
|
|
<ul>
|
|
<li><a href="/"><img src="{{path|/mask-icon.svg}}" alt=""/>GrapheneOS</a></li>
|
|
<li><a href="/features">Features</a></li>
|
|
<li><a href="/install/">Install</a></li>
|
|
<li><a href="/build">Build</a></li>
|
|
<li aria-current="page"><a href="/usage">Usage</a></li>
|
|
<li><a href="/faq">FAQ</a></li>
|
|
<li><a href="/releases">Releases</a></li>
|
|
<li><a href="/source">Source</a></li>
|
|
<li><a href="/history/">History</a></li>
|
|
<li><a href="/articles/">Articles</a></li>
|
|
<li><a href="/donate">Donate</a></li>
|
|
<li><a href="/contact">Contact</a></li>
|
|
</ul>
|
|
</nav>
|
|
</header>
|
|
<main id="usage">
|
|
<h1><a href="#usage">Usage guide</a></h1>
|
|
<p>This is a guide covering some aspects of using GrapheneOS. See the
|
|
<a href="/features">features page</a> for a list of GrapheneOS features.</p>
|
|
|
|
<nav id="table-of-contents">
|
|
<h2><a href="#table-of-contents">Table of contents</a></h2>
|
|
<ul>
|
|
<li>
|
|
<a href="#system-navigation">System navigation</a>
|
|
<ul>
|
|
<li><a href="#gesture-navigation">Gesture navigation</a></li>
|
|
<li><a href="#2-button-navigation">2-button navigation</a></li>
|
|
<li><a href="#3-button-navigation">3-button navigation</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#accessibility">Accessibility</a></li>
|
|
<li><a href="#auditor">Auditor</a></li>
|
|
<li>
|
|
<a href="#updates">Updates</a>
|
|
<ul>
|
|
<li><a href="#updates-settings">Settings</a></li>
|
|
<li><a href="#updates-security">Security</a></li>
|
|
<li><a href="#updates-disabling">Disabling</a></li>
|
|
<li><a href="#updates-sideloading">Sideloading</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#web-browsing">Web browsing</a></li>
|
|
<li>
|
|
<a href="#camera">Camera</a>
|
|
<ul>
|
|
<li><a href="#grapheneos-camera-app">GrapheneOS Camera app</a></li>
|
|
<li><a href="#google-camera">Google Camera</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#exec-spawning">Exec spawning</a></li>
|
|
<li><a href="#bugs-uncovered-by-security-features">Bugs uncovered by security features</a></li>
|
|
<li>
|
|
<a href="#wifi-privacy">Wi-Fi privacy</a>
|
|
<ul>
|
|
<li><a href="#wifi-privacy-scanning">Scanning</a></li>
|
|
<li><a href="#wifi-privacy-associated">Associated with an Access Point (AP)</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#lte-only-mode">LTE-only mode</a></li>
|
|
<li>
|
|
<a href="#sandboxed-play-services">Sandboxed Play services</a>
|
|
<ul>
|
|
<li><a href="#sandboxed-play-services-installation">Installation</a></li>
|
|
<li><a href="#sandboxed-play-services-limitations">Limitations</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="#banking-apps">Banking apps</a></li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<section id="system-navigation">
|
|
<h2><a href="#system-navigation">System navigation</a></h2>
|
|
|
|
<p>By default, GrapheneOS uses gesture-based navigation. We recommend reading our
|
|
guide on gesture navigation and giving it a chance even if you think you won't
|
|
like it. Our experience is that when armed with the appropriate knowledge, the
|
|
vast majority of users prefer the newer gesture navigation approach.</p>
|
|
|
|
<p>The system navigation mode can be configured in Settings → System → Gestures →
|
|
System navigation. The same menu is also available in Settings → Accessibility →
|
|
System navigation.</p>
|
|
|
|
<section id="gesture-navigation">
|
|
<h3><a href="#gesture-navigation">Gesture navigation</a></h3>
|
|
|
|
<p>The bottom of the screen is a reserved touch zone for system navigation. A
|
|
line is displayed in the center to show that the navigation bar is present
|
|
across the entire bottom of the screen. In most apps, this area will display
|
|
padding. Modern apps are able to tell the OS that they can handle not having
|
|
the padding to display app content there while still not being able to receive
|
|
touches from it. Open up the Settings app for an example.</p>
|
|
|
|
<p>Swiping up from the navigation bar while removing your finger from the
|
|
screen is the <strong>Home</strong> gesture.</p>
|
|
|
|
<p>Swiping up from the navigation bar while holding your finger on the screen
|
|
before releasing is the <strong>Recent Apps</strong> gesture. The most
|
|
recently opened activity is always on the furthest right. Each step left goes
|
|
one step back through the history of recently opened apps. Opening an app with
|
|
the recent apps activity will place it on the furthest right in the recent
|
|
apps order just like a new app being opened.</p>
|
|
|
|
<p>The recent apps activity has a screenshot button as an alternative to
|
|
holding power and volume down while using an app.</p>
|
|
|
|
<p>Rather than opening the recent apps activity, you can swipe left on the
|
|
navigation bar for the <strong>Previous</strong> app and swipe right for the
|
|
<strong>Next</strong> app. This will not change the recent apps order. This is
|
|
usually the best way to navigate through recent apps.</p>
|
|
|
|
<p>Swiping from either the left or the right of the screen within the app (not
|
|
the navigation bar) is the <strong>Back</strong> gesture. Apps are supposed to
|
|
avoid implementing conflicting gestures, but have the option to override this
|
|
gesture if they truly need to get rid of it. However, many apps without active
|
|
development of their UI design still haven't addressed this despite gestures
|
|
being the default for 2 years on Google Android. You can avoid triggering the
|
|
back gesture in one of 2 easy ways: avoid swiping from right near the edge or
|
|
hold your finger on the side of the screen for a moment before swiping. The
|
|
more advanced option is using a diagonal swipe pointing sharply to the bottom
|
|
of the screen since this will bypass the back gesture but will still trigger
|
|
most app gestures. The advanced option is the most convenient approach once
|
|
you get used to doing it.</p>
|
|
|
|
<p>The launcher uses a swipe up gesture starting anywhere on the screen to
|
|
open the app drawer from the home screen. You need to start that gesture above
|
|
the system navigation bar since any gesture starting on the navigation bar is
|
|
handled by the OS as a system navigation gesture.</p>
|
|
</section>
|
|
|
|
<section id="2-button-navigation">
|
|
<h3><a href="#2-button-navigation">2-button navigation</a></h3>
|
|
|
|
<p>2-button navigation is a legacy mode not supported anymore by Google
|
|
Android on the Pixel 4 and later. It will likely be removed in a future
|
|
release of GrapheneOS. You should use <a href="#3-button-navigation">3-button
|
|
navigation</a> if you want the traditional button-based navigation.</p>
|
|
|
|
<p>A large row across the bottom of the screen is reserved for navigation
|
|
buttons. The <strong>Back</strong> button is on the left and the
|
|
<strong>Home</strong> button is in the center.</p>
|
|
|
|
<p>Swiping up from the navigation bar while removing your finger from the
|
|
screen is the <strong>Recent apps</strong> gesture. The most recently opened
|
|
activity is always on the furthest right. Each step left goes one step back
|
|
through the history of recently opened apps. Opening an app with the recent
|
|
apps activity will place it on the furthest right in the recent apps
|
|
order just like a new app being opened.</p>
|
|
|
|
<p>2-button navigation provides the recent apps activity with the launcher. It
|
|
shows the recent apps above the bottom row of the home screen and the search
|
|
integration not used in GrapheneOS. The usual launcher features work including
|
|
swiping up anywhere on the screen to open the app drawer. Due to the launcher
|
|
integration, the screenshot button available in the other modes isn't present.
|
|
Instead, a screenshot button is added to the global action menu accessed by
|
|
holding the power button.</p>
|
|
</section>
|
|
|
|
<section id="3-button-navigation">
|
|
<h3><a href="#3-button-navigation">3-button navigation</a></h3>
|
|
|
|
<p>3-button navigation is Android's oldest touchscreen-based navigation
|
|
system. It will remain supported for the foreseeable future to provide
|
|
accessibility for users unable to easily use the gestures. It's older than
|
|
2-button navigation but isn't considered a legacy feature.</p>
|
|
|
|
<p>A large row across the bottom of the screen is reserved for navigation
|
|
buttons. The <strong>Back</strong> button is on the left, the
|
|
<strong>Home</strong> button is in the center and the <strong>Recent
|
|
Apps</strong> button is on the right.</p>
|
|
|
|
<p>In the recent apps activity, the most recently opened activity is always on
|
|
the furthest right. Each step left goes one step back through the history of
|
|
recently opened apps. Opening an app with the recent apps activity will place
|
|
it on the furthest right in the recent apps order just like a new app being
|
|
opened.</p>
|
|
|
|
<p>The recent apps activity has a screenshot button as an alternative to
|
|
holding power and volume down while using an app.</p>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="accessibility">
|
|
<h2><a href="#accessibility">Accessibility</a></h2>
|
|
|
|
<p>GrapheneOS includes all of the accessibility features from the Android Open
|
|
Source Project and strives to fill in the gaps from not including Google apps and
|
|
services. We include our own fork of the open source TalkBack accessibility
|
|
service along with a Monochromacy option for the standard color correction
|
|
menu.</p>
|
|
|
|
<p>GrapheneOS does not yet include a text-to-speech (TTS) service in the base OS
|
|
due to limitations of the available options. Including one is planned in the
|
|
future when a suitable option is available. RHVoice and eSpeak NG are both open
|
|
source and are the most common choices by GrapheneOS users. Both of these mostly
|
|
work fine but have licensing issues and don't support Direct Boot so they cannot
|
|
be used before the initial unlock of the device. Installing and setting up either
|
|
one of these or another TTS app will get TalkBack working. TalkBack itself
|
|
supports Direct Boot and works before the first unlock but it needs to have a TTS
|
|
app supporting it in order to do more than playing the activation sound before the
|
|
first unlock. After installing a TTS service, you need to select it in the OS
|
|
configuration to accept activating it. The OS will display one of them as already
|
|
selected, but it won't simply work from being installed as that wouldn't be safe.
|
|
This is the same as the stock OS but it comes with one set up already.</p>
|
|
|
|
<p>GrapheneOS disables showing the characters as passwords are typed by default.
|
|
You can enable this in Settings ➔ Privacy.</p>
|
|
|
|
<p>Third party accessibility services can be installed and activated. This
|
|
includes the ones made by Google. Most of these will work but some may have a hard
|
|
dependency on functionality from Google Play services for some of their
|
|
functionality or to run at all. Accessibility services are very powerful and we
|
|
strongly recommend against using third party implementations if you can get by
|
|
well without them. We plan to add safeguards in this area while still keeping them
|
|
working without problematic barriers.</p>
|
|
</section>
|
|
|
|
<section id="auditor">
|
|
<h2><a href="#auditor">Auditor</a></h2>
|
|
<p>See the <a href="https://attestation.app/tutorial">tutorial page on the site for the attestation sub-project</a>.</p>
|
|
</section>
|
|
|
|
<section id="updates">
|
|
<h2><a href="#updates">Updates</a></h2>
|
|
|
|
<p>The update system implements automatic background updates. It checks for updates
|
|
approximately once every four hours when there's network connectivity and then
|
|
downloads and installs updates in the background. It will pick up where it left off if
|
|
downloads are interrupted, so you don't need to worry about interrupting it.
|
|
Similarly, interrupting the installation isn't a risk because updates are installed to
|
|
a secondary installation of GrapheneOS which only becomes the active installation
|
|
after the update is complete. Once the update is complete, you'll be informed with a
|
|
notification and simply need to reboot with the button in the notification or via a
|
|
normal reboot. If the new version fails to boot, the OS will be rolled back to the
|
|
past version and the updater will attempt to download and install the update
|
|
again.</p>
|
|
|
|
<p>The updater will use incremental (delta) updates to download only changes rather
|
|
than the whole OS when one is available to go directly from the installed version to
|
|
the latest version. As long as you have working network connectivity on a regular
|
|
basis and reboot when asked, you'll almost always be on one of the past couple
|
|
versions of the OS which will minimize bandwidth usage since incrementals will always
|
|
be available.</p>
|
|
|
|
<p>The updater works while the device is locked / idle, including before the first
|
|
unlock since it's explicitly designed to be able to run before decryption of user
|
|
data.</p>
|
|
|
|
<p>Release changelogs are available <a href="/releases#changelog">in a section on the releases page</a>.</p>
|
|
|
|
<section id="updates-settings">
|
|
<h3><a href="#updates-settings">Settings</a></h3>
|
|
|
|
<p>The settings are available in the Settings app in System ➔ Advanced ➔ Update
|
|
settings.</p>
|
|
|
|
<p>The "Check for updates" option will manually trigger an update check as soon as
|
|
possible. It will still wait for the configuration conditions listed below to be
|
|
satisfied, such as being connected to the internet via one of the permitted network
|
|
types.</p>
|
|
|
|
<p>The "Release channel" setting can be changed from the default Stable channel to the
|
|
Beta channel if you want to help with testing. The Beta channel will usually simply
|
|
follow the Stable channel, but the Beta channel may be used to experiment with new
|
|
features.</p>
|
|
|
|
<p>The "Permitted networks" setting controls which networks will be used to perform
|
|
updates. It defaults to using any network connection. It can be set to "Non-roaming"
|
|
to disable it when the cellular service is marked as roaming or "Unmetered" to disable
|
|
it on cellular networks and also Wi-Fi networks marked as metered.</p>
|
|
|
|
<p>The "Require battery above warning level" setting controls whether updates will
|
|
only be performed when the battery is above the level where the warning message is
|
|
shown. The standard value is at 15% capacity.</p>
|
|
|
|
<p>Enabling the opt-in "Automatic reboot" setting allows the updater to reboot the
|
|
device after an update once it has been idle for a long time. When this setting is
|
|
enabled, a device can take care of any number of updates completely automatically even
|
|
if it's left completely idle.</p>
|
|
</section>
|
|
|
|
<section id="updates-security">
|
|
<h3><a href="#updates-security">Security</a></h3>
|
|
|
|
<p>The update server isn't a trusted party since updates are signed and verified along
|
|
with downgrade attacks being prevented. The update protocol doesn't send identifiable
|
|
information to the update server and works well over a VPN / Tor. GrapheneOS isn't
|
|
able to comply with a government order to build, sign and ship a malicious update to a
|
|
specific user's device based on information like the IMEI, serial number, etc. The
|
|
update server only ends up knowing the IP address used to connect to it and the
|
|
version being upgraded from based on the requested incremental.</p>
|
|
|
|
<p>Android updates can support serialno constraints to make them validate only on a
|
|
certain device but GrapheneOS rejects any update with a serialno constraint for both
|
|
over-the-air updates (Updater app) and sideloaded updates (recovery).</p>
|
|
</section>
|
|
|
|
<section id="updates-disabling">
|
|
<h3><a href="#updates-disabling">Disabling</a></h3>
|
|
|
|
<p>It's highly recommended to leave automatic updates enabled and to configure the
|
|
permitted networks if the bandwidth usage is a problem on your mobile data connection.
|
|
However, it's possible to turn off the update client by going to Settings ➔ Apps,
|
|
enabling Show system via the menu, selecting System Updater and disabling the
|
|
app. If you do this, you'll need to remember to enable it again to start receiving
|
|
updates.</p>
|
|
</section>
|
|
|
|
<section id="updates-sideloading">
|
|
<h3><a href="#updates-sideloading">Sideloading</a></h3>
|
|
|
|
<p>Updates can be downloaded via
|
|
<a href="https://grapheneos.org/releases">the releases page</a> and installed via recovery
|
|
with adb sideloading. The zip files are signed and verified by recovery, just as they
|
|
are by the update client within the OS. This includes providing downgrade protection,
|
|
which prevents attempting to downgrade the version. If recovery didn't enforce these
|
|
things, they would still be enforced via verified boot including downgrade protection
|
|
and the attempted update would just fail to boot and be rolled back.</p>
|
|
|
|
<p>To install one by sideloading, first, boot into recovery. You may do this either by
|
|
using <code>adb reboot recovery</code> from the operating system, or by selecting the
|
|
"Recovery" option in the bootloader interface.</p>
|
|
|
|
<p>You should see the green Android lying on its back being repaired, with the text "No
|
|
command" meaning that no command has been passed to recovery.</p>
|
|
|
|
<p>Next, access the recovery menu by holding down the power button and pressing the volume
|
|
up button a single time. This key combination toggles between the GUI and text-based mode
|
|
with the menu and log output.</p>
|
|
|
|
<p>Finally, select the "Apply update from ADB" option in the recovery menu and
|
|
sideload the update with adb. For example:</p>
|
|
|
|
<pre>adb sideload blueline-ota_update-2019.07.01.21.zip</pre>
|
|
|
|
<p><strong>You do not need to have adb enabled within the OS or the host's ADB key
|
|
whitelisted within the OS to sideload an update to recovery. Recovery mode does not
|
|
trust the attached computer and this can be considered a production feature. Trusting
|
|
a computer with ADB access within the OS is much different and exposes the device to a
|
|
huge amount of attack surface and control by the trusted computer.</strong></p>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="usb-peripherals">
|
|
<h2><a href="#usb-peripherals">USB peripherals</a></h2>
|
|
|
|
<p>GrapheneOS defaults to ignoring connected USB peripherals when the device is
|
|
already booted and the screen is locked. A USB device already connected at boot
|
|
will still work. The purpose is reducing attack surface for a locked device with
|
|
active login sessions to user profiles to protect data that's not at rest. This
|
|
can be controlled in Settings ➔ Security ➔ USB accessories. The options are:</p>
|
|
|
|
<ul>
|
|
<li>Disallow new USB peripherals</li>
|
|
<li>Allow new USB peripherals when unlocked (default)</li>
|
|
<li>Allow new USB peripherals (like stock Android)</li>
|
|
</ul>
|
|
|
|
<p>This option has no impact on the device acting as a USB peripheral itself when
|
|
connected to a computer. Android defaults to charge only mode and requires opt-in
|
|
to the device being used for file transfer, USB tethering, MIDI or PTP.</p>
|
|
</section>
|
|
|
|
<section id="web-browsing">
|
|
<h2><a href="#web-browsing">Web browsing</a></h2>
|
|
|
|
<p>GrapheneOS includes a Vanadium subproject providing privacy and security enhanced
|
|
releases of Chromium. Vanadium is both the user-facing browser included in the OS and
|
|
the provider of the WebView used by other apps to render web content. The WebView is
|
|
the browser engine used by the vast majority of web browsers and nearly all other apps
|
|
embedding web content or using web technologies for other uses.</p>
|
|
|
|
<p>Using Vanadium is highly recommended. Bromite is a solid alternative and is the
|
|
only other browser we recommend. Bromite provides integrated ad-blocking and more
|
|
advanced anti-fingerprinting. For now, Vanadium is more focused on security hardening
|
|
and Bromite is more focused on anti-fingerprinting. The projects are collaborating
|
|
together and will likely converge to providing more of the same features. Vanadium
|
|
will be providing content filtering and anti-fingerprinting, but it needs to be done
|
|
in a way that meets the standards of the project, which takes time.</p>
|
|
|
|
<p>Vanadium is designed for use on GrapheneOS and does not duplicate the OS privacy
|
|
and security features such as the hardened malloc implementation. This leads to some
|
|
of the differences from Bromite, such as relying on OS support for encrypted DNS
|
|
rather than enabling Chromium's DNS-over-HTTPS support.</p>
|
|
|
|
<p>Chromium-based browsers like Vanadium and Bromite provide the strongest sandbox
|
|
implementation, leagues ahead of the alternatives. It is much harder to escape from
|
|
the sandbox and it provides much more than acting as a barrier to compromising the
|
|
rest of the OS. Site isolation enforces security boundaries around each site using the
|
|
sandbox by placing each site into an isolated sandbox. It required a huge overhaul of
|
|
the browser since it has to enforce these rules on all the IPC APIs. Site isolation is
|
|
important even without a compromise, due to side channels. Browsers without site
|
|
isolation are very vulnerable to attacks like Spectre. On mobile, due to the lack of
|
|
memory available to apps, there are different modes for site isolation. Vanadium turns
|
|
on strict site isolation, matching Chromium on the desktop. Bromite enables strict
|
|
site isolation on high memory devices, including all the devices that are officially
|
|
supported by GrapheneOS.</p>
|
|
|
|
<p>Chromium has decent exploit mitigations, unlike the available alternatives. This is
|
|
improved upon in Vanadium by enabling further mitigations, including those developed
|
|
upstream but not yet fully enabled due to code size, memory usage or performance. For
|
|
example, it enables type-based CFI like Chromium on the desktop, uses a stronger SSP
|
|
configuration, zero initializes variables by default, etc. Some of the mitigations are
|
|
inherited from the OS itself, which also applies to other browsers, at least if they
|
|
don't do things to break them.</p>
|
|
|
|
<p>We recommend against trying to achieve browser privacy and security through piling
|
|
on browser extensions and modifications. Most privacy features for browsers are
|
|
privacy theater without a clear threat model and these features often reduce privacy
|
|
by aiding fingerprinting and adding more state shared between sites. Every change you
|
|
make results in you standing out from the crowd and generally provides more ways to
|
|
track you. Enumerating badness via content filtering is not a viable approach to
|
|
achieving decent privacy, just as AntiVirus isn't a viable way to achieving decent
|
|
security. These are losing battles, and are at best a stopgap reducing exposure while
|
|
waiting for real privacy and security features.</p>
|
|
|
|
<p>Vanadium will be following the school of thought where hiding the IP address
|
|
through Tor or a trusted VPN shared between many users is the essential baseline, with
|
|
the browser partitioning state based on site and mitigating fingerprinting to avoid
|
|
that being trivially bypassed. The Tor Browser's approach is the only one with any
|
|
real potential, however flawed the current implementation may be. This work is
|
|
currently in a very early stage and it is largely being implemented upstream with the
|
|
strongest available implementation of state partitioning. Chromium is using Network
|
|
Isolation Keys to divide up connection pools, caches and other state based on site and
|
|
this will be the foundation for privacy. Chromium itself aims to prevent tracking
|
|
through mechanisms other than cookies, greatly narrowing the scope downstream work
|
|
needs to cover. Bromite is doing a lot of work in these areas and Vanadium will be
|
|
benefiting from that along with this upstream work. The focus is currently on research
|
|
since we don't see much benefit in deploying bits and pieces of this before everything
|
|
is ready to come together. At the moment, the only browser with any semblance of
|
|
privacy is the Tor Browser but there are many ways to bypass the anti-fingerprinting
|
|
and state partitioning. The Tor Browser's security is weak which makes the privacy
|
|
protection weak. The need to avoid diversity (fingerprinting) creates a monoculture
|
|
for the most interesting targets. This needs to change, especially since Tor itself
|
|
makes people into much more of a target (both locally and by the exit nodes).</p>
|
|
|
|
<p>WebView-based browsers use the hardened Vanadium rendering engine, but they can't
|
|
offer as much privacy and control due to being limited to the capabilities supported
|
|
by the WebView widget. For example, they can't provide a setting for toggling sensors
|
|
access because the feature is fairly new and the WebView WebSettings API doesn't yet
|
|
include support for it as it does for JavaScript, location, cookies, DOM storage and
|
|
other older features. For sensors, the Sensors app permission added by GrapheneOS can
|
|
be toggled off for the browser app as a whole instead. The WebView sandbox also
|
|
currently runs every instance within the same sandbox and doesn't support site
|
|
isolation.</p>
|
|
|
|
<p>Avoid Gecko-based browsers like Firefox as they're currently much more vulnerable
|
|
to exploitation and inherently add a huge amount of attack surface. Gecko doesn't have
|
|
a WebView implementation (GeckoView is not a WebView implementation), so it has to be
|
|
used alongside the Chromium-based WebView rather than instead of Chromium, which means
|
|
having the remote attack surface of two separate browser engines instead of only one.
|
|
Firefox / Gecko also bypass or cripple a fair bit of the upstream and GrapheneOS
|
|
hardening work for apps. Worst of all, Firefox runs as a single process on mobile and
|
|
has no sandbox beyond the OS sandbox. This is despite the fact that Chromium semantic
|
|
sandbox layer on Android is implemented via the OS <code>isolatedProcess</code>
|
|
feature, which is a very easy to use boolean property for app service processes to
|
|
provide strong isolation with only the ability to communicate with the app running
|
|
them via the standard service API. Even in the desktop version, Firefox's sandbox is
|
|
still substantially weaker (especially on Linux, where it can hardly be considered a
|
|
sandbox at all) and lacks support for isolating sites from each other rather than only
|
|
containing content as a whole.</p>
|
|
</section>
|
|
|
|
<section id="camera">
|
|
<h2><a href="#camera">Camera</a></h2>
|
|
|
|
<p>GrapheneOS has the same camera capabilities and quality as the stock OS. It
|
|
will match the stock OS when comparing the same app on each OS. GrapheneOS uses
|
|
our own modern Camera app rather than the standard AOSP Camera app. GrapheneOS
|
|
Camera is far better than any of the portable open source camera alternatives and
|
|
even most proprietary camera apps including paid apps. On Pixels, Google Camera
|
|
can be used as an alternative with more features. The section below has a detailed
|
|
guide on using GrapheneOS Camera and the following section explains the remaining
|
|
advantages of Google Camera on Pixels.</p>
|
|
|
|
<section id="grapheneos-camera-app">
|
|
<h3><a href="#grapheneos-camera-app">GrapheneOS Camera app</a></h3>
|
|
|
|
<p>GrapheneOS includes our own modern Camera app based on the bleeding edge
|
|
release channel of Android's CameraX library. It provides modes for QR
|
|
scanning, image capture and video recording as tabs at the bottom of the
|
|
screen. You can either use the tab interface or swipe left and right anywhere
|
|
on the screen above it to switch between them. The arrow button at the top of
|
|
the screen opens the settings panel and you can close it by pressing anywhere
|
|
outside the settings panel. You can also swipe down to open the settings and
|
|
swipe up to close it. Outside of the QR scanning mode, there's a row of large
|
|
buttons above the tab bar for switching between the cameras (left), capturing
|
|
images and starting/stopping video recording (middle) and opening the gallery
|
|
(right). The volume keys can also be used as an equivalent to pressing the
|
|
capture button. While recording a video, the gallery button becomes an image
|
|
capture button for capturing images.</p>
|
|
|
|
<p>Our Camera app provides the system media intents used by other apps to
|
|
capture images / record videos via the OS provided camera implementation.
|
|
These intents can only be provided by a system app since Android 11, so the
|
|
quality of the system camera is quite important.</p>
|
|
|
|
<p>The in-app gallery / video player doesn't yet support zooming and depends
|
|
on opening an external image/video editor. This will be improved in the
|
|
future. We'll eventually be making our own gallery/editor app sharing a lot of
|
|
the code with the in-app gallery in the camera.</p>
|
|
|
|
<p>Using the default 4:3 aspect ratio for image capture is recommended since
|
|
16:9 is simply cropped output on all supported devices. A device oriented
|
|
towards video recording might actually have a wider image sensor but that's
|
|
not the case for Pixels or nearly any other smartphone.</p>
|
|
|
|
<p>Image capture uses lightweight HDR+ on all supported Pixels and HDRnet for the
|
|
preview on 5th generation Pixels. Using the torch or camera flash will result
|
|
in HDR+ being disabled which is why automatic flash isn't enabled by default.
|
|
The lightweight HDR+ doesn't use as many frames as the more aggressive Google
|
|
Camera HDR+. CameraX extensions will eventually provide support for an HDR
|
|
mode with more aggressive HDR+ taking/combining more than only around 3 frames
|
|
along with a Night mode providing the Night Sight variant of HDR+ inflating
|
|
the light of the scene through combining the frames. Other fancy features like
|
|
Portrait mode will also depend on CameraX extensions being provided in the
|
|
future. There isn't a timeline for this but an initial implementation will
|
|
likely be shipped within the next year for Pixels.</p>
|
|
|
|
<p>Zooming via pinch to zoom or the zoom slider will automatically make use of
|
|
the wide angle and telephoto cameras on Pixels. 5th and 6th generation Pixels
|
|
(4a (5G), 5, 5a, 6, 6 Pro) have a wide angle camera for zooming out to under
|
|
1x to capture a much wider field of view. Images taken with the wide angle
|
|
lens won't match the quality of the normal camera, especially with 6th
|
|
generation Pixels. Flagship 4th generation Pixels (4, 4 XL) have a telephoto
|
|
camera providing 2x optical zoom and the Pixel 6 Pro has one providing 4x
|
|
optical zoom.</p>
|
|
|
|
<p>By default, continuous auto focus, auto exposure and auto white balance are
|
|
used across the whole scene. Tapping to focus will switch to auto focus, auto
|
|
exposure and auto white balance based on that location. The focus timeout
|
|
setting determines the timeout before it switches back the default mode. The
|
|
exposure compensation slider on the left allows manually tuning exposure and
|
|
will automatically adjust shutter speed, aperture and ISO without disrupting
|
|
lightweight HDR+ support. Further configuration / tuning over the algorithms
|
|
will be provided in the future. Direct manual control doesn't make much sense
|
|
with the modern camera stack and isn't planned.</p>
|
|
|
|
<p>CameraX only recently gained official support for video recording in
|
|
October 2021 and there are still some quirks. The preview can sometimes end up
|
|
misaligned but the recorded videos won't be impacted. 16:9 is currently the
|
|
only supported video aspect ratio. 1080p (FHD) is the default but 2160p (UHD)
|
|
is supported. CameraX UHD support may be buggy on some devices.</p>
|
|
|
|
<p>The QR scanning mode only scans within the scanning square marked on the
|
|
screen. The QR code should be aligned with the edges of the square but can
|
|
have any 90 degree orientation. Non-standard inverted QR codes are fully
|
|
supported. It's a very quick and high quality QR scanner able to easily scan
|
|
very high density QR codes from Pixels. Every 2 seconds, it will refresh auto
|
|
focus, auto exposure and auto white balance on the scanning square. It has
|
|
full support for zooming in and out. Support for other kinds of barcodes will
|
|
be added in the future, but adding them transparently would result in getting
|
|
false positives and would substantially harm the QR scanning capability. It
|
|
will need to be done in a way offering more control without having an overly
|
|
complex user interface.</p>
|
|
|
|
<p>Camera permission is the only one that's required. Images and videos are
|
|
stored via the Media Store API so media/storage permissions aren't required.
|
|
The Microphone permission is needed for video recording by default but not
|
|
when including audio is disabled. Location permission is only needed if you
|
|
explicitly enabling location tagging, which is an experimental feature.</p>
|
|
|
|
<p>Captured images currently include an EXIF timestamp, the phone model and an
|
|
abstraction of the exposure configuration. This will become fully optional in
|
|
the future and will likely be opt-in rather than opt-out. EXIF orientation
|
|
data is crucial for setting the proper orientation of the image. Videos have
|
|
their own similar metadata.</p>
|
|
</section>
|
|
|
|
<section id="google-camera">
|
|
<h3><a href="#google-camera">Google Camera</a></h3>
|
|
|
|
<p>Google Camera can be used with the <a href="#sandboxed-play-services">sandboxed
|
|
Play services compatibility layer</a> and can take full advantage of the
|
|
available cameras and image processing hardware as it can on the stock OS.</p>
|
|
|
|
<p>We aim to reduce the benefits of Google Camera compared to GrapheneOS
|
|
Camera over time, especially on Pixels. Many features of Google Camera will
|
|
end up being available for GrapheneOS Camera in the next year or so via
|
|
CameraX extensions including more aggressive HDR+, Night Sight and Portrait.
|
|
Video features such as Electronic Image Stabilization (EIS), slow motion and
|
|
time lapse are likely further away than within the next year. These video
|
|
features could potentially be provided via CameraX vendor extensions or could
|
|
be implemented via our own post-processing of the video output. Panorama,
|
|
Photo Sphere, Astrophotography, Motion Photos, Frequent Faces, Dual Exposure
|
|
Controls, Google Lens, etc. aren't on the roadmap for GrapheneOS Camera. Video
|
|
refresh rate configuration and H.265 support should be available for
|
|
GrapheneOS Camera in the near future via CameraX improvements along with DNG
|
|
(RAW) support in the further future.</p>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="exec-spawning">
|
|
<h2><a href="#exec-spawning">Exec spawning</a></h2>
|
|
|
|
<p>GrapheneOS creates fresh processes (via exec) when spawning applications instead of
|
|
using the traditional Zygote spawning model. This improves privacy and security at the
|
|
expense of higher cold start app spawning time and higher initial memory usage. It
|
|
doesn't impact runtime performance beyond the initial spawning time. It adds somewhere
|
|
in the ballpark of 100ms to app spawning time on the flagship devices and is only very
|
|
noticeable on lower-end devices with a weaker CPU and slower storage. The spawning
|
|
time impact only applies when the app doesn't already have an app process and the OS
|
|
will try to keep app processes cached in the background until memory pressure forces
|
|
it to start killing them.</p>
|
|
|
|
<p>In the typical Zygote model, a template app process is created during boot and
|
|
every app is spawned as a clone of it. This results in every app sharing the same
|
|
initial memory content and layout, including sharing secrets that are meant to be
|
|
randomized for each process. It saves time by reusing the initialization work. The
|
|
initial memory usage is reduced due to copy-on-write semantics resulting in memory
|
|
written only during initialization being shared between app processes.</p>
|
|
|
|
<p>The Zygote model weakens the security provided by features based on random secrets
|
|
including Address Space Layout Randomization (ASLR), stack canaries, heap canaries,
|
|
randomized heap layout and memory tags. It cripples these security features since
|
|
every app has the values for every other app and the values don't change for fresh app
|
|
processes until reboot. Much of the OS itself is implemented via non-user-facing apps
|
|
with privileges reserved for OS components. The Zygote template is reused across user
|
|
profiles, so it also provides a temporary set of device identifiers across profiles
|
|
for each boot via the shared randomized values.</p>
|
|
</section>
|
|
|
|
<section id="bugs-uncovered-by-security-features">
|
|
<h2><a href="#bugs-uncovered-by-security-features">Bugs uncovered by security features</a></h2>
|
|
|
|
<p>GrapheneOS substantially expands the standard mitigations for memory corruption
|
|
vulnerabilities. Some of these features are designed to directly catch the memory
|
|
corruption bugs either via an explicit check or memory protection and abort the
|
|
program in order to prevent them from being exploited. Other features mitigate issues
|
|
a bit less directly such as zeroing data immediately upon free, isolated memory
|
|
regions, heap randomization, etc. and can also lead to latent memory corruption bugs
|
|
crashing instead of the program continuing onwards with corrupted memory. This means
|
|
that many latent memory corruption bugs in apps are caught along with some in the OS
|
|
itself. These bugs are not caused by GrapheneOS, but rather already existed and are
|
|
uncovered by the features. The features are aimed at preventing or hindering exploits,
|
|
not finding bugs, but they do that as part of doing their actual job.</p>
|
|
|
|
<p>Similarly, some of the other privacy and security improvements reduce the access
|
|
available to applications and they may crash. Some of these features are always
|
|
enabled under the hood, while others like the Network and Sensors toggles are
|
|
controlled by users via opt-in or opt-out toggles. Apps may not handle having access
|
|
taken away like this, although it generally doesn't cause any issues as it's all
|
|
designed to be friendly to apps and fully compatible rather than killing the
|
|
application when it violates the rules.</p>
|
|
|
|
<p>If you run into an application aborting, try to come up with a process for
|
|
reproducing the issue and then capture a bug report via the 'Take bug report'
|
|
feature in Developer options. Report an issue to <a
|
|
href="https://github.com/GrapheneOS/os-issue-tracker/issues">the GrapheneOS OS
|
|
issue tracker</a> and email the bug report capture zip to contact@grapheneos.org
|
|
with the issue tracker number in the subject like "Bug report capture for issue
|
|
#104". The bug report capture includes plain text 'tombstones' with logs,
|
|
tracebacks, address space layout, register content and a tiny bit of context
|
|
from memory from areas that are interesting for debugging. This may contain
|
|
some sensitive data. Feel free to provide only the tombstone for the relevant
|
|
crash and filter out information you don't want to send. However, it will be
|
|
more difficult to debug if you provide less of the information. If the app
|
|
doesn't work with sensitive information, just send the whole tombstone.</p>
|
|
</section>
|
|
|
|
<section id="wifi-privacy">
|
|
<h2><a href="#wifi-privacy">Wi-Fi privacy</a></h2>
|
|
|
|
<p>Wi-Fi on GrapheneOS is very privacy-friendly and is essentially anonymous as long
|
|
as apps do not leak uniquely identifying information to the network. GrapheneOS avoids
|
|
allowing itself to be fingerprinted as GrapheneOS, other than connections which are
|
|
documented (see the FAQ) and can be easily disabled or forced through a VPN
|
|
service.</p>
|
|
|
|
<section id="wifi-privacy-scanning">
|
|
<h3><a href="#wifi-privacy-scanning">Scanning</a></h3>
|
|
|
|
<p>MAC randomization is always performed for Wi-Fi scanning. Pixel
|
|
phones have firmware support for scanning MAC randomization going
|
|
<a href="https://android-developers.googleblog.com/2017/04/changes-to-device-identifiers-in.html">significantly beyond a naive implementation</a>.
|
|
On many other devices, there are identifiers exposed by Wi-Fi scanning beyond the MAC
|
|
address such as the packet sequence number and assorted identifying information in the
|
|
probe requests.</p>
|
|
|
|
<p>Avoid using hidden APs (i.e. APs not broadcasting their SSID) since all
|
|
known hidden SSIDs end up being broadcast as part of scanning for networks to
|
|
find them again. SSIDs are not broadcast for standard non-hidden APs. Hidden
|
|
APs are only hidden when no devices are connected. It makes little sense as a
|
|
privacy feature, especially for a non-mobile AP where knowing the AP exists
|
|
can't be used for tracking it since it doesn't move. The feature reduces your
|
|
privacy rather than increasing it. If you need to use a hidden AP, make sure
|
|
to delete the saved network afterwards.</p>
|
|
|
|
<p>Wi-Fi and Bluetooth scanning for improving location detection are disabled by
|
|
default, unlike the stock OS. These can be toggled in Settings ➔ Location ➔ Wi-Fi and
|
|
Bluetooth scanning. These features enable scanning even when Wi-Fi or Bluetooth is
|
|
disabled, so these need to be kept disabled to fully disable the radios when Wi-Fi and
|
|
Bluetooth are disabled. GrapheneOS doesn't yet have an implementation of a coarse
|
|
location service to supplement GPS location, so enabling these options doesn't
|
|
actually do anything at the moment. Implementing a supplementary location service is
|
|
planned but we need a robust, secure and private implementation via a local database.
|
|
The initial focus will likely be a cell phone tower database, so these features still
|
|
wouldn't be relevant.</p>
|
|
</section>
|
|
|
|
<section id="wifi-privacy-associated">
|
|
<h3><a href="#wifi-privacy-associated">Associated with an Access Point (AP)</a></h3>
|
|
|
|
<p>Associated MAC randomization is performed by default. This can be controlled
|
|
per-network with Settings ➔ Network & Internet ➔ Wi-Fi ➔ <network> ➔
|
|
Advanced ➔ Privacy.</p>
|
|
|
|
<p>In the stock OS, the default is to use a unique persistent random MAC address for
|
|
each network. It has 2 options available: "Use randomized MAC (default)" and "Use
|
|
device MAC". In GrapheneOS, the default is generating a new random MAC address when
|
|
connecting to a network. It has 3 options available: "Use per-connection randomized MAC
|
|
(default)", "Use per-network randomized MAC" and "Use device MAC".</p>
|
|
|
|
<p>The DHCP client uses the anonymity profile rather than sending a hostname
|
|
so it doesn't compromise the privacy offered by MAC randomization. When the
|
|
per-connection MAC randomization added by GrapheneOS is being used, DHCP
|
|
client state is flushed before reconnecting to a network to avoid revealing
|
|
that it's likely the same device as before.</p>
|
|
|
|
<p>GrapheneOS also disables support for stable link-local IPv6 addresses, since these
|
|
have the potential to be used as identifiers. It's more sensible to use typical
|
|
link-local address generation based on the (randomized) MAC address since link-local
|
|
devices have access to both. As of Android 11, Android only uses stable link-local
|
|
privacy addresses when MAC randomization is disabled, so we no longer need to disable
|
|
the feature.</p>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="lte-only-mode">
|
|
<h2><a href="#lte-only-mode">LTE-only mode</a></h2>
|
|
|
|
<p>If you have a reliable LTE connection from your carrier, you can reduce attack
|
|
surface by disabling 2G, 3G and 5G connectivity in Settings ➔ Network & Internet ➔
|
|
Mobile network ➔ Preferred network type. Traditional voice calls will only work in
|
|
the LTE-only mode if you have either an LTE connection and VoLTE (Voice over LTE)
|
|
support or a Wi-Fi connection and VoWi-Fi (Voice over Wi-Fi) support. VoLTE /
|
|
VoWi-Fi works on GrapheneOS for most carriers unless they restrict it to carrier
|
|
phones. US carriers other than T-Mobile tend to be missing these features due to
|
|
us not including their proprietary apps.</p>
|
|
|
|
<p>This feature is not intended to improve the confidentiality of traditional calls and
|
|
texts, but it might somewhat raise the bar for some forms of interception. It's not a
|
|
substitute for end-to-end encrypted calls / texts or even transport layer encryption.
|
|
LTE does provide basic network authentication / encryption, but it's for the network
|
|
itself. The intention of the LTE-only feature is only hardening against remote
|
|
exploitation by disabling an enormous amount of legacy code.</p>
|
|
</section>
|
|
|
|
<section id="sandboxed-play-services">
|
|
<h2><a href="#sandboxed-play-services">Sandboxed Play services</a></h2>
|
|
|
|
<p>GrapheneOS has a compatibility layer providing the option to install and use
|
|
the official releases of Play services in the standard app sandbox. Play services
|
|
receives absolutely no special access or privileges on GrapheneOS as opposed to
|
|
bypassing the app sandbox and receiving a massive amount of highly privileged
|
|
access. Instead, the compatibility layer teaches it how to work within the full
|
|
app sandbox. It also isn't used as a backend for the OS services as it would be
|
|
elsewhere since GrapheneOS doesn't use Play services even when it's installed.</p>
|
|
|
|
<p>Since the Play services apps are simply regular apps on GrapheneOS, you install
|
|
them within a specific user or work profile and they're only available within that
|
|
profile. Only apps within the same profile can use it and they need to explicitly
|
|
choose to use it. It works the same way as any other app and has no special
|
|
capabilities. As with any other app, it can't access data of other apps and
|
|
requires explicit user consent to gain access to profile data or the standard
|
|
permissions. Apps within the same profile can communicate with mutual consent and
|
|
it's no different for sandboxed Play services.</p>
|
|
|
|
<p>The core functionality and APIs are almost entirely supported already since
|
|
GrapheneOS largely only has to coerce these apps into continuing to run without
|
|
being able to use any of the usual invasive OS integration. A compatibility layer
|
|
is also provided to support dynamically downloaded/loaded modules (dynamite
|
|
modules). The compatibility layer will be gradually expanded and improved in order
|
|
to get more of the Play services functionality working.</p>
|
|
|
|
<section id="sandboxed-play-services-installation">
|
|
<h3><a href="#sandboxed-play-services-installation">Installation</a></h3>
|
|
|
|
<p>Play services is divided up into 3 separate apps: Google Services Framework
|
|
(com.google.android.gsf), Google Play services (com.google.android.gms) and
|
|
Google Play Store (com.android.vending). To use sandboxed Play services, you
|
|
simply need to install the official releases of these 3 apps in the user and
|
|
work profiles where you want to use it.</p>
|
|
|
|
<p>The simplest approach is to only use the Owner user profile. Apps installed
|
|
in the Owner profile are sandboxed the same way as everywhere else and don't
|
|
receive any special access. If you want to choose which apps use Play services
|
|
rather than making it available to all of them, install it in a separate user
|
|
or work profile for apps depending on Play services. You could also do it the
|
|
other way around, but it makes more sense to try to use as much as possible
|
|
without Play services rather than treating not using it as the exceptional
|
|
case.</p>
|
|
|
|
<p>Install com.google.android.gsf, then com.google.android.gms and finally use
|
|
a split APK installer to install all 5 of the APKs for com.android.vending
|
|
together. Make sure to install all 3 in the correct order and don't skip
|
|
installing the Play Store since it provides services used by apps depending on
|
|
Play. You can obtain a split APK installer app from either Aurora Store,
|
|
F-Droid or the developers of the app via their GitHub releases, etc.</p>
|
|
|
|
<p>In the future, we'll have a client app for our repository so you'll be able
|
|
to install and update the official Play services apps through that app and you
|
|
won't need to deal with split APK installation manually.</p>
|
|
|
|
<ul>
|
|
<li><a href="https://apps.grapheneos.org/packages/com.google.android.gsf/">com.google.android.gsf</a></li>
|
|
<li><a href="https://apps.grapheneos.org/packages/com.google.android.gms/">com.google.android.gms</a></li>
|
|
<li><a href="https://apps.grapheneos.org/packages/com.android.vending/">com.android.vending</a></li>
|
|
</ul>
|
|
|
|
<p>You should give a battery optimization exception to Google Play services
|
|
for features like push notifications to work properly in the background. It
|
|
isn't needed for the other 2 apps.</p>
|
|
|
|
<p>After installing the apps, you should open the Play Store and press sign in
|
|
to trigger initialization. Signing into an account is optional and it will
|
|
work fine without it, but you do need to get it initialized and this is
|
|
currently the best way to mimic the initialization done by the stock OS setup
|
|
wizard.</p>
|
|
|
|
<p>You can obtain updates to these apps from our repository which will be easy
|
|
once we have a client app. The Play Store app can also be used to update
|
|
Google Play services. Updates to the Google Services Framework
|
|
(com.google.android.gsf) app are normally only distributed through OS updates
|
|
so you need to get those from our repository. The Play Store app isn't able to
|
|
update itself through the compatibility layer yet but it may be supported in
|
|
the future.</p>
|
|
</section>
|
|
|
|
<section id="sandboxed-play-services-limitations">
|
|
<h3><a href="#sandboxed-play-services-limitations">Limitations</a></h3>
|
|
|
|
<p>Functionality depending on privileged access such as special access to
|
|
hardware isn't available. We would need to implement compatibility layers
|
|
teaching it how to function as a regular app. This currently isn't within the
|
|
scope of the project beyond the existing support for dynamite modules and
|
|
partially implemented support for Play Store app installation/updates. The
|
|
official Android Auto interface is a good example of functionality heavily
|
|
depending on having highly invasive privileged access beyond what would be
|
|
realistic to get working with an expanded compatibility layer.</p>
|
|
|
|
<p>The Play Store app is designed to use privileged permissions for unattended
|
|
app installation, updates and removal which isn't possible on GrapheneOS since
|
|
it's not a privileged app. GrapheneOS provides a dedicated compatibility layer
|
|
for Play Store app installation teaching it to use the standard unprivileged
|
|
approach. It prompts the user to permit it as an app source and then prompts
|
|
for each app install/update. The Play Store currently doesn't get the result
|
|
for the install succeeding or failing so it will think the installation is
|
|
still in progress. You can work around this by force stopping the Play Store
|
|
after installing an app and then opening it again to install other apps.</p>
|
|
|
|
<p>Play Store feature delivery isn't currently supported, but this isn't
|
|
broadly used by current generation apps aside from large games.</p>
|
|
|
|
<p>Since there's no OS integration beyond fallback code to make it function
|
|
without any special privileges, there isn't a way to launch the Play services
|
|
settings activity. We'll need to make a tiny app providing a way to launch
|
|
it.</p>
|
|
</section>
|
|
</section>
|
|
|
|
<section id="banking-apps">
|
|
<h2><a href="#banking-apps">Banking apps</a></h2>
|
|
|
|
<p>Banking apps are a particularly problematic class of apps for compatibility
|
|
with alternate operating systems. Some of these work fine with any GrapheneOS
|
|
configuration but most of them have extensive dependencies on Play services. For
|
|
many of these apps, it's enough to set up the GrapheneOS sandboxed Play services
|
|
feature in the same profile. Unfortunately, there are further complications not
|
|
generally encountered with non-financial apps.</p>
|
|
|
|
<p>Many of these apps have their own crude anti-tampering mechanisms trying to
|
|
prevent inspecting or modifying the app in a weak attempt to hide their code and
|
|
API from security researchers. GrapheneOS allows users to disable native code
|
|
debugging via a toggle in Settings ➔ Security to improve the app sandbox and this
|
|
can interfere with apps debugging their own code to add a barrier to analyzing the
|
|
app. You should try enabling this again if you've disabled it and are encountering
|
|
compatibility issues with these kinds of apps.</p>
|
|
|
|
<p>Banking apps are increasingly using Google's SafetyNet attestation service to
|
|
check the integrity and certification status of the operating system. GrapheneOS
|
|
passes the <code>basicIntegrity</code> check but isn't certified by Google so it
|
|
fails the <code>ctsProfileMatch</code> check. Most apps currently only enforce
|
|
weak software-based attestation which can be bypassed by spoofing what it checks.
|
|
GrapheneOS doesn't attempt to bypass the checks since it would be very fragile and
|
|
would repeatedly break as the checks are improved. Devices launched with Android 8
|
|
or later have hardware attestation support which cannot be bypassed without leaked
|
|
keys or serious vulnerabilities so the era of being able to bypass these checks by
|
|
spoofing results is coming to an end regardless.</p>
|
|
|
|
<p>The hardware attestation feature is part of the Android Open Source Project and
|
|
is fully supported by GrapheneOS. SafetyNet attestation chooses to use it to
|
|
enforce using Google certified operating systems. However, app developers can use
|
|
it directly and permit other properly signed operating systems upholding the
|
|
security model. GrapheneOS has a
|
|
<a href="https://grapheneos.org/articles/attestation-compatibility-guide">a
|
|
detailed guide</a> for app developers on how to support GrapheneOS with the
|
|
hardware attestation API. Direct use of the hardware attestation API provides much
|
|
higher assurance than using SafetyNet so these apps have nothing to lose by using a
|
|
more meaningful API and supporting a more secure OS.</p>
|
|
</section>
|
|
</main>
|
|
<footer>
|
|
<a href="/"><img src="{{path|/mask-icon.svg}}" width="512" height="512" alt=""/>GrapheneOS</a>
|
|
<ul id="social">
|
|
<li><a href="https://twitter.com/GrapheneOS">Twitter</a></li>
|
|
<li><a href="https://github.com/GrapheneOS">GitHub</a></li>
|
|
<li><a href="https://reddit.com/r/GrapheneOS">Reddit</a></li>
|
|
<li><a href="https://www.linkedin.com/company/grapheneos/">LinkedIn</a></li>
|
|
</ul>
|
|
</footer>
|
|
</body>
|
|
</html>
|