# Set up Sign in with Apple

Put an Apple button on your sign-in page. Make a Services ID and a Sign in with Apple key, paste four values into BuildBase and register the return URL.

Sign in with Apple puts an **Apple** button on your hosted sign-in page. The person confirms with their Apple Account, often with Face ID or Touch ID on an iPhone or Mac, and comes back to your app signed in. They can share their real email address or let Apple hide it behind a forwarding one. It suits apps with many iPhone and Mac users. Apple asks for more than other providers: a paid developer membership, an identifier for your website sign-in (a **Services ID**), and a private key file that BuildBase signs with.

> **Note:**

- A membership of the **Apple Developer Program**, and access to **Certificates, Identifiers & Profiles** in the [Apple Developer account](https://developer.apple.com/account/resources/identifiers/list).
- A public `https://` BuildBase server. Apple accepts only HTTPS return URLs on a public domain, never `localhost` or an IP address. BuildBase's cloud server is one; a self-hosted server on your laptop is not, so test Apple on a deployed server.
- An app in the BuildBase console, here **Acme Analytics**, and room on your plan: Apple counts toward your plan's limit of social sign-in providers.



## What goes where

| Copy this                | From                                                                      | Paste it into                                       |
| ------------------------ | ------------------------------------------------------------------------- | --------------------------------------------------- |
| Services ID identifier   | Apple, **Identifiers**, Services IDs, such as `com.acme.analytics.signin` | BuildBase, **Services ID**                          |
| Team ID                  | Apple, **Membership details**, 10 characters, such as `A1B2C3D4E5`        | BuildBase, **Team ID**                              |
| Key ID                   | Apple, **Keys**, your Sign in with Apple key, such as `XYZ987WVU6`        | BuildBase, **Key ID**                               |
| The whole `.p8` key file | The file Apple let you download once, `AuthKey_XYZ987WVU6.p8`             | BuildBase, **Private key (.p8)**                    |
| Domain                   | BuildBase, after you press **Create**                                     | Apple, the Services ID's **Domains and Subdomains** |
| Return URL               | BuildBase, after you press **Create**                                     | Apple, the Services ID's **Return URLs**            |

Only the key file is secret. There is no client secret to copy: Apple's client secret is a short-lived token signed with your key, and BuildBase makes it for you.

## 1. Make the identifiers and the key at Apple

These are the steps the console shows under **How to get your Apple keys**.

1. Sign in to your [Apple Developer account](https://developer.apple.com/account/resources/identifiers/list).
2. Under **Certificates, Identifiers & Profiles**, register an **App ID** with **Sign in with Apple** turned on, if you do not have one. If you have an iPhone app, its App ID will do.
3. Register a **Services ID**, such as `com.acme.analytics.signin`, with a description such as `Acme Analytics sign-in`. That identifier is the **Services ID** BuildBase asks for. It is not the App ID.
4. Under **Keys**, make a key with **Sign in with Apple** turned on, linked to that App ID. Download its `.p8` file (Apple lets you do this only once) and note its **Key ID**. The file is named `AuthKey_` followed by the Key ID.
5. Your **Team ID** is under **Membership details** in your Apple Developer account.

## 2. Add Apple in the BuildBase console

1. In the console, open **User management**, then **Authentication** under **Access**, and the **Methods** tab.
2. Press **Add auth method** and choose **Apple**. The dialog says what Apple needs and opens **How to get your Apple keys**.

![The Add new method dialog with Apple chosen, its note that Apple needs a Developer Program membership and a public https server, and the open guide How to get your Apple keys with its seven steps](/images/sign-in-setup/apple/console-choose.webp)

3. Fill in the form:
   - **Title**: your own name for the method, shown in the console only. The button always says Apple.
   - **Services ID**, **Team ID** and **Key ID**: as in the table above.
   - **Private key (.p8)**: open the `.p8` file in a text editor such as Notepad or TextEdit and paste all of it, from `-----BEGIN PRIVATE KEY-----` to `-----END PRIVATE KEY-----`.
   - **Scopes**: keep `name email`.

![The Apple form filled in: Title Apple, Services ID com.acme.analytics.signin, Team ID A1B2C3D4E5, Key ID XYZ987WVU6, an example private key, and the default scopes name and email](/images/sign-in-setup/apple/console-form.webp)

BuildBase checks the key when you press **Create**. Pasting the file's name, or part of the file, is refused at once:

![A message in the console: Could not add Apple. That is not a .p8 private key. Paste the whole file, from BEGIN PRIVATE KEY to the end.](/images/sign-in-setup/apple/console-bad-key.webp)

4. Press **Create**. The dialog says **One step left** and shows two values: the domain under **Domains and Subdomains** and the return URL under **Return URLs**, each with **Copy**.

![After Create: One step left, then the Domains and Subdomains box and the Return URLs box, each with a copy button, to paste into the Services ID at Apple](/images/sign-in-setup/apple/console-redirect-url.webp)

5. Press **Done**.
6. At Apple, open the Services ID, turn on **Sign in with Apple**, and choose **Configure**. Pick your App ID as the primary App ID, and add the domain under **Domains and Subdomains** and the return URL under **Return URLs**. Save the Services ID.

The return URL has this shape, and the domain is its host:

```text
https://api.console.buildbase.app/api/v1/auth/social/apple/<orgId>/<methodId>/callback
```

It starts with your BuildBase server, https://api.console.buildbase.app on BuildBase's cloud. Apple sends the person back to it with a form `POST`, not a redirect, so on a self-hosted server anything in front of BuildBase must let `POST` requests through to that path.

**The key is write-only.** When you edit the method later, the key box is empty and says a private key is saved. Leave it empty to keep it, or paste a new key file to replace it, with its new **Key ID**.

## 3. Attach it to your app

1. Open the **Settings** tab and press **Edit** on **Acme Analytics**.
2. Under **Methods**, tick **Apple** and press **Update**.

![The Edit auth setting sheet for Acme Analytics, at Methods: Apple ticked beside Email and password](/images/sign-in-setup/apple/console-attach.webp)

## 4. Check the preview

The **Preview** on the **Sign-in page** tab shows your look with sample GitHub and Google buttons, whatever your app offers. Press **Open the live page for Acme Analytics** above it to see the real page with the Apple button.

![The Preview on the Sign-in page tab, with the button Open the live page for Acme Analytics, and a sample sign-in card whose social buttons are always GitHub and Google](/images/sign-in-setup/google/console-preview.webp)

## 5. What people see

The hosted sign-in and register pages now have an **Apple** button.

![The hosted sign-in page Sign in to Acme, with the email and password form and, under or, an Apple button](/images/sign-in-setup/apple/hosted-button.webp)

Pressing it opens Apple's page. The first time, Apple asks the person whether to share their name, and whether to share their email address or hide it. Then Apple sends them back, and the sign-in page carries on as after any sign-in: a second step if your [two-step policy](/sign-in-setup/two-step) asks social sign-ins for one, **Trust this device?**, and the passkey offer if your app offers passkeys.

### The first sign-in

- **The name arrives once.** Apple sends the person's name only the first time they authorize your Services ID, and BuildBase saves it then. Later sign-ins carry an ID and an email address, and no name. To see the first time again while you test, remove your app under **Sign in with Apple** in the settings of the Apple Account you test with.
- **Hide My Email.** A person who hides their address gets one at `privaterelay.appleid.com`, such as `x7k2m9p4qz@privaterelay.appleid.com`, which forwards to their real inbox. That relay address matches no account they made another way, so where sign-up is open their first Apple sign-in makes a new account. Someone who already has an account should sign in as before and connect Apple from the Security screen.
- **Mail to relay addresses** is forwarded only from senders you register with Apple. Under **Certificates, Identifiers & Profiles**, then **Services**, register the domain or address your app's email comes from under **Sign in with Apple for Email Communication**. Until you do, magic links, sign-in codes and every other email to those people bounce.
- **Finding the account**: by the person's Apple user ID first, then by email address when Apple says it is verified (relay addresses count as verified), then as a new account if sign-up is open to them and your plan has room.
- **The ID is per team.** Apple gives the same person a different user ID, and a different relay address, in each developer team. If you [import users](/sign-in-setup/importing-users) with their Apple sign-ins, use a Services ID in the same team as before. Otherwise they are found by email address, which fails for anyone who hid theirs.

## In your app

Nothing changes in your code. People connect and remove Apple on the SDK's Security screen: see [Account security screens](/sign-in-setup/account-security-screens).

```tsx
import { useSaaSAuth } from '@buildbase/sdk/react';

export function SecurityButton() {
  const { openWorkspaceSettings } = useSaaSAuth();
  return (
    <button onClick={() => openWorkspaceSettings('security')}>Security</button>
  );
}
```

## Check it works

- [ ] **Apple** is in the **Login methods** list.
- [ ] The Services ID has **Sign in with Apple** on, with the domain and the return URL from the console.
- [ ] Your sending domain is registered under **Sign in with Apple for Email Communication**.
- [ ] **Apple** is ticked on your app, and **Open the live page** on your deployed server shows the button.
- [ ] A first sign-in creates a user with a name; a second reaches the same user.

## Things to watch out for

- **The name comes once, and is lost if that sign-in is refused.** Apple sends the person's name only the first time they authorize your Services ID. If that first sign-in is turned away (sign-up closed, an address not on your allowlist, the waitlist, a full plan), the account made later is named after the first part of its email address, which for a hidden address is a string of random letters. The person can fix it on the **Account** screen.
- **Hidden addresses bounce your email until you register your sender.** Under **Sign in with Apple for Email Communication**, register the domain your email comes from. Apple checks it with SPF or DKIM, and the domain must match the sending domain exactly. If you send from a Gmail or other address on a domain you do not own, register that single address instead.
- **A hidden address matches nothing you already have.** It matches no account made another way and no domain on your allowlist, so where sign-up is open, the first Apple sign-in of someone who hid their address makes a new account.
- **Apple needs a public HTTPS server.** It refuses `localhost` and IP addresses as return URLs, so test on a deployed BuildBase server.
- **User IDs and hidden addresses belong to one developer team.** Make every Services ID for this app in the same Apple developer team, or people who hid their address cannot be found again.
- **Finish at Apple within 10 minutes.** A sign-in left open on Apple's page for more than 10 minutes cannot finish: BuildBase sends the browser to your sign-in page, with a note that the sign-in expired. Start again from your app's **Sign in** button.

## If something goes wrong

| What you see                                                                                                                                            | Why                                                                                                                                                 | What to do                                                                                     |
| ------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| In the console: That is not a .p8 private key. Paste the whole file, from `-----BEGIN PRIVATE KEY-----` to the end.                                     | The key box holds part of the file, or something else                                                                                               | Open the `.p8` file in a text editor and paste all of it.                                      |
| In the console: That key is not an Apple Sign in with Apple key, which is an EC P-256 key.                                                              | The file is a private key, but not the kind Apple makes for Sign in with Apple                                                                      | Paste the `.p8` file from **Keys** at Apple.                                                   |
| Apple's page shows an error instead of asking the person to sign in, often `invalid_client`                                                             | The **Services ID** is wrong (an App ID pasted by mistake), or the domain or return URL is not on it                                                | Check the identifier, and the Services ID's **Configure** list.                                |
| Sign-in with that provider failed. Please try again.                                                                                                    | Apple sent the person back, but BuildBase could not finish: the key, **Key ID** or **Team ID** is wrong, or the key was revoked (`provider_failed`) | Check the three values, or make a new key and paste it with its Key ID.                        |
| Sign-in with that provider did not finish. Please try again.                                                                                            | The person cancelled at Apple, or Apple answered with an error (`provider_error`)                                                                   | Try again.                                                                                     |
| This email is already registered. Sign in the way you did before, then connect this provider from your account's security settings.                     | An account has this address, and Apple did not say it is verified (`email_unverified`)                                                              | The person signs in as before, then connects Apple from the Security screen.                   |
| This provider did not share an email address, so an account cannot be created. Allow access to your email address and try again.                        | The `email` scope was removed (`email_missing`)                                                                                                     | Clear the **Scopes** box to go back to the defaults.                                           |
| Sign-up is invite-only here, and there is no account for that address yet. Ask the team for an invitation, or sign in with an account you already have. | Public sign-up is off (`signup_disabled`)                                                                                                           | Invite the person, or open sign-up.                                                            |
| Sign-up isn't available for this address.                                                                                                               | The address is blocked or not on your allowlist (`signup_restricted`)                                                                               | Change the lists in **Who may sign up**. A relay address will not match an allowlisted domain. |
| Join the waitlist, and you can sign up once you're approved.                                                                                            | Sign-up is by waitlist (`waitlist_required`)                                                                                                        | Approve them on the waitlist.                                                                  |
| This app is not taking new sign-ups right now.                                                                                                          | Your plan's end-user limit is reached (`signup_unavailable`)                                                                                        | Upgrade, or remove users you no longer need.                                                   |
| Your account has been blocked. Please contact support for assistance.                                                                                   | The account is blocked (`blocked`)                                                                                                                  | Unblock the user in the console if that was a mistake.                                         |
| In the console: Your plan includes 2 social sign-in providers. Upgrade for more, or remove one.                                                         | Your plan's social provider limit is reached; the number is your plan's                                                                             | Upgrade, or delete a provider you no longer use.                                               |

## Next steps

- [Social providers](/authentication/social-providers#sign-in-with-apple) - the reference for every provider.
- [Importing users](/sign-in-setup/importing-users) - bring people over with their Apple sign-ins.
- [Account security screens](/sign-in-setup/account-security-screens) - connected accounts inside your app.
- [Set up sign-in, step by step](/sign-in-setup/overview) - every sign-in guide, and the order to set them up in.
