JanssenProject / JanssenProject/jans
feat(jans-fido2): structured native-app (iOS/Android) origin & RP-ID policy model
- Dominant language
- Java
- Stars
- 648
- Forks
- 174
- Avg merge
- 1d 18h
- Merged PRs (30d)
- 110
Description
**Is your feature request related to a problem? Please describe.**
The FIDO2 RP configuration is browser-only. `Fido2Configuration.requestedParties` is a flat list of `RequestedParty` objects, each just an `id` plus a `List origins` (`model/src/main/java/io/jans/fido2/model/conf/RequestedParty.java`). Native-app origins (Android `android:apk-key-hash:…`, iOS RP-ID-scoped) get mixed into the same flat `origins[]` as web origins, and there is **no structured place** to record the platform-specific facts that native passkeys require: Android package name + SHA-256 signing fingerprint (upload key vs. Play App Signing key), or iOS Team ID + Bundle ID. Origin acceptance today is a plain string-equality check against `RequestedParty.getOrigins()` (`CommonVerifiers.verifyRpDomain`, `CommonVerifiers.java:104-107`) with a registrable-suffix rule in `DomainVerifier.verifyDomain` (`DomainVerifier.java:74-77`). When a native origin isn't configured correctly, the result is a generic `INVALID_ORIGIN` / `INVALID_DOMAIN` failure with no explanation of *why* — one of the most common and hardest-to-diagnose native deployment errors.
**Describe the solution you'd like**
Introduce an explicit, structured RP origin-policy model (as part of the RP refactoring) that separates web, Android, and iOS applications under a single RP ID, e.g.:
```jsonc
{
"rpId": "example.com",
"webOrigins": ["https://login.example.com"],
"androidApps": [
{ "packageName": "com.example.app",
"sha256CertFingerprints": ["AB:CD:…"],
"distribution": "play-store" } // play-store | self-signed
],
"iosApps": [
{ "teamId": "T9A667JL6T", "bundleId": "com.example.app" }
]
}
```
- This single source of truth is what the `assetlinks.json` / AASA generation builds on, and what the readiness checker validates deployed files against.
- Add **origin-decision diagnostics** explaining why an origin was accepted or rejected, rather than only a generic error. Keep the public FIDO response envelope unchanged.
**Describe alternatives you've considered**
- *Keep the flat `origins[]` and just document native origin formats* — rejected: no place for fingerprints/Team IDs, and the file-generation and readiness-checker work have no source of truth to generate/validate from.
- *A standalone feature separate from RP refactoring* — rejected; this belongs inside the RP refactoring so there's one RP model, not two.
**Additional context**
Foundation for the `assetlinks.json` / AASA generation and the readiness checker, and for the Admin UI work that splits the RP config screen into Web / Android / iOS sections. This should fold into the upcoming RP-refactoring effort rather than being a standalone feature.
Corbado article — https://www.corbado.com/blog/native-ios-android-passkey-implementation-challenges ;
ChatGPT analysis — https://chatgpt.com/share/6a5129bc-a8f4-83ea-8649-3e463e0a7db3
Contributor guide
Assessment
This issue has not been assessed yet.