Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions play-services-droidguard/REMOTE_DROIDGUARD_SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Remote DroidGuard Setup for Play Integrity

This covers the minimal client-side configuration to use microG's remote
DroidGuard path (which this PR enables for request-backed flows).

## 1) When this matters

The `guardWithRequest` path is called when Play Integrity (or other
attestation services) sends a `DroidGuardResultsRequest`. Without this PR,
any app hitting this path gets `NotImplementedError`.

With this PR, the path is wired through the existing handle lifecycle:
`initWithRequest → snapshot → onResult → close`.

## 2) Client setup

1. Open microG Settings → DroidGuard → Remote
2. Set the Remote URL to your DroidGuard server endpoint
3. Save; microG will use remote mode for attestation

## 3) Required server endpoint

The remote endpoint receives:

- `GET`/`POST` at the configured URL
- Query params: `flow`, `source`, plus `x-request-*` from the request bundle
- POST body: URL-encoded key/value payload

It must return a Base64-encoded byte array (URL-safe, no padding).

## 4) Quick validation

1. Set a 30-second test timer
2. Trigger a Play Integrity check from a test app (e.g., Dott sign-in)
3. Confirm the remote server receives the request
4. Confirm the attestation flow completes without `NotImplementedError`

No AIDL changes. No new session APIs. Uses existing infrastructure.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,23 @@ class DroidGuardServiceImpl(private val service: DroidGuardChimeraService, priva

override fun guardWithRequest(callbacks: IDroidGuardCallbacks?, flow: String?, map: MutableMap<Any?, Any?>?, request: DroidGuardResultsRequest?) {
Log.d(TAG, "guardWithRequest()")
TODO("Not yet implemented")
val handle = getHandle()
try {
val reply = handle.initWithRequest(flow, request)
if (reply == null) {
handle.init(flow)
}
callbacks?.onResult(handle.snapshot(map ?: mutableMapOf()))
} catch (e: Exception) {
Log.w(TAG, "Error during guardWithRequest", e)
callbacks?.onResult(byteArrayOf())
} finally {
try {
handle.close()
} catch (e: Exception) {
Log.w(TAG, "Error during handle close", e)
}
}
}

override fun getHandle(): IDroidGuardHandle {
Expand Down