Overview
Apple Sign-In provides a secure and privacy-focused authentication method for iOS users. The Launch boilerplate already includes the Apple Sign-In wiring on both the API and the mobile client—you just need to enable it and add your credentials.
Prerequisites
- Apple Developer Account (paid membership required)
- iOS App with unique Bundle Identifier
- Access to Apple Developer Console
Steps
Step 0: Set Up ngrok (Recommended First)
Apple and Google sign-in flows work best with a stable HTTPS callback URL. Use
ngrok to expose your local API, then set that URL in both the backend and mobile
env files.
Run ngrok and copy the HTTPS forwarding URL:
Example forwarding URL:
https://27f9fd215cd7.ngrok-free.app
- Start a tunnel to your API (running on port 3001).
- Copy the HTTPS URL from ngrok.
- Update
apps/api/.env with BETTER_AUTH_URL set to the ngrok URL.
- Update
apps/mobile/.env with EXPO_PUBLIC_API_URL set to the same ngrok URL.
- Restart the API and the mobile app so the new URLs are used.
- Log in to Apple Developer Console
- Select Account from the top navigation
- Choose Certificates
- Pick your App ID (or create one) and set a bundle identifier such as
com.company.example
- Scroll down, find Sign in with Apple, enable it, and make sure
Enable as a primary App ID is checked
- Click Save
Step 2: Generate a Private Key
- Select Account from the top navigation
- Open Keys
- Click the + button
- Enter a Key Name (e.g., “Launch Apple Sign-In”)
- Find Sign in with Apple and click Configure
- Choose your Primary App ID (this should be the same bundle ID you set in Step 1, part 4)
- Click Save
- Click Continue, then Register
- Download the
.p8 key immediately (you can only download it once)
- Note the Key ID and your Team ID for the next steps
The .p8 file can only be downloaded once. Store it securely and never commit it to version control.
Step 3: Convert the Private Key to Base64
Apple requires the .p8 file to be stored as a single-line base64 string in your
environment. Convert the key locally using a secure method you trust, and avoid
online converters.
Example command:
base64 -i AuthKey_KEYID.p8 | tr -d '\n'
Step 4: Update Your API Environment
Add the values below to your backend environment file (see
apps/api/.env for where they live). The backend reads these at startup to
enable Apple Sign-In.
After updating the API environment, restart the API server so the new values
are loaded. Then restart the mobile app by running pnpm prebuild, followed by
pnpm ios to launch the iOS app.
You will need the following values:
APPLE_CLIENT_ID (your iOS bundle identifier)
APPLE_TEAM_ID (your 10-character team ID)
APPLE_KEY_ID (your 10-character key ID)
APPLE_PRIVATE_KEY_BASE64 (the base64 version of the .p8 key)
Finding Your Team ID
- Go to Apple Developer Console
- Click on your name in the top right
- Your Team ID is displayed next to your name
Finding Your Bundle Identifier
- In Apple Developer Console, go to Identifiers → App IDs
- Select your app
- The Identifier field shows your Bundle ID
Step 5: Mobile App Configuration
Update apps/mobile/app.config.ts to:
- Set your iOS bundle identifier (this must match
APPLE_CLIENT_ID).
- Uncomment the
expo-apple-authentication plugin.
- Enable the Apple Sign-In entitlement when you are ready to ship.
Step 6: Backend Configuration
The boilerplate already includes the server-side Apple Sign-In wiring in
apps/api/src/services/auth.ts. Once the Apple environment values exist, the
provider is enabled automatically.
Step 7: Testing
Confirm Apple Sign-In is working by:
- Running the iOS app on a simulator or device.
- Tapping the Apple Sign-In button on the login screen.
- Verifying that you return to the app authenticated.
Success Checks
- You can sign in successfully from the app using Apple.
- Query your database and confirm a new user appears in the
users table and
a linked record exists in the accounts table.
Troubleshooting
-
Apple Sign-In button not appearing: ensure you are running on iOS and that
expo-apple-authentication is enabled in apps/mobile/app.config.ts.
-
Invalid client: confirm your bundle ID matches
APPLE_CLIENT_ID.
-
Backend validation errors: verify all Apple env values are set and restart
the API after changes.