> For the complete documentation index, see [llms.txt](https://manual.bubble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manual.bubble.io/help-guides/data/user-accounts/sign-in-with-apple.md).

# Sign in with Apple

## What is Sign in with Apple?

Sign in with Apple lets your end-users create an account and log in with the Apple Account they already have. On iOS, the sign-in sheet is presented by the operating system and confirmed with Face ID, Touch ID, or the device passcode. The end-user never leaves your app and never types a password. On Android and on the web, they sign in through Apple's page in the system browser.

<figure><img src="/files/ND2cuWQfjx5VR5Vho68O" alt=""><figcaption></figcaption></figure>

Apple is a built-in login provider in Bubble. There's no plugin to install: you add the Apple Sign-In Button element, fill in a few credentials in Settings, and Bubble handles the rest.

{% hint style="info" icon="user-question" %}
**Note**: In this article, **you** are the Bubble developer building the app, and **end-users** are the people who use it.
{% endhint %}

#### Where it works

<table><thead><tr><th width="111.85546875">Platform</th><th>How it works</th><th>Identifier used</th></tr></thead><tbody><tr><td><strong>iOS</strong></td><td>Apple's native sign-in sheet</td><td>Bundle ID</td></tr><tr><td><strong>Android</strong></td><td>Apple's sign-in page in the system browser</td><td>Service ID</td></tr><tr><td><strong>Web</strong></td><td>Apple's sign-in page</td><td>Service ID</td></tr></tbody></table>

Apple publishes no native Android SDK and blocks Sign in with Apple inside embedded webviews, which is why Android goes out to the system browser.

#### Apple sign-in button availability

The Apple Sign-In Button element is available **in mobile views only**. On the web you can still trigger the flow from any button using the [Signup/login with a social network action](/core-resources/bubble-workflows/bubble-actions/account-actions.md#signup-login-with-a-social-network).

## When you're required to offer it

Apple's App Review Guideline 4.8 (Design: Login Services) applies to any app using a third-party or social login service (Google, Facebook, LinkedIn, X, Amazon) to set up or authenticate an end-user's primary account.

If your app does that, it must also offer an equivalent login option that limits data collection to name and email address, lets the end-user keep their email address private, and doesn't collect in-app interactions for advertising without consent. Sign in with Apple meets all three, which makes it the most direct way to comply.

**External page**: [Apple app Review Guidelines](https://developer.apple.com/app-store/review/guidelines/)

{% hint style="info" %}
You do not need Sign in with Apple if your app only offers email and password login. It becomes a requirement the moment you add a third-party social login. This is a common cause of App Store rejection for Bubble apps using the Google plugin
{% endhint %}

## Before you start

**You'll need:**

* [ ] **An active Apple Developer Program membership with the Admin or Account Holder role** — creating keys and editing capabilities requires one of these.
* [ ] **Your app connected to App Store Connect.** The Sign in with Apple section doesn't appear until you've connected your app in the Apple App Store settings, and it depends on the Bundle ID and Team ID from that form. If you haven't done this, connect your project to [App Store Connect](/help-guides/publishing-your-app/native-mobile-app/ios-app-store.md).

### Custom domains

You don't need a custom domain to offer Sign in with Apple, on any platform. For Android and the web, the *Return URL* Bubble gives you falls back to your app's built-in .bubbleapps.io subdomain, and you can register that subdomain with Apple when you configure your Services ID (Step 2).

A custom domain only matters if you want to send email to end-users who chose Hide My Email. See Step 4 for the details and the limitation.

{% hint style="warning" icon="lock" %}
**Security**: This setup produces a private key file (.p8) that can authenticate as your app. Treat it like a password: store it securely, keep a backup, and never commit it anywhere public. It's the same class of credential as your APNs key and your App Store Connect API key — and a different key from both.
{% endhint %}

## Setting up Sign in with Apple

Start in Bubble. Turning on the Sign in with Apple permission (Step 1) is usually all it takes to enable the capability on Apple's side, because Bubble configures your App ID for you.

Steps 2 to 4 happen in the Apple Developer portal, at[ developer.apple.com/account](https://developer.apple.com/account) under *Certificates, Identifiers & Profiles*. Steps 2 and 4 are only needed if you're offering Sign in with Apple on Android or the web (Step 2) or emailing Hide My Email end-users (Step 4).

{% stepper %}
{% step %}

### Turn on the Sign in with Apple permission in Bubble

Go to *Settings → Device permissions* and turn on *Sign in with Apple*. Placing the Apple Sign-In Button element (see Adding the button to your app) turns it on for you.

That's normally the whole step. When you deploy, Bubble automatically adds the Sign in with Apple capability to your Bundle ID through the App Store Connect API. You don't need to touch the Apple Developer portal for this.

The automatic step is best-effort, and it can fail silently, most often when your App Store Connect API key doesn't have permission to manage identifiers.

**If a build fails**, enable the capability by hand in the Apple Developer portal:

1. Log into developer.apple.com.
2. Go to *Certificates, Identifiers & Profiles* → *Identifiers* and select your App ID.
3. Scroll the Capabilities list to Sign In with Apple and check it.
4. Click Edit, choose Enable as a primary App ID, and Save.
5. Save the App ID configuration in the top right corner.
6. Apple asks you to confirm that your provisioning profile needs updating. This is fine: Bubble generates a new profile with your next app build.

<figure><img src="/files/xDnP4VnW9x2Bc0QMm5OI" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Note**: Group with an existing primary App ID only if you have several apps that should share one Apple Account identity for the same end-user. Apple's user identifier is stable per primary App ID, not per app, so changing the grouping later can make existing end-users appear as new accounts.
{% endhint %}
{% endstep %}

{% step %}

### Create a Services ID (Android and web only)

{% hint style="info" %}
**Skip this if you're iOS-only.** On iOS, Bubble uses your Bundle ID automatically.
{% endhint %}

<figure><img src="/files/R48XbIfOs1mhULwDm7XZ" alt=""><figcaption></figcaption></figure>

1. Go to Identifiers, click +, choose Services IDs, and click Continue.
2. Enter a description and an identifier. The convention is your Bundle ID with a suffix, for example com.mycompany.myapp.siwa.
3. Register it, then select it from the list and check Sign in with Apple.
4. Click *Configure*:
   1. Set *Primary App ID* to your app's App ID.
   2. Under *Domains and Subdomains*, add your app's domain, without the https\:// part. If you don't have a custom domain, enter your app's built-in Bubble subdomain, for example myapp.bubbleapps.io.
   3. Under *Return URLs*, paste the Return URL shown in Bubble's Sign in with Apple settings (Step 5). If your app has no custom domain, this URL is on your bubbleapps.io subdomain, which works fine.
5. Save and continue.

{% hint style="info" %}
**Note:** Apple verifies the domain you register here, but it doesn't have to be a custom domain. Your .bubbleapps.io subdomain is accepted.
{% endhint %}
{% endstep %}

{% step %}

### Create a Sign in with Apple key

Bubble uses this key to sign its requests to Apple on your behalf: the token exchange on Android and the web, and revoking an end-user's token when they delete their account.

1. In the Apple Developer portal, click *Keys* in the sidebar, then +.
2. Name the key so you can identify the app later, for example Sign in with Apple.
3. Check *Sign in with Apple*, click *Configure*, select your Primary App ID, and Save.
4. Click *Continue*, then *Register*.
5. Download the `.p8` file.
6. Copy the Key ID from the confirmation page.

<figure><img src="/files/IY7ciImzdah08bDiT93s" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
**Warning**: You can download the `.p8` file only once. If you leave the page without downloading it, revoke the key and create a new one.
{% endhint %}

{% hint style="info" %}
**Note**: Apple generates filenames like AuthKey\_ABC123DEFG.p8 for every key type. Label your download clearly so you don't confuse it with your APNs key or your App Store Connect API key.
{% endhint %}
{% endstep %}

{% step %}

### Register your sending domain for private email relay (optional)

End-users can choose *Hide My Email* during signup. Apple then gives your app a relay address ending in `@privaterelay.appleid.com` and forwards messages to the end-user's real inbox, but only from domains you've registered.

This step is optional for sign-in itself. Sign in with Apple works end to end on every platform without it. You only need to configure the relay if your app sends emails to end-users, like password resets, receipts, or notifications, and some of those end-users chose *Hide My Email*. Without it, Apple's relay rejects messages sent from your app to those end-users.

{% hint style="warning" %}
**Warning:** Without a custom domain, you can't email end-users who chose Hide My Email. Registering a domain here requires adding a TXT record to its DNS and passing SPF and DKIM checks, so it must be a domain you control.

If your app sends email through Bubble's built-in email service and you don't have a custom domain, you can't complete this step, and there's currently no way to deliver email to end-users who chose Hide My Email. Sign-in itself isn't affected: those end-users can still create accounts and log in.

If emailing your end-users matters to your app, set up a custom domain and your own email-sending configuration first.
{% endhint %}

1. Go to *Certificates, Identifiers & Profiles* → *Services*.
2. Under *Sign in with Apple for Email Communication*, click *Configure*.
3. Register each domain or subdomain you send email from, as a comma-separated list, and click *Register*.
4. Verify each domain and make sure SPF or DKIM is in place. The envelope sender domain of your outbound email must exactly match a registered domain and pass SPF.

Reference: [Configure private email relay service](https://developer.apple.com/help/account/capabilities/configure-private-email-relay-service) (Apple)

{% hint style="info" %}
**Note**: Individual accounts can register up to 32 email sources; organization accounts up to 100.
{% endhint %}
{% endstep %}

{% step %}

### Configure Sign in with Apple in Bubble

{% hint style="info" %}
**Note:** The section only appears once your app is connected to the Apple App Store settings. On a brand-new app it stays hidden until then, because Sign in with Apple depends on the Bundle ID and Team ID from that connection.
{% endhint %}

Go to *Settings → Apple app store*. Below the App Store Connect card you'll find the *Sign in with Apple section.*

The section looks like this:

<figure><img src="/files/KNAE9fCzJQXmjVMtE7YW" alt="Enabling Apple App store settings"><figcaption><p>First, Connect to the Apple App store setting.</p></figcaption></figure>

<figure><img src="/files/VbfXa6Q0yytLuVz1oUVh" alt="Apple App Store settings panel"><figcaption><p>See below on how to fill out this section.</p></figcaption></figure>

The fields are grouped by what they're needed for.

#### Required for all platforms

<table><thead><tr><th width="181.34765625">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong>Key ID</strong></td><td>From Step 3. Bubble uses this key to sign two kinds of requests to Apple: the token exchange when an end-user signs in on Android or the web, and revoking an end-user's Apple token when they delete their account, as Apple requires.</td></tr><tr><td><strong>Private key (<code>.p8</code>)</strong></td><td>Upload the file from Step 3.</td></tr></tbody></table>

#### Web and Android (optional)

<table><thead><tr><th width="186.55859375">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong>Service ID</strong></td><td>The identifier from Step 2, for example <code>com.mycompany.myapp.siwa</code>. Required for Android and web. Not used on iOS.</td></tr><tr><td><strong>Return URL</strong></td><td>Read-only, with a copy button. Copy this into your Service ID's <em>Return URLs</em> field in the Apple Developer portal. Only the Android and web flows use it.</td></tr></tbody></table>

#### Validate your credentials

Once the required fields are filled in, click *Validate*. Bubble checks your credentials against Apple and surfaces any problem immediately: a wrong Key ID or a `.p8` file that doesn't match it fails validation with a specific error, instead of failing silently when an end-user tries to sign in.

After validation succeeds, the button is disabled and the section shows Credentials validated; the form collapses into its configured state, with the Web and Android fields still visible. Editing any relevant field clears the validated state and requires you to validate again.

Below the fields, an information block headed Emails to "Hide My Email" users repeats the private relay guidance from [Step 4.](#register-your-sending-domain-for-private-email-relay)
{% endstep %}
{% endstepper %}

## Adding the button to your app

### The Sign in with Apple permission

You already turned this on in Step 1, and placing the Apple Sign-In Button turns it on automatically, so you'll usually find it enabled.

<figure><img src="/files/R14O7EvAAM5Oi9dl8TfX" alt=""><figcaption></figcaption></figure>

The permission card in *Settings → Device permissions* reads:

> Adds the Sign in with Apple capability to your iOS builds. Requires the capability to be enabled on your App ID in the Apple Developer portal.

{% hint style="warning" %}
**Warning:** This permission is what puts the capability into your iOS binary. If you deploy with it off, Sign in with Apple stops working in that build, and you'll need a new build (**not** an OTA update) to fix it.
{% endhint %}

### Adding the element

In a **mobile view**, open the element palette and find Apple Sign-In Button under Authentication.

<figure><img src="/files/m9C91C6ckb0Is4auRzEZ" alt=""><figcaption></figcaption></figure>

When you place it, Bubble does three things: creates the element, wires up a workflow (*Apple Sign-In Button A is tapped → Signup/login with Apple*), and turns on the Sign in with Apple device permission. For the standard sign-in flow, that's the whole setup — you don't need to add anything to the workflow.

### Styling the button

Apple controls how its button looks, and App Review checks it. Bubble exposes Apple's own options and locks the rest.

<table><thead><tr><th width="149.78125">Property</th><th>Options</th></tr></thead><tbody><tr><td>Button type</td><td>Label and icon, or Logo only</td></tr><tr><td>Button style</td><td>Black, White, or White with outline</td></tr><tr><td>Text</td><td><p><em>Sign in with Apple</em>, <em>Sign up with Apple</em>, or <em>Continue with Apple</em>.</p><p><sup><sub>Hidden when</sub><sub> </sub><sub><em>Button type</em></sub><sub> </sub><sub>is</sub><sub> </sub><sub><em>Logo only</em></sub><sub>.</sub></sup></p></td></tr></tbody></table>

<figure><img src="/files/IZi53eDZQVge865T1v1l" alt="The three Apple button styles with text."><figcaption><p>The button styles with text: Black, white or white with outline.</p></figcaption></figure>

<figure><img src="/files/M17m63lODmOxZl58TVDw" alt="The three button caption types."><figcaption><p>The three caption alternatives. Hidden when <em>Button type</em> is <em>Logo only.</em></p></figcaption></figure>

<figure><img src="/files/o6cFskjUvRlH4GzwiSLs" alt="The three Apple button styles without text."><figcaption><p>The buttons without text, in three different styles</p></figcaption></figure>

You can change size, position and corner roundness. Opacity is locked: Apple's guidelines require the button background to stay pure black or white. Font, colours, padding, the Apple logo and shadows are rendered by Apple's component and can't be edited. Reusable styles don't apply.

When Button type is *Logo only*, the button keeps a 1:1 aspect ratio, and Bubble enforces Apple's minimum button size.

**External page:** [Creating a custom Sign in with Apple button](https://developer.apple.com/design/human-interface-guidelines/sign-in-with-apple#Creating-a-custom-Sign-in-with-Apple-button) (Apple Developer documentation)

{% hint style="warning" %}
**Note**: Don't make the Apple button smaller or less prominent than your other login buttons. Apple treats a de-emphasized *Sign in with Apple* button as a **Guideline 4.8 violation**.
{% endhint %}

## Workflows

The button exposes a single event: is tapped. There are no separate success or failure events, and the element has no exposed states.

The auto-created workflow uses the standard Signup/login with a social network action with the OAuth provider set to Apple. You can add actions after it, such as navigating to a view or creating related data, and they run once sign-in completes. If the end-user cancels the Apple sheet, the workflow stops.

You can also add the action manually to any workflow, including on web pages, without using the element.

{% hint style="info" %}
**Note**: Because there's no failure event, you can't currently branch on a failed sign-in inside a workflow. If an end-user's sign-in fails, they see an error message and the workflow ends. Validating your credentials in Settings (Step 5) is the way to catch configuration problems before end-users hit them.
{% endhint %}

<figure><img src="/files/tiCXwUrjxkMQUbTb0p8o" alt="Signup/login the user using a social network using Apple as provider."><figcaption><p>You can also add the action manually to any workflow, including on web pages, without using the element.</p></figcaption></figure>

## What Apple sends your app, and what you can use

On success, the end-user is signed up or logged in as a Bubble User, through the same path as any other OAuth provider.

The email address becomes the User's email. If the end-user chose Hide My Email, that's their  [relay address](#hidden-email-addresses): Bubble stores it and treats it as a normal, confirmed email address. `Current User's email` returns it.

The name and the Apple user identifier are stored on the User internally, but are not currently exposed anywhere you can reach them — no field, no data source, no expression.

{% hint style="warning" icon="user-question" %}
Warning: Apple sends the end-user's full name only on the **very first authorization**, and never again. Bubble captures and stores it, but there is currently no way for your app to read it back. If you need the end-user's name, **collect it in your own form after signup**.
{% endhint %}

### Hidden email addresses

Relay addresses (`a1b2c3d4e5@privaterelay.appleid.com`) work like normal addresses, provided you completed Step 4.

**Things to know**:

* The end-user can turn off forwarding at any time in their Apple Account settings. Your email then stops being delivered, with no signal to your app.
* The relay address is unique to your app, so you can't use it to match the end-user to an account created another way.
* If you haven't (or can't) complete Step 4, for example because your app has no custom domain and uses Bubble's built-in email sending, Apple's relay rejects email to these addresses. Sign-in still works; delivery doesn't.

## How Apple sign-in interacts with existing accounts

Sign in with Apple follows Bubble's general OAuth behavior:

* **A new end-user signs in with Apple**. A User is created and the Apple identity is stored on it.
* **An end-user who is already logged in signs in with Apple.** Bubble links their existing account to Apple, and they can then use either method. If a different User already holds that Apple identity, the link fails with "We cannot link your account to this email because there is already an account for this email".
* **Someone signs in with Apple while logged out, and the email Apple returns already belongs to another User:** for example, they originally signed up with that email and a password. This fails: they stay logged out and see your app's standard "email already used" message. No account is created and nothing is linked.

{% hint style="warning" %}
**Warning**: There is no automatic merge between an Apple sign-in and an existing email/password account with the same address. If you're adding Sign in with Apple to an app that already has end-users, they need to log in first and then sign in with Apple to link the two. Signing in with Apple while logged out will fail for them.
{% endhint %}

## Account deletion

Apple requires two things of apps offering Sign in with Apple, and both are checked at review:

* Guideline 5.1.1(v): end-users must be able to delete their account from within the app.
* The app must revoke the Apple tokens for a deleted account.

Bubble handles revocation for you. Whenever a User is deleted server-side, Bubble calls Apple's revoke endpoint automatically. You don't need to add anything to your delete-account workflow beyond deleting the User.

Revocation needs your Team ID, Key ID, and .p8 private key to be configured. If they're missing, deletion still succeeds and Bubble skips the revocation with a warning in your server logs.

{% hint style="warning" %}
**Note**: Accounts created by signing in through BubbleGo don't have a stored refresh token, so revocation is skipped for them. This doesn't affect end-users of your published app.
{% endhint %}

You still need to build the delete-account flow itself; Apple requires it to be reachable from inside the app.

## Testing

<table><thead><tr><th width="274.8984375">Environment</th><th>Sign in with Apple support</th></tr></thead><tbody><tr><td>BubbleGo</td><td>Sign in with Apple works. Requires a recent BubbleGo build.</td></tr><tr><td>Mobile web preview</td><td>Works, using the Android/web flow rather than the native sheet. Requires the Service ID, Team ID, Key ID, and .p8 all to be configured.</td></tr><tr><td>TestFlight and App Store builds</td><td>The only way to test the native iOS sheet in context.</td></tr></tbody></table>

**To test the first-time flow again:** after an end-user authorizes your app once, later sign-ins are silent and return no name. To reset, on the device open *Settings*, tap your name, tap *Sign in with Apple*, select your app and tap Stop using Apple Account.

{% hint style="warning" %}
**Warning**: Turning the Sign in with Apple permission on or off changes your binary. Test on a build made after you enabled it — an OTA update won't add the capability.
{% endhint %}

## Troubleshooting

<details>

<summary>Validation fails in Settings → Apple app store</summary>

The credentials don't check out against Apple, most often because of a wrong Key ID or a `.p8` file that doesn't match the Key ID. Re-check both against the key's confirmation page in the Apple Developer portal, and revalidate.

</details>

<details>

<summary>Apple Sign-In is not fully configured: the app is missing its iOS Bundle ID or Service ID.</summary>

Neither a Bundle ID nor a Service ID is set. Connect your app to App Store Connect, and add a Service ID if you're targeting Android or web.

</details>

<details>

<summary>Missing Apple identity token on Android or web</summary>

Usually the `.p8` private key isn't uploaded. Without it, Bubble can't complete the token exchange with Apple. Check all four values: Service ID, Team ID, Key ID, and private key.

</details>

<details>

<summary>We could not verify your Sign in with Apple credentials. Please try again.</summary>

The token from Apple didn't validate. Most often this is a Service ID or Bundle ID that doesn't match what Apple issued the token for. Confirm the Service ID in Bubble matches the one configured in the Apple Developer portal.

</details>

<details>

<summary>Sorry, we ran into a temporary bug and can't complete your request…</summary>

Apple's token endpoint rejected the request. The usual cause is a wrong Key ID or a `.p8` that doesn't match it. Run Validate in *Settings* → *Apple app store*; the same misconfiguration fails validation there with a specific error.

</details>

<details>

<summary>Nothing happens when the button is tapped</summary>

The build may predate Sign in with Apple support. Generate a new build. This can't be fixed with an OTA update.

</details>

<details>

<summary>The end-user's name is empty</summary>

Expected. See *What Apple sends your app*.

</details>

<details>

<summary>Emails to @privaterelay.appleid.com aren't delivered</summary>

Your sending domain isn't registered with Apple or isn't passing SPF. See Step 4. If your app has no custom domain and sends through Bubble's built-in email service, this can't currently be fixed. See the warning in Step 4.

</details>

<details>

<summary>Rejected under Guideline 4.8</summary>

This usually means the Apple button is smaller, lower, or visually weaker than the other login buttons.

</details>

## Issues flagged in the editor

<details>

<summary>Sign in with Apple is turned on but not fully configured. Please fill out [fields] in the Settings Tab.</summary>

One or more of the Service ID, Team ID, Key ID, or private key (.p8) is blank. Complete all four fields in the *Settings* tab to finish the configuration.

</details>

<details>

<summary>Signup/login with Apple requires the Sign in with Apple permission. Turn it on in Settings → Device permissions.</summary>

The Sign in with Apple permission isn't enabled for your app. Go to *Settings → Device permissions* and turn it on.

</details>

***

### FAQ: Sign in with Apple

<details>

<summary>Do I need Sign in with Apple if my app only uses email and password?</summary>

No. Guideline 4.8 applies only when you offer a third-party or social login service.

</details>

<details>

<summary>Does it work on Android?</summary>

Yes, through Apple's sign-in page in the system browser. It needs a Services ID, unlike iOS, **but not a custom domain** — your bubbleapps.io subdomain works.

</details>

<details>

<summary>Do I need a custom domain?</summary>

Not for sign-in, on any platform. You only need a domain you control if you want to send email to end-users who chose Hide My Email (see Step 4). Without one, those end-users can still sign up and log in, but your emails to them won't be delivered.

</details>

<details>

<summary>Do I need to install a plugin?</summary>

&#x20;No. Apple is built into Bubble as a login provider.

</details>

<details>

<summary>Can end-users who signed in with Apple also use a password?</summary>

Yes, they can add one with a Reset the user's password flow, the same as any other OAuth account. But an existing password account can't be joined to Apple by signing in with Apple while logged out — see How Apple sign-in interacts with existing accounts.

</details>

<details>

<summary>Can I get the end-user's name? </summary>

Not currently. Apple sends it once, on first sign-in, and Bubble stores it internally, but it isn't exposed in the editor. Collect the name in your own form.

</details>

<details>

<summary>What if I lose the .p8 file?</summary>

Revoke the key in the Apple Developer portal, create a new one, and upload it. Existing end-users are unaffected — the key authenticates your app, not them.

</details>

<details>

<summary>What happens if I accidentally expose the private key?</summary>

Revoke it immediately and generate a replacement. Deploy the change to Live.

</details>

<details>

<summary>Does Bubble listen to Apple's server-to-server notifications, for example when an end-user deletes their Apple Account?</summary>

Not currently. Bubble handles revoking tokens when you delete a User, but reacting to Apple-side account events (an end-user disabling or deleting their Apple Account) isn't supported.

</details>
