# Third-party authentication

Already have authentication in your iOS app? Openfort's embedded signers work with **any provider that issues JWT-based, stateless tokens**. Instead of replacing your login, you give Openfort a way to fetch the current user's access token, and Openfort verifies it server-side to bind an embedded wallet to that user. Your existing sign-in stays exactly as it is.

This is the right path when you use Firebase, Supabase, Auth0/Cognito (via OIDC), a game backend like PlayFab, or your own auth server.

## How it works

1. The user signs in with **your** provider (Firebase, Supabase, and so on).
2. You pass a `getAccessToken` closure to `setupSDK` that returns your provider's current ID token.
3. Openfort calls that closure, **verifies the token** against the provider you configured in the dashboard, and resolves the Openfort user.
4. An embedded wallet is linked to that user — ready to configure and sign.

## Supported providers

Configure your provider in the [Openfort Dashboard](https://dashboard.openfort.io) first, then pass the matching `OFAuthProvider` case to `setupSDK`.

| Provider | `OFAuthProvider` case | Setup guide |
|----------|-----------------------|-------------|
| Firebase | `.firebase` | [Firebase](/docs/configuration/external-auth/firebase) |
| Supabase | `.supabase` | [Supabase](/docs/configuration/external-auth/supabase) |
| PlayFab | `.playfab` | [PlayFab](/docs/configuration/external-auth/playfab) |
| AccelByte | `.accelbyte` | [AccelByte](/docs/configuration/external-auth/accelbyte) |
| LootLocker | `.lootlocker` | [LootLocker](/docs/configuration/external-auth/lootlocker) |
| Custom OIDC (Auth0, Cognito, …) | `.oidc` | [Custom OIDC](/docs/configuration/custom-auth/oidc-token) |
| Custom auth server | `.custom` | [Custom auth](/docs/configuration/custom-auth/auth-token) |

## Configure the SDK with your provider

Pass `thirdParty` and `getAccessToken` to `setupSDK`. The closure runs whenever Openfort needs a fresh token, so return your provider's *current* token each time — don't cache a stale one.

This example uses Firebase:

```swift
import UIKit
import OpenfortSwift
import FirebaseAuth

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        do {
            try OFSDK.setupSDK(
                thirdParty: .firebase,
                getAccessToken: {
                    // Return the current user's ID token, or nil if signed out.
                    try await Auth.auth().currentUser?.getIDToken()
                }
            )
        } catch {
            // e.g. OFError.keychainInaccessible or OFError.missingConfiguration
            print("Openfort setup failed: \(error.localizedDescription)")
        }
        return true
    }
}
```

:::note
`setupSDK` is a throwing function — always call it with `try`. `getAccessToken` is a **named parameter**, not a trailing closure, so keep it inside the call's parentheses.
:::

:::warning
`setupSDK()` returns before the embedded WebView bridge is ready. Await readiness before the first SDK call: `try await OFSDK.shared.waitUntilReady()`. See [Getting started](/docs/products/embedded-wallet/swift).
:::

## Keep Openfort in sync with sign-out

When the user signs out of your provider, the `getAccessToken` closure should return `nil` so Openfort drops the session. With Firebase, observe the auth state and refresh Openfort accordingly:

```swift
import FirebaseAuth
import OpenfortSwift

func observeAuthState() {
    Auth.auth().addStateDidChangeListener { _, user in
        Task {
            if user != nil {
                // Token is available; Openfort can fetch it via getAccessToken.
                _ = try? await OFSDK.shared.getAccessToken()
            } else {
                try? await OFSDK.shared.logOut()
            }
        }
    }
}
```

## Next steps

* Follow your provider's [external-auth configuration guide](/docs/configuration/external-auth) to register it
* [Configure the embedded wallet](/docs/products/embedded-wallet/swift/wallet/recovery) once the user is authenticated
* Read about [user sessions](/docs/products/embedded-wallet/swift/auth/user-session)
