Add Login to Your iOS or macOS Application using the Auth0.swift SDK - Auth0 Docs

Use AI to integrate Auth0

If you use an AI coding assistant like Claude Code, Cursor, or GitHub Copilot, you can add Auth0 authentication automatically in minutes using agent skills.Install:

npx skills add auth0/agent-skills --skill auth0

Then ask your AI assistant:

Add Auth0 authentication to my iOS app

Your AI assistant will automatically create your Auth0 application, fetch credentials, add the Auth0.swift SDK dependency, configure Auth0.plist, set up callback URLs, and implement login/logout flows. Full agent skills documentation →

Get Started

  1. Create a new project
    Create a new iOS or macOS project for this quickstart.In Xcode:
    1. File → New → Project (or ⌘+Shift+N)
    2. Select either:
      • iOS tab → App template
      • macOS tab → App template
    3. Configure your project:
      • Product Name: Auth0-Sample
      • Interface: SwiftUI
      • Language: Swift
      • Use Core Data: Unchecked
      • Include Tests: Checked (recommended)
    4. Choose a location and click Create

This creates a standard app with SwiftUI and Swift Package Manager support, perfect for Auth0 integration.

  1. Add the Auth0 SDK
    Add the Auth0 SDK to your project using your preferred package manager.
    • Swift Package Manager
    • CocoaPods
    • Carthage

In Xcode:

  1. File → Add Package Dependencies… (or ⌘+Shift+K)
  2. Enter the Auth0 SDK URL:
https://github.com/auth0/Auth0.swift
  1. Add Package → Select your app target → Add Package

  2. Create a Podfile in your project directory:

    platform :ios, '14.0' # Or platform :osx, '11.0' for macOS
    use_frameworks!
    

target 'YourApp' do pod 'Auth0', '~> 3.0' end


2. Install the dependencies:

pod install


3. Open the generated `.xcworkspace` file (not `.xcodeproj`)

1. Create a `Cartfile` in your project directory:

github "auth0/Auth0.swift" ~> 3.0


2. Run Carthage:

carthage update --platform iOS --use-xcframeworks


For macOS, use `--platform macOS`
3. Drag the generated `Auth0.xcframework` from `Carthage/Build` into your Xcode project
4. In your target’s **General** settings, add `Auth0.xcframework` to **Frameworks, Libraries, and Embedded Content**

3. **Configure Auth0**  
Create a new Auth0 application and configure callback URLs.
1. Go to [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
2. **Applications** \> **Create Application** \> Name it, select **Native** \> **Create**
3. In the **Settings** tab, note your **Client ID** and **Domain**
4. Add the following URLs to **Allowed Callback URLs**:

- iOS
- macOS

https://{yourDomain}/ios/YOUR_BUNDLE_IDENTIFIER/callback, YOUR_BUNDLE_IDENTIFIER://{yourDomain}/ios/YOUR_BUNDLE_IDENTIFIER/callback


https://{yourDomain}/macos/YOUR_BUNDLE_IDENTIFIER/callback, YOUR_BUNDLE_IDENTIFIER://{yourDomain}/macos/YOUR_BUNDLE_IDENTIFIER/callback


5. Add the following URLs to **Allowed Logout URLs**:

- iOS
- macOS

6. Click **Save Changes**

4. **Configure App Credentials**  
Create `Auth0.plist` in your project directory:
ClientId YOUR_AUTH0_CLIENT_ID Domain {yourDomain} ```

Never hardcode clientId or domain values directly in Swift source files — they will be committed to version control. Read them from environment variables or a build-time configuration file at runtime. For most apps, prefer Auth0.plist (the default approach in this quickstart).

Drag Auth0.plist into Xcode and ensure “Add to target” is checked.

  1. Create the Authentication Service
    Create AuthenticationService.swift to handle login, logout, and token storage.

Use CredentialsManager for token storage. The CredentialsManager class securely stores credentials in the Keychain and automatically refreshes expired access tokens. Always use it — do not store tokens in memory, UserDefaults, or localStorage.

  1. Right-click your project → New File… → Swift File

    1. Name it AuthenticationService
    2. Replace contents with:
    import Foundation
    import Auth0
    import Combine
    

@MainActor class AuthenticationService: ObservableObject { @Published var isAuthenticated = false @Published var user: UserProfile? @Published var isLoading = false @Published var errorMessage: String?

private let credentialsManager = CredentialsManager(authentication: Auth0.authentication())

init() { Task { await checkAuthenticationStatus() } }

private func checkAuthenticationStatus() async { isLoading = true defer { isLoading = false }

guard let credentials = try? await credentialsManager.credentials() else { isAuthenticated = false return }

isAuthenticated = true // Get the user profile from the stored ID token user = try? credentialsManager.userProfile() }

func login() async { isLoading = true errorMessage = nil defer { isLoading = false }

do { // offline_access is included in the default scope as of v3, shown here for clarity _ = try await Auth0 .webAuth() .scope("openid profile email offline_access") .useCredentialsManager(credentialsManager) .start()

isAuthenticated = true // Get the user profile from the stored ID token user = try? credentialsManager.userProfile() } catch { errorMessage = "Login failed: (error.localizedDescription)" } }

func logout() async { isLoading = true defer { isLoading = false }

do { try await Auth0 .webAuth() .useCredentialsManager(credentialsManager) .logout() isAuthenticated = false user = nil } catch { errorMessage = "Logout failed: (error.localizedDescription)" } } }


See all 70 lines

6. **Configure Authentication Flow (Optional)**  
To improve the user experience, you can minimize system alerts in the following ways:
1. Use Universal Links: This eliminates the ‘Open in “AppName”?’ prompt that appears during the redirect. Note: The ASWebAuthenticationSession permission alert will still appear.
2. Use Ephemeral Sessions: This eliminates all permission alerts. Note: This disables Single Sign-On (SSO) and shared cookies.

**Skip this step** to use the default behavior with a permission alert. You can configure this later.

- Universal Links
- Ephemeral Session

1. Auth0 Dashboard → **Applications** → Your app → **Settings** → **Advanced Settings** → **Device Settings**
2. Add **Apple Team ID** and **bundle identifier** → **Save**
3. Xcode: Target → **Signing & Capabilities** → **\+ Capability** → **Associated Domains**
4. Add: `webcredentials:{yourDomain}`

Requires: Paid Apple Developer account, iOS 17.4+/macOS 14.4+

Best for production apps.

Add `.useEphemeralSession()` to the login call in `AuthenticationService.swift`:

```swift
// In the login() function
let credentials = try await Auth0
    .webAuth()
    .scope("openid profile email offline_access")
    .useCredentialsManager(credentialsManager)
    .useEphemeralSession()
    .start()

When using ephemeral sessions, you don’t need to call logout() on the Web Auth client. Just clear the credentials from your app - there’s no shared cookie to remove.

  1. Run your app
    Press ⌘+R in Xcode.
    1. Tap “Log In” → Permission alert (if using default) → Tap “Continue”
    2. Complete login in browser
    3. See your profile!

CheckpointYou now have a fully functional Auth0 login in your iOS or macOS app!

Troubleshooting & Advanced

Common Issues & Solutions

Build errors: ‘Auth0’ module not found

Solutions:

  1. Swift Package Manager: Check Package Dependencies → Verify Auth0.swift is listed
  2. CocoaPods: Ensure you’re opening the .xcworkspace file, not .xcodeproj
  3. Carthage: Verify Auth0.xcframework is added to Frameworks, Libraries, and Embedded Content
  4. Clean and rebuild: ⌘+Shift+K then ⌘+R
  5. Restart Xcode if needed

App crashes: ‘Auth0.plist not found’

Fix:

  1. Verify Auth0.plist is in your Xcode project navigator
  2. Select the file → Inspector → Ensure your app target is checked
  3. Confirm it has ClientId and Domain keys with your values

Browser opens but never returns to app

Fix:

  1. Check callback URLs in Auth0 Dashboard match your bundle identifier and platform exactly
  2. For iOS: URLs should contain /ios/, for macOS: /macos/
  3. Verify bundle identifier in Xcode matches Auth0 settings
  4. Ensure no typos in URLs (common: missing colons, wrong domain format)
  5. Custom domain users: Verify you’re using your custom domain, not the Auth0 domain

Permission alert appears every time

This is standard iOS/macOS security behavior when using custom URL schemes. See Step 6 to eliminate this alert using Universal Links or Ephemeral Sessions.

Custom Domain Configuration

If you’re using a custom domain, use its value instead of your Auth0 domain everywhere.Example: Use login.example.com instead of tenant.auth0.comThis is required for certain features to work properly:

Production Deployment

App Store Preparation

Security Best Practices

Performance Optimization

Advanced Integration

Enhanced Keychain Security with Biometrics

Require Face ID or Touch ID to access stored credentials:

private let credentialsManager: CredentialsManager = {
    var manager = CredentialsManager(authentication: Auth0.authentication())
    manager.enableBiometrics(
        withTitle: "Unlock with Face ID",
        cancelTitle: "Cancel",
        fallbackTitle: "Use Passcode"
    )
    return manager
}()

When enabled, users must authenticate with biometrics before the SDK can retrieve stored credentials.

Automatic Token Refresh

The CredentialsManager automatically refreshes expired access tokens:

// Get credentials - automatically refreshes if expired
func getAccessToken() async throws -> String {
    let credentials = try await credentialsManager.credentials()
    return credentials.accessToken
}

Use this pattern when making API calls that require an access token.

Shared Credentials Across App Extensions

For widgets, app extensions, or background tasks that need access tokens:

// Create a shared credentials manager with an app group
let credentialsManager = CredentialsManager(
    authentication: Auth0.authentication(),
    storeKey: "credentials",
    storage: SimpleKeychain(accessGroup: "group.com.example.myapp")
)

Requirements:

  1. Enable App Groups capability in Xcode for all targets
  2. Use the same app group identifier across targets
  3. Configure the shared CredentialsManager in each target

Authentication Flow Options Comparison

Feature Universal Links Ephemeral Session Default (Alert)
Permission Alert Reduced (no redirect prompt) None Shows all alerts
SSO Support Yes No Yes
Apple Developer Account Required Not required Not required
User Experience Best Good Acceptable
Setup Complexity Medium Easy Easy
Private Browsing Support Yes Yes No

Recommendations: