Segurança · Android · Fintech
Play Integrity está barrando seus clientes pagantes
A Play Integrity do Google não responde se o aparelho está comprometido. Ela responde uma pergunta mais estreita, e a diferença recusa clientes que você não vê.

Um cliente escreve pro suporte porque o seu app não abre no celular dele. Esse celular tem bootloader travado e um sistema operacional verificado criptograficamente a cada boot — mais rígido, pela maioria das métricas, que metade dos aparelhos que o seu app aceita sem piscar. Ele é recusado do mesmo jeito, porque o seu app perguntou pra Play Integrity API do Google se dava pra confiar naquele aparelho. A Play Integrity não responde essa pergunta. O veredito padrão dela responde uma mais estreita: isto é uma imagem certificada por um fabricante parceiro do Google? São perguntas diferentes, e a diferença entre as duas está recusando gente que quer te pagar.
A história chegou à imprensa no formato de sempre: apps de banco bloqueiam sistemas Android endurecidos, a GrapheneOS reclama, a Revolut é citada. Nesse enquadramento parece assunto de sistema operacional de nicho. Não é. Todo app de fintech, marketplace e carteira digital no Android — aqui incluído praticamente tudo que move Pix — embarca um gate de integridade, quase todos embarcam o mesmo, e ele foi escolhido uma única vez por quem plugou o SDK. Esse gate decide quem tem permissão de ser seu cliente.
O que aqui está verificado e o que não está
Abaixo convivem dois tipos de afirmação, e elas não têm o mesmo peso.
Verificado nos documentos primários em 24 de outubro de 2026: cada citação da referência da Play Integrity e do esquema de atestação do Android Open Source Project, e o arquivo de allowlist assinado — 1.452 bytes, 21 fingerprints de chave, assinatura Ed25519 conferida localmente com ssh-keygen -Y verify.
Informado por parte interessada e sem medição independente: os números de manchete. A GrapheneOS afirma que cerca de 10% dos apps bancários estão indisponíveis para seus usuários e que uns doze bancos passaram a permitir o sistema. Os dois números são do próprio projeto, publicados sem metodologia nem amostra, e a lista colaborativa que ele linka no mesmo post nomeia quatro instituições, não doze. O que a Revolut especificamente checa também é a GrapheneOS lendo um app de código fechado — o site que noticiou não afirma ter verificado as alegações, e a Revolut não se pronunciou. Nada disso toca o mecanismo, que está na documentação do próprio Google. Mas um número que uma parte interessada divulga sobre si mesma deve ser lido como tal.

GrapheneOS, 23 de outubro de 2026. Os dois números são do próprio projeto; nenhum tem medição independente. Fonte: grapheneos.social.
O veredito padrão tem duas saídas, e nenhuma quer dizer "comprometido"
O Google documenta o deviceRecognitionVerdict padrão com exatamente dois valores possíveis. MEETS_DEVICE_INTEGRITY significa que "o app está rodando num dispositivo Android genuíno e certificado", com prova em hardware no Android 13 ou superior de "que o bootloader do dispositivo está travado e que o Android carregado é uma imagem certificada do fabricante". O outro valor é vazio — campo em branco — que o Google documenta como "o app está rodando num dispositivo que apresenta sinais de ataque (como hooking de API) ou de comprometimento do sistema (como estar com root)".
Leia as duas juntas. Um bootloader travado rodando um sistema verificado que não é do Google atende à propriedade de segurança da primeira frase e falha na propriedade de certificação da mesma frase. Logo, cai no segundo balde — ao lado de um aparelho com root e um framework de hooking acoplado. A sua regra antifraude não distingue os dois, porque a API não contou.
E não existe degrau mais baixo que resolva. MEETS_BASIC_INTEGRITY tem cara de nível de degradação elegante, mas o Google o define como um estado em que "o bootloader do dispositivo pode estar travado ou destravado, e o boot pode estar verificado ou não verificado". É mais fraco, não mais estreito: aceitá-lo para admitir aparelhos endurecidos admite também tudo que o gate existe para barrar.
O Google tem uma segunda API de atestação que responde a pergunta certa
A Play Integrity é construída sobre a atestação de chave em hardware do Android, e a primitiva de baixo acaba sendo mais informativa que o produto que está em cima dela. O esquema do AOSP devolve uma estrutura RootOfTrust com quatro campos separados:
RootOfTrust ::= SEQUENCE {
verifiedBootKey OCTET_STRING,
deviceLocked BOOLEAN,
verifiedBootState VerifiedBootState,
verifiedBootHash OCTET_STRING,
}
VerifiedBootState ::= ENUMERATED {
Verified (0),
SelfSigned (1),
Unverified (2),
Failed (3),
}

A mesma empresa, outra API: a RootOfTrust entrega ao app a chave de boot, o estado do bloqueio e um veredito SelfSigned como fatos separados. Fonte: esquema de atestação do Android Open Source Project.
SelfSigned é o degrau que a Play Integrity não sabe expressar: cadeia de boot verificada, sob uma chave de assinatura que não é do fabricante. É distinto de Unverified e de Failed, e chega junto com a chave que assinou — então o app decide em quais chaves não originais confia, em vez de herdar a lista de um fornecedor. Essa API existe desde o Android 8.
| Play Integrity (veredito padrão) | Atestação de chave em hardware | |
|---|---|---|
| Pergunta que responde | É uma imagem certificada por fabricante parceiro do Google? | A cadeia de boot está verificada, e sob qual chave? |
| O que volta | MEETS_DEVICE_INTEGRITY ou valor vazio | verifiedBootKey, deviceLocked, verifiedBootState, verifiedBootHash |
| Travado, verificado, chave não original | Vazio — idêntico a root sob ataque | SelfSigned, mais a chave, como fatos separados |
| Disponível desde | Android 8, via Google Play services | Android 8, em hardware, sem depender do Play |
| Quem define a política | Você |
E o argumento não é só de quem está sendo bloqueado. Uma comparação acadêmica da Johannes Kepler University Linz conclui que a API de atestação em hardware "oferece uma alternativa mais flexível, viabilizando suporte a sistemas operacionais de terceiros ao mesmo tempo que mantém garantias fortes de segurança por meio de armazenamento de chaves em hardware", e que a natureza proprietária da Play Integrity e sua dependência do Google Play Services "levantam preocupações concorrenciais".
O cliente recusado não aparece em nenhum dos seus números
É isso que transforma o assunto num problema de gestão, e não de engenharia. O cliente que o seu gate recusa não gera transação negada: nem pagamento recusado, nem ticket numa categoria que alguém revisa, nem queda num passo de funil que você instrumentou. O app fechou antes de qualquer uma dessas coisas existir.
Então o custo é real e não é medido, que é exatamente a razão pela qual o gate nunca é revisto. Todo outro controle do seu produto tem uma taxa de falso positivo que alguém discute em reunião. A desse é desconhecida, e as pessoas dentro dela são a única coorte que o seu analytics não vê.
Ou seja: ninguém na sua empresa perguntou se vocês deveriam admitir esses usuários. Uma dependência respondeu.
Quanto custa consertar
O guia para desenvolvedores do sistema Android endurecido mais comum resume a checagem em duas frases: exija que verifiedBootState seja Verified ou SelfSigned e, no caso SelfSigned, confira se verifiedBootKey corresponde a uma das chaves de verified boot publicadas.
Baixei essa lista. É um arquivo JSON de 1.452 bytes com 21 fingerprints de chave, cada um uma string hexadecimal de 64 caracteres, com timestamp de 20 de abril de 2026, acompanhado de assinatura OpenSSH e chave de assinante publicada. Verificar é um comando:
ssh-keygen -Y verify -f allowed_signers -I contact@grapheneos.org \
-n 'attestation keys' -s attestation.json.sig < attestation.json
Sai com código 0 e assinatura Ed25519 válida. Rodei em 24 de outubro de 2026.

A integração, em duas frases, tirada do guia do desenvolvedor: checar um enum e casar um hash contra um arquivo assinado de 1,4 KB. Fonte: grapheneos.org.
Sendo honesto sobre o tamanho do trabalho: se o seu app já faz atestação de chave em hardware, admitir esses aparelhos são dois campos que você já recebe hoje. Se ele só chama a Play Integrity, o trabalho é adotar a API que está embaixo da que você já chama — uma sprint de formato conhecido, contra documentação que existe há oito anos. Não é projeto de pesquisa nem impossibilidade, que são as duas coisas que costumam ser alegadas.
Alguns bancos já fizeram
A lista colaborativa de compatibilidade do PrivSec.dev tem 907 entradas únicas de apps. Duas estão anotadas como tendo liberado o sistema endurecido via a API de atestação em hardware — Swissquote e Yuh — e duas como oferecendo suporte oficial: UBS (com UBS key4) e AmeriCU Credit Union.

Lista de compatibilidade mantida pela comunidade, lida em 24 de outubro de 2026: dois bancos anotados como tendo liberado via API de atestação em hardware, um com suporte oficial. Fonte: PrivSec.dev; a GrapheneOS não garante a exatidão da lista.
Trate essas entradas pelo que elas são: relatos de usuários. A própria GrapheneOS, que linka a lista, diz com todas as letras que "não oferece nenhuma garantia quanto à validade da lista", e nenhum banco citado aqui nos informou qual API de atestação usa, nem por quê. O que a lista estabelece não é roadmap de fornecedor. Estabelece que a coisa é entregável, porque alguém entregou.
A mesma lista mede o atrito na direção oposta: 8 entradas em que o app não pode nem ser instalado pelo Google Play por causa da Play Integrity, 4 em que ele só roda se a API for bloqueada, e uma — N26 — em que a Play Integrity bloqueia novos cadastros enquanto contas existentes seguem funcionando. Essa última merece um minuto. É um gate que proíbe aquisição e permite retenção, o oposto de como alguém escreveria essa política de propósito.
A decisão, dita como decisão
Três perguntas, e elas são de quem responde pelo produto, não de quem responde pelo build mobile.
- O que a gente precisa saber sobre um aparelho? Se a resposta é "que a cadeia de boot está íntegra", você está chamando a API errada. Se é "que é uma imagem certificada pelo Google", diga em voz alta — isso é posição comercial, não de segurança.
- Qual é a nossa política de falso positivo? Escolha um número. "Vamos recusar aparelhos endurecidos e aceitar os cadastros perdidos" é defensável. "Nunca olhamos" não é.
- Quem é o dono dessa checagem? Diga um nome. Controle sem dono vai atrás do default do fornecedor, e você descobre quando um cliente te conta.
A gente vê esse formato toda hora em trabalho que chega para virar produção: uma dependência adicionada por um bom motivo, ligada a uma decisão que ninguém escreveu, e depois tratada como resolvida porque compila. Mesma falha de entregar demo como se fosse produto (o problema do Roadster), mesma falha de deixar código gerado definir uma fronteira que ninguém revisou (contendo código escrito por IA). O gate de integridade é um caso caro demais, porque o erro é silencioso e recai justamente sobre os clientes que mais se preocupam em proteger o próprio aparelho.
Pontos principais
- O veredito padrão de dispositivo da Play Integrity tem duas saídas: imagem certificada de fabricante, ou um valor vazio que o Google documenta como sinais de ataque ou comprometimento do sistema.
- Um celular com bootloader travado rodando um sistema verificado que não é do Google recebe o valor vazio — indistinguível de root sob ataque.
- A atestação de chave em hardware, base sobre a qual a Play Integrity é construída, devolve
verifiedBootStatecom um valorSelfSigneddistinto, mais a chave de assinatura, então o app define a própria política. - O cliente recusado não gera transação, ticket nem evento de funil, então o custo do gate nunca chega a um número revisado — e é por isso que ele nunca é revisto.
Perguntas frequentes
A Play Integrity diz ao meu app se o aparelho tem root? Não de forma distinta. O Google agrupa root com outras falhas num único veredito vazio, que também cobre qualquer sistema que não seja imagem certificada de fabricante. Se a sua regra precisa de "com root" especificamente, o veredito padrão não entrega isso.
Aceitar MEETS_BASIC_INTEGRITY é um meio-termo razoável?
Não. O Google define esse nível como permitindo bootloader travado ou destravado e boot verificado ou não verificado. É estritamente mais fraco, então admite justamente o que você queria barrar.
Quantos clientes isso admitiria na prática? Ninguém publica esse número, e é esse o ponto do post. Dá para medir: registre os campos de atestação que você já recebe, conte os aparelhos travados e verificados sob chave não original, e você tem o tamanho da coorte antes de decidir qualquer coisa.