ZITADEL Docs
Integrate & AuthenticateOIDC & OAuth Flows

Native app links for passkeys

Native mobile apps that create or use passkeys with platform WebAuthn APIs need the issuer domain to publish OS trust association files. ZITADEL serves those files from your instance based on iOS and Android settings on OIDC applications.

Prerequisites

  • An OIDC Native application in your project
  • Passkeys enabled in your login policy
  • A stable issuer / custom domain (passkeys are domain-bound)
  • Platform association configured in the mobile app project (Associated Domains on iOS; Digital Asset Links / App Links on Android)

Configure the OIDC application

Set association fields on each Native OIDC app that should participate in passkey trust.

You can do this in the Console under the app's Native App Links section, or via the Application API / Management API OIDC app create and update endpoints (ios / android).

iOS

FieldDescription
Team IDApple Developer Team ID (exactly 10 alphanumeric characters), for example ABCDE12345
Bundle IDApp bundle identifier (CFBundleIdentifier), for example com.example.app — do not include the Team ID prefix

ZITADEL publishes these as a single App ID in the association file: {team_id}.{bundle_id}.

Android

FieldDescription
Package nameAndroid applicationId / package name from the app manifest
SHA-256 certificate fingerprintsSigning certificate fingerprints (64 hex characters, optionally colon-separated). Include debug and release fingerprints as needed.

Update semantics

On update:

  • Omit a field group to leave it unchanged
  • Send an empty message / empty values to clear
  • Send populated values to replace

Well-known endpoints

ZITADEL aggregates association data from active OIDC apps on the instance and serves:

PathPurpose
${CUSTOM_DOMAIN}/.well-known/apple-app-site-associationiOS Associated Domains / webcredentials
${CUSTOM_DOMAIN}/.well-known/assetlinks.jsonAndroid Digital Asset Links for delegate_permission/common.handle_all_urls and delegate_permission/common.get_login_creds

If no apps are configured, both endpoints still return HTTP 200 with empty collections.

Example: apple-app-site-association

{
  "webcredentials": {
    "apps": [
      "ABCDE12345.com.example.one",
      "FGHIJ67890.com.example.two"
    ]
  }
}

Duplicate iOS App IDs across apps are deduplicated.

[
  {
    "relation": [
      "delegate_permission/common.handle_all_urls",
      "delegate_permission/common.get_login_creds"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.one",
      "sha256_cert_fingerprints": [
        "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99"
      ]
    }
  }
]

Fingerprints are normalized to colon-separated uppercase hex when served.

Both relations from Google's Credential Manager prerequisites are included, as some devices reject passkey creation when handle_all_urls is missing. The additional relation only takes effect if your app declares matching intent filters.

Caching

The contents are specific to your instance domain, so HTTP caching is disabled and the files are always served directly by ZITADEL:

Cache-Control: no-store

Platform verifiers cache association files on their side. After you change app link settings, allow time for OS verification to refresh before expecting passkeys to work with the new values.

Verify

curl -i "${CUSTOM_DOMAIN}/.well-known/apple-app-site-association"
curl -i "${CUSTOM_DOMAIN}/.well-known/assetlinks.json"

Confirm:

  • HTTP status 200
  • Content-Type: application/json
  • Cache-Control: no-store header
  • JSON contents match your configured apps

Was this page helpful?

On this page