Skip to content

android: prompt for my.yubico.com link association#2190

Open
thomasbuilds wants to merge 1 commit into
Yubico:mainfrom
thomasbuilds:android-domain-association-prompt
Open

android: prompt for my.yubico.com link association#2190
thomasbuilds wants to merge 1 commit into
Yubico:mainfrom
thomasbuilds:android-domain-association-prompt

Conversation

@thomasbuilds
Copy link
Copy Markdown

@thomasbuilds thomasbuilds commented May 7, 2026

Attemps to fix #2189

Background

On Android 16 (API 36), NFC taps on a YubiKey no longer fire NDEF_DISCOVERED. The tag's NDEF record is treated as a regular https://my.yubico.com/... URL and dispatched via ACTION_VIEW. The app's manifest already declares an autoVerify intent filter for that host, but unless my.yubico.com is associated with the app (via Digital Asset Links auto-verification, or the user enabling it under Settings → Apps → Yubico Authenticator → Open by default), ACTION_VIEW falls through to a browser and the launch-on-tap setting silently does nothing.

Android 12–15 are unaffected: NDEF_DISCOVERED is still delivered there regardless of domain verification state.

Approach

Use DomainVerificationManager (API 31+) to query whether my.yubico.com is associated with the app, and show a dialog with a direct link to the system "Open by default" settings page when it isn't.

The status check covers both conditions that allow ACTION_VIEW to be routed to the app:

  1. hostToStateMap[my.yubico.com] must be DOMAIN_STATE_VERIFIED or DOMAIN_STATE_SELECTED.
  2. userState.isLinkHandlingAllowed must be true — if the user disabled "Open supported links" globally for the app, ACTION_VIEW won't be routed here even when the host is individually verified or selected.

If either condition fails the prompt is shown.

Note on "one tap" UX: Android has no public API to programmatically grant per-domain link approval. Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS is the deepest available deep link — it lands directly on the per-app "Open by default" page where the user can enable "Open supported links" and verify my.yubico.com in two taps rather than navigating through system settings manually.

The prompt is shown at two points:

  • When the user selects a launch tap action (NfcTapAction.launch / NfcTapAction.launchAndCopy) in NFC settings.
  • At startup, once per app build (tracked in SharedPreferences), when a launch action is already configured. Users are reminded after install/update but not on every launch.

Changes

Kotlin / Android

  • New DomainVerificationHelper — guards on API 36, checks isLinkHandlingAllowed before hostToStateMap, swallows runtime exceptions to behave gracefully on quirky OEM builds.
  • MainActivity.AppMethodChannel exposes getDomainVerificationStatus and openDomainVerificationSettings on the existing app.methods channel.

Dart / Flutter

  • app_methods.dart — typed DomainVerificationStatus enum + channel bindings.
  • domain_association_prompt.dart — promptDomainAssociation() (settings change) and maybePromptDomainAssociationOnStartup() (startup). Uses the shared BasicDialog widget.
  • init.dart — invokes the startup variant in a post-frame callback when a launch action is configured.
  • settings_page.dart — invokes the on-change variant when the user selects launch or launchAndCopy.

Localization

  • app_en.arb — adds s_link_my_yubico and p_link_my_yubico_desc. Reuses existing s_open_settings. check_strings.py passes.

Compatibility

  • minSdk = 24, compileSdk = 37. The prompt is entirely suppressed below API 36 (STATUS_UNSUPPORTED). DomainVerificationManager calls are guarded on API 31 as required by the SDK, but the outer API-36 gate makes them unreachable on older releases.
  • The legacy NDEF_DISCOVERED intent filter and AliasNdefActivity are unchanged — Android ≤15 behavior is unaffected.
  • No new permissions.

@thomasbuilds thomasbuilds force-pushed the android-domain-association-prompt branch from 1b1a643 to daa0a72 Compare May 7, 2026 10:23
@thomasbuilds thomasbuilds marked this pull request as ready for review May 7, 2026 10:24
@AdamVe
Copy link
Copy Markdown
Member

AdamVe commented May 7, 2026

Thanks for the contribution, @thomasbuilds! I like the idea a lot. I'm on other tasks right now so review may take a while, but I'll get to it as soon as I can.

@AdamVe
Copy link
Copy Markdown
Member

AdamVe commented May 7, 2026

Please run pre-commit run --all-files to identify the pre-commit issues. Usually this will update formatting of files.

@thomasbuilds
Copy link
Copy Markdown
Author

thomasbuilds commented May 7, 2026

ubuntu apt repos have been down for nearly 1 week so I can't even install the package!!
will try to fix it manually

@thomasbuilds thomasbuilds force-pushed the android-domain-association-prompt branch from 6930dc5 to daa0a72 Compare May 7, 2026 11:38
@AdamVe
Copy link
Copy Markdown
Member

AdamVe commented May 7, 2026

No problem! When I start working with the PR I will make sure the precommit passes. Thanks for trying!

On Android 16 (API 36), NFC taps on a YubiKey no longer broadcast
NDEF_DISCOVERED but launch https://my.yubico.com via ACTION_VIEW.
Without an association between the app and that domain, the tap falls
through to a browser and the launch action silently does nothing.

Use DomainVerificationManager to detect the association state and show
a dialog that deep-links to the system 'Open by default' settings page
when the domain is not associated. Two entry points:

  - When the user picks a launch action in NFC tap settings.
  - At startup, once per app build, when a launch action is already
    configured. The prompted build is tracked in SharedPreferences so
    the dialog is not shown on every launch.

The status check accounts for the app-level isLinkHandlingAllowed flag
in addition to per-host state, so users who disabled 'Open supported
links' globally see the prompt even when my.yubico.com is technically
verified or selected in hostToStateMap.

The prompt is suppressed below API 36: NDEF_DISCOVERED is still
delivered on Android 12-15, so the domain association state is
irrelevant there.

Fixes Yubico#2189
@thomasbuilds thomasbuilds force-pushed the android-domain-association-prompt branch from daa0a72 to 3278343 Compare May 14, 2026 11:24
@thomasbuilds
Copy link
Copy Markdown
Author

I ran the pre-commit

@thomasbuilds
Copy link
Copy Markdown
Author

thomasbuilds commented May 14, 2026

Can you verify that also on regular Android phones the deep link isn't enabled automatically when installing app on playstore?
If it is, then this is only a GrapheneOS issue and this PR should be closed?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Show domain association prompt automatically when NFC launch is enabled on Android 16

2 participants