Attestation compatibility guide
Apps using the Play Integrity API or obsolete SafetyNet Attestation API to check the authenticity/integrity of the OS can support GrapheneOS by using the standard Android hardware attestation API instead and permitting our official release signing keys. Android's hardware attestation API provides a much stronger form of attestation than the Play Integrity API with the ability to whitelist the keys of alternate operating systems. It also avoids an unnecessary dependency on Google Play services and Google's Play Integrity servers.
Devices have been required to ship with hardware attestation support since Android 8. You can use hardware attestation on devices running Android 8 or later when the ro.product.first_api_level
system property isn't set to 25 or below, which indicates they launched with Android 8 or later with hardware attestation support as a mandatory feature. On older devices, you can continue using the Play Integrity API. Some low quality devices shipped broken implementations of hardware attestation despite the requirement to have it working for CDD/CTS certification and the Play Integrity API currently still passes on those devices wrongly claiming them to be CTS certified. If you don't want to fail on those devices, then you can start with hardware attestation and fall back to the Play Integrity API or do both and accept either passing as success.
Google provides a key attestation library with examples. Our MIT / Apache 2 licensed Auditor app can be used as a reference implementation for verifying hardware-based attestations. There are some subtleties in the verification process such as making sure only the 2nd certificate in the chain (the one signing the certificate for the key generated by your app) has an attestation extension to prevent making a fake attestation by extending the chain. You can reuse our code and simply omit support for an app generated attestation signing key (attest key) and the other pinning support.
After verifying the signature of the attestation certificate chain and extracting the attestation metadata, you can enforce that verifiedBootState
is either Verified
or SelfSigned
. For the SelfSigned
case, you can check that verifiedBootKey
matches one of the official GrapheneOS verified boot keys. These are the base16-encoded verified boot key fingerprints for the official GrapheneOS releases:
af4d2c6e62be0fec54f0271b9776ff061dd8392d9f51cf6ab1551d346679e24c
: Pixel 9 Pro Fold55d3c2323db91bb91f20d38d015e85112d038f6b6b5738fe352c1a80dba57023
: Pixel 9 Pro XLf729cab861da1b83fdfab402fc9480758f2ae78ee0b61c1f2137dd1ab7076e86
: Pixel 9 Pro9e6a8f3e0d761a780179f93acd5721ba1ab7c8c537c7761073c0a754b0e932de
: Pixel 9096b8bd6d44527a24ac1564b308839f67e78202185cbff9cfdcb10e63250bc5e
: Pixel 8a896db2d09d84e1d6bb747002b8a114950b946e5825772a9d48ba7eb01d118c1c
: Pixel 8 Procd7479653aa88208f9f03034810ef9b7b0af8a9d41e2000e458ac403a2acb233
: Pixel 8ee0c9dfef6f55a878538b0dbf7e78e3bc3f1a13c8c44839b095fe26dd5fe2842
: Pixel Fold94df136e6c6aa08dc26580af46f36419b5f9baf46039db076f5295b91aaff230
: Pixel Tablet508d75dea10c5cbc3e7632260fc0b59f6055a8a49dd84e693b6d8899edbb01e4
: Pixel 7abc1c0dd95664604382bb888412026422742eb333071ea0b2d19036217d49182f
: Pixel 7 Pro3efe5392be3ac38afb894d13de639e521675e62571a8a9b3ef9fc8c44fd17fa1
: Pixel 708c860350a9600692d10c8512f7b8e80707757468e8fbfeea2a870c0a83d6031
: Pixel 6a439b76524d94c40652ce1bf0d8243773c634d2f99ba3160d8d02aa5e29ff925c
: Pixel 6 Prof0a890375d1405e62ebfd87e8d3f475f948ef031bbf9ddd516d5f600a23677e8
: Pixel 60abddeda03b6ce10548c95e0bea196faa539866f929bcdf7eca84b4203952514
: Pixel 5a36a99eab7907e4fb12a70e3c41c456bcbe46c13413fbfe2436adee2b2b61120f
: Pixel 5dcec2d053d3ec4f1c9be414aa07e4d7d7cbd12040ad2f8831c994a83a0536866
: Pixel 4a (5G)9f2454a1657b1b5ad7f2336b39a2611f7a40b2e0ddfd0d6553a359605928df29
: Pixel 4a3f15fdcb82847fed97427ce00563b8f9ff34627070de5fdb17aca7849ab98cc8
: Pixel 4 XL80ef268700ee42686f779a47b4a155fe1ffc2eedf836b4803caab8fa61439746
: Pixel 4
The verifiedBootKey
field is binary data so you either need to encode it as base16 to compare with these or convert these to binary. An easy approach is storing the permitted key fingerprints in a set and enforcing that the verified boot key is in the permitted set when verifiedBootState
is SelfSigned
.
GrapheneOS regularly adds support for new devices so you should have a process for regularly adding the new verified boot key fingerprints from this page.
The hardware attestation API also provides other useful information signed by the hardware including the OS patch level, in a way that even an attacker exploiting the OS after boot to gain root cannot trivially bypass. It's a better feature than the Play Integrity API which has to be designed for the lowest common denominator.
GrapheneOS users are strongly encouraged to share this documentation with app developers enforcing only being able to use the stock OS. Send an email to the developers and leave a review of the app with a link to this information. Share it with other users and create pressure to support GrapheneOS rather than locking users into the stock OS without a valid security reason. GrapheneOS not only upholds the app security model but substantially reinforces it, so it cannot be justified with reasoning based on security, anti-fraud, etc.