Pular para o conteúdo principal

Attest (atestação de dispositivo)

O SDK de runtime roda no aparelho, então um aparelho totalmente comprometido pode mentir sobre o que reporta. O Attest fecha essa brecha: o app troca o relatório de runtime do SDK — mais uma atestação da plataforma (Play Integrity no Android, App Attest no iOS) — por um token assinado curto. O seu backend verifica esse token antes de uma ação sensível (uma transferência Pix, um login, uma troca de senha).

O Attest está disponível a partir do plano Startup.

Como funciona​

  1. O seu backend gera um nonce para a operação e envia ao app.
  2. O app chama Moatgator.attest(nonce). O SDK junta os achados, pede à plataforma uma atestação presa a esse nonce e troca os dois em POST /v1/attest/token.
  3. A Moatgator verifica a atestação da plataforma no servidor e devolve um token (um JWT EdDSA, válido por 5 minutos, preso ao seu app, à plataforma e ao nonce).
  4. O app envia o token ao seu backend. O seu backend o verifica — offline com o JWKS público, ou com POST /v1/attest/verify.

O veredito é trusted, suspicious ou untrusted, com os motivos e a evidência que o sustentaram (rasp sozinho significa que não houve atestação da plataforma).

Configurar (console)​

Em Console → o seu app → Attest:

  • Play Integrity (Android): cole o JSON da conta de serviço do Google Cloud do seu projeto e o nome do pacote. Fica guardado cifrado e nunca mais é mostrado.
  • App Attest (iOS): informe o Team ID da Apple e o bundle id.
  • Exigir atestação da plataforma: quando ligado, um token só com o relatório de runtime (sem atestação da plataforma) é untrusted.

No app​

val r = Moatgator.attest(nonce = order.nonce, integrity = { challenge -> playIntegrityToken(challenge) })
if (!r.trusted) blockPayment()

O provedor integrity é onde você chama a API do Play Integrity; o SDK não depende da biblioteca do Google. Sem um provedor, o token carrega só o relatório de runtime.

Verificação no backend​

import { createVerifier } from "@moatgator/attest";

const attest = createVerifier({ appId: process.env.MOATGATOR_APP_ID, env: "live" });
const r = await attest.verify(req.header("x-moatgator-attest"), { nonce: order.nonce, platform: "android" });
if (!r.trusted) return res.status(403).json({ error: "device_not_trusted", reasons: r.reasons });

Também há verificadores para Python e Go. Com qualquer biblioteca JOSE: busque /.well-known/jwks.json, aceite só alg: EdDSA e confira typ == "attest", iss, aud (o id do seu app), exp e nonce.

Limites​

  • O nonce é seu: gere um valor novo e imprevisível por operação no backend e confira na volta.
  • O App Attest exige compilar no macOS com Xcode; o atalho Moatgator.attest() está no Android hoje, com o iOS a seguir.
  • A atestação da plataforma vale só o que a plataforma oferece; o relatório de runtime soma sinais do aparelho, mas nenhum sinal sozinho é prova.