Step 1: Find your Team ID
Sign in to the Apple Developer portal. Your Team ID is shown in the Membership details section. It is a ten-character value such asA1B2C3D4E5.
Step 2: Create an App ID
- Go to Certificates, Identifiers & Profiles > Identifiers.
- Add an identifier and choose App IDs, then App.
- Set a description and a Bundle ID in reverse-domain form, for example
com.example.app. - Under Capabilities, enable Sign in with Apple.
- Save. The Bundle ID is the value you will enter into Portal as the App ID.
Step 3: Create a Services ID
The Services ID is the identifier Apple treats as the OAuth client for web sign-in. It is a separate identifier from the App ID.-
In Identifiers, add another identifier and choose Services IDs.

-
Set a description and an identifier, for example
com.example.auth. This is the value you will enter into Portal as the Service ID. - Save, then reopen the Services ID and enable Sign in with Apple.
-
Click Configure and set:
- Primary App ID: the App ID from step 2.
- Domains and Subdomains:
api.portalhq.io - Return URLs: the Portal callback URL for each environment, as described in The return URL Apple needs.

- Save.
The return URL Apple needs
The Apple OAuth process should redirect to Portal, which verifies the sign-in with Apple and then redirects the user on to your Redirect URL. The return URL you register with Apple is therefore a Portal URL:<AUTH_ENVIRONMENT_ID> with the Auth Environment ID from
Authentication > Configure. Each environment has a different Auth Environment
ID, so register a return URL for each environment you plan to use.
Step 4: Create a Sign in with Apple key
- Go to Certificates, Identifiers & Profiles > Keys.
- Add a key, give it a name, and enable Sign in with Apple.
- Click Configure and select the App ID from step 2 as the primary App ID.
- Register the key and download the
.p8file. - Note the Key ID shown on the key’s page.
The
.p8 file can only be downloaded once. Store it somewhere safe. If you lose
it you have to revoke the key and create a new one.Step 5: Enter the credentials in Portal
Information from Apple (to enter in Portal):- Team ID: your ten-character Apple team identifier
- App ID: the Bundle ID from step 2, for example
com.example.app - Service ID: the Services ID from step 3, for example
com.example.auth - Key ID: the identifier of the key from step 4
- Private key: the full contents of the
.p8file
- In the dashboard, click Configure in the left sidebar, under Authentication, and select the environment.
- In the Apple OAuth section, turn on the toggle.
- Fill in all five fields and save.

.p8 file, including the
-----BEGIN PRIVATE KEY----- and -----END PRIVATE KEY----- lines.
All five fields are write-only. After saving, each shows that a value is stored
rather than the value itself. To replace one, type the new value and save. To
leave a stored value alone, leave its field empty.
Step 6: Sign a user in
Get the authorize URL
apple key only if Apple is enabled on the environment.
redirectUrl must be URL-encoded and must exactly match one of your Redirect
URLs.
Send the user to Apple
Opendata.apple in a browser. The user signs in and consents, choosing whether
to share their real email address or use Apple’s private relay.
Apple posts the result to Portal, Portal verifies it, and Portal redirects the
user to your Redirect URL:
Exchange the token
clientSessionToken is null and
userJwt is set. See
Two-factor authentication.
Handle a failed sign-in
If the user cancels, or the exchange fails, Portal redirects them to your Redirect URL with an error instead of a token:error before looking for token on your callback page, and offer the
user another attempt.
How Apple handles email addresses
Portal identifies an end user by email address, and Apple’s behaviour around email is worth knowing about.- Apple only returns the user’s email on their first consent for a given Services ID. Portal records it then and recognizes the user by their Apple account on later sign-ins.
- If Apple does not supply an email, Portal cannot create the end user and the sign-in fails. In practice this happens when a user has previously consented under a different configuration.
- If the user chooses Hide My Email, Apple supplies a private relay address
such as
abc123@privaterelay.appleid.com. That relay address is what Portal stores, so a user who signs in with Google/Magic Links using their real address and with Apple using a relay address is treated as two separate end users, each with their own wallet.
Next steps
Two-factor authentication
Add a TOTP second factor to every sign-in.
API reference
Full reference for the OAuth endpoints.