Skip to content

Android: native Capacitor bridge to CredentialManager for passkeys#30

Merged
HiLleywyn merged 1 commit into
mainfrom
claude/investigate-android-issue-RTlYp
May 9, 2026
Merged

Android: native Capacitor bridge to CredentialManager for passkeys#30
HiLleywyn merged 1 commit into
mainfrom
claude/investigate-android-issue-RTlYp

Conversation

@HiLleywyn
Copy link
Copy Markdown
Owner

Android System WebView does not back WebAuthn even though it exposes
navigator.credentials, so the existing JS path fails inside the
Capacitor wrapper and the user lands on the "Passkeys aren't available
in this webview" error. Add a tempest-passkey-bridge Capacitor plugin
that wraps androidx.credentials.CredentialManager.createCredential and
getCredential, and route the web-side ceremony through it whenever
Capacitor.isNativePlatform() is true. Browsers and the desktop shell
keep using navigator.credentials.

Render /.well-known/assetlinks.json on tempest-web at container start
from ANDROID_PACKAGE_NAME and ANDROID_ASSETLINKS_SHA256, so the RP
origin can authorize the Android app for passkey requests. The Android
workflow now prints the signing cert SHA-256 from each assembled APK
so the value can be pasted into the env. RAILWAY.md documents the env
vars; scripts/android-cert-sha.sh extracts the SHA from any APK or
keystore locally.

iOS does not need a native bridge because WKWebView ships WebAuthn
from iOS 16; the iOS plugin is a stub that reports unavailable so the
JS path stays in charge.

Anchor /android/ and /ios/ in apps/mobile/.gitignore so the
auto-scaffolded Capacitor projects stay ignored but the plugin source
under apps/mobile/plugins/passkey-bridge/{android,ios}/ is tracked.

Android System WebView does not back WebAuthn even though it exposes
navigator.credentials, so the existing JS path fails inside the
Capacitor wrapper and the user lands on the "Passkeys aren't available
in this webview" error. Add a tempest-passkey-bridge Capacitor plugin
that wraps androidx.credentials.CredentialManager.createCredential and
getCredential, and route the web-side ceremony through it whenever
Capacitor.isNativePlatform() is true. Browsers and the desktop shell
keep using navigator.credentials.

Render /.well-known/assetlinks.json on tempest-web at container start
from ANDROID_PACKAGE_NAME and ANDROID_ASSETLINKS_SHA256, so the RP
origin can authorize the Android app for passkey requests. The Android
workflow now prints the signing cert SHA-256 from each assembled APK
so the value can be pasted into the env. RAILWAY.md documents the env
vars; scripts/android-cert-sha.sh extracts the SHA from any APK or
keystore locally.

iOS does not need a native bridge because WKWebView ships WebAuthn
from iOS 16; the iOS plugin is a stub that reports unavailable so the
JS path stays in charge.

Anchor /android/ and /ios/ in apps/mobile/.gitignore so the
auto-scaffolded Capacitor projects stay ignored but the plugin source
under apps/mobile/plugins/passkey-bridge/{android,ios}/ is tracked.
@HiLleywyn HiLleywyn merged commit b640663 into main May 9, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants