JanssenProject / JanssenProject/jans
feat(jans-chip): create sample android/iOS app for using jans-fido for passkey authentication
- Dominant language
- Java
- Stars
- 648
- Forks
- 174
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 110
Description
Create sample Android and iOS applications that demonstrate native passkey (FIDO2/WebAuthn) authentication against the jans-fido2 server, to give developers a working reference for integrating passkeys into their own native apps.
## Goal
Ship two small, runnable sample apps (Android + iOS) that each:
- Register a passkey against a `jans-fido2` server (attestation flow)
- Sign in with that passkey (assertion flow)
- Demonstrate a usernameless / discoverable-credential sign-in
- Handle the platform-specific pitfalls listed below, not just the "happy path"
## Native Passkey Pitfalls to Handle
Per [Corbado's "Native Passkey Challenges: iOS & Android Pitfalls"](https://www.corbado.com/blog/native-ios-android-passkey-implementation-challenges), both sample apps should explicitly handle (not just document) the following:
### Domain association
- [ ] **Android:** use the Play Console **App signing key certificate** SHA-256 fingerprint in `assetlinks.json`, not just the local debug/upload key — call this out prominently since it silently breaks passkeys for 100% of Play Store users if missed
- [ ] **Android:** no wildcard subdomains — document that each subdomain needs its own `assetlinks.json` entry
- [ ] **iOS:** validate the AASA file's Team ID + bundle ID carefully; these fail silently with no error message
- [ ] **iOS:** account for Apple's AASA CDN caching — document the `?mode=developer` bypass for local testing and the requirement to remove it before App Store submission
- [ ] **iOS:** handle the "Application is not associated with this domain" error that ~5% of users hit right after install (AASA not yet verified) with retry logic rather than treating it as fatal
### Platform APIs
- [ ] **Android:** build on Credential Manager (`androidx.credentials`), not the legacy `com.google.android.gms.fido.fido2` API
- [ ] **Android:** proactively check `KeyguardManager.isDeviceSecure` (not `isKeyguardSecure`) before attempting any passkey operation, and prompt the user to set a screen lock if it's false
- [ ] **Android:** account for Play Services/OS fragmentation (Android 14+ native, 9–13 backport, no support at all without Google Play services e.g. Huawei) and known OEM issues (Samsung Pass conflicts, the `TransactionTooLargeException` bug when combining Google Sign-In with passkeys, Xiaomi ROM interference)
- [ ] **iOS:** use Base64URL encoding/decoding consistently for challenge, credential ID, and signature — flag this as the most common silent failure point (standard Base64 corrupts the bytes with no clear error)
- [ ] **iOS:** design around having no control over the system authentication sheet (can't theme or customize it; cancellation returns a generic error)
- [ ] **iOS:** handle iCloud Keychain sync lag gracefully (a passkey created on one Apple device may not be immediately usable on another) with a fallback path rather than a hard failure
### Autofill / Conditional UI
- [ ] Note (and ideally demonstrate) that autofill/Conditional UI is not guaranteed to appear on either platform — third-party password managers can take priority, and on Android the passkey-save and password-save dialogs can compete for the same tap on Android 13 and below
### Platform lock-in
- [ ] Include a fallback (non-passkey) sign-in path in both samples, and a short note that passkeys do not currently transfer between iOS and Android ecosystems (no shipping Credential Exchange Protocol/Format implementation yet)
### Testing
- [ ] Document that emulators/simulators do not reliably reproduce real screen-lock, Play Services version, OEM, or iCloud sync behavior
- [ ] Provide a recommended minimum physical test matrix: Pixel + Samsung + one Android 9–12 device; iPhone with Face ID + iPhone SE with Touch ID
- [ ] Call out that automated UI tests cannot drive the system biometric prompt — that step requires manual QA
Contributor guide
Assessment
This issue has not been assessed yet.