DefGuard / DefGuard/defguard

Implement full Android integrity check

Open
#2,986 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
2.8k
Forks
115
Avg merge
1d 4h
Merged PRs (30d)
51

Description

## Summary

Android device integrity posture check implementation is deferred because the correct implementation is more complex than estimated. Full integrity verification requires Google Play Integrity integration, backend-issued challenges, server-side token verification, and posture protocol changes across the mobile client, proxy, and core.

https://developer.android.com/google/play/integrity/overview

## Background

Android device integrity should be implemented with the Google Play Integrity API.

**Expected flow:**
1. Backend creates a fresh, single-use nonce/challenge for a posture/MFA attempt.
2. Mobile client requests a Play Integrity token from Google Play services using that nonce.
3. Google Play services perform device/app integrity checks and returns an integrity token to the app.
4. Mobile client includes the returned token in posture data sent to proxy/core.
5. Backend verifies the token with Google Play Integrity API.
6. Backend validates:
- nonce matches the issued challenge
- nonce is fresh and single-use
- token timestamp is fresh
- package name matches the defguard mobile app
- signing certificate digest matches the expected app signing key
- device verdict meets policy, e.g. `MEETS_DEVICE_INTEGRITY`
7. Backend derives the final `device_integrity` posture result from the verified Play Integrity verdict.
The integrity result is only trustworthy after backend-side token verification.

## Required Changes

### Protocol / Data Model
- Extend the posture proto/data model with an Android-specific Play Integrity token field.
- Suggested field:
```proto
StringCheck android_play_integrity_token = ;
- Add a new RPC/API for issuing Android Play Integrity challenges/nonces.
- The challenge response should include a fresh nonce generated by the backend.
- The nonce must be bound to the posture/MFA attempt context, e.g. device pubkey, location ID, and expiry.
- The nonce must be single-use or otherwise replay-resistant.
- Mobile client should request this challenge before collecting Android posture data and performing the MFA start request.

### Mobile Client
- Add Google Play Integrity SDK/plugin integration for Android.
- Request a backend-issued nonce before collecting Android posture data and MFA start request.
- Call Play Integrity with the nonce.
- Include the returned token in the new posture field, e.g. android_play_integrity_token.

### Proxy / Core
- Add challenge/nonce generation gprc for Android integrity checks.
- Store or validate nonce freshness and single-use semantics.
- Accept the new play_integrity_token posture field.
- Verify the token server-side using Google Play Integrity API.
- What if core has no internet access (enclave deployment scenario)?
- Validate package name, signing certificate digest, timestamp, nonce, and verdict labels.
- Add configuration for:
- Google API credentials
- Those would probably have to be configured by the admin? How do we work around the issue:
The credentials/API access are tied to the Google Play Console app / Google Cloud project that owns or is linked to the app whose integrity is being verified. Ordinary self-hosted Defguard customers generally cannot obtain credentials to verify the official Defguard app’s Play Integrity tokens themselves, unless Defguard grants them access through Google Cloud/Play Console, which would be a serious operational/security problem.
- expected Android package name
- expected app signing certificate digest
- required integrity level, initially likely MEETS_DEVICE_INTEGRITY

## Acceptance Criteria
- Android posture data can carry a Play Integrity token.
- Backend verifies the token with Google before treating device integrity as passed.
- device_integrity cannot be satisfied by a client-reported boolean alone on Android.
- Non-Android behavior remains unchanged.
- Existing posture/MFA flows continue to work when no Android integrity policy is required.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.