Apple Sign In Configuration

1. Overview

This guide explains how to configure the Registration Portal to authenticate users via Apple Sign In. Apple uses OIDC but has several non-standard requirements, particularly around client secret generation.

2. Prerequisites

  • An Apple Developer account (requires annual fee)

  • Access to the Apple Developer Portal > Certificates, Identifiers & Profiles

3. Apple Developer Portal Setup

3.1. App ID Configuration

  1. Navigate to Identifiers > App IDs

  2. Create or select an App ID

  3. Enable the Sign In with Apple capability

3.2. Services ID (OAuth2 Client)

  1. Navigate to Identifiers > Services IDs

  2. Click + to register a new Services ID

  3. Configure:

Field Value

Description

e.g., "Registration Portal"

Identifier

e.g., com.example.registrationportal (this becomes the client_id)

  1. Enable Sign In with Apple

  2. Click Configure:

Field Value

Primary App ID

Select the App ID from the previous step

Domains and Subdomains

Each tenant domain (e.g., runningclub.example.com)

Return URLs

https://<tenant-domain>/login/oauth2/code/apple

3.3. Key for Client Secret Generation

Apple does not use a static client secret. Instead, the client secret is a JWT signed with a private key.

  1. Navigate to Keys

  2. Create a new key with Sign In with Apple enabled

  3. Download the .p8 private key file

  4. Note the Key ID

  5. Note your Team ID (from the top-right of the developer portal)

The private key can only be downloaded once. Store it securely.

4. Client Secret Generation

Apple requires a JWT-based client secret that must be regenerated periodically (maximum validity: 6 months).

The client secret JWT must contain:

Claim Value

iss

Team ID

iat

Current timestamp

exp

Expiry (max 6 months from iat)

aud

https://appleid.apple.com

sub

Services ID (the client_id)

The JWT is signed with the ES256 algorithm using the private key from the .p8 file.

The Registration Portal should generate the client secret at runtime from the stored private key, key ID, and team ID. This avoids manual rotation every 6 months.

5. Registration Portal Configuration

Create a TenantIdentityProvider record with the following values:

Field Value

provider_type

APPLE

display_name

"Sign in with Apple"

client_id

Services ID identifier (e.g., com.example.registrationportal)

client_secret

Generated JWT client secret (or private key material for runtime generation)

issuer_uri

https://appleid.apple.com

authorization_uri

https://appleid.apple.com/auth/authorize

token_uri

https://appleid.apple.com/auth/token

jwks_uri

https://appleid.apple.com/auth/keys

scopes

name,email

user_name_attribute

sub

enabled

true

Apple supports OIDC Discovery at https://appleid.apple.com/.well-known/openid-configuration. However, explicit URI overrides are listed above for reference and as fallback.

6. Apple-Specific Behaviour

Characteristic Detail

OIDC Compliance

Mostly OIDC-compliant with some deviations

Client Secret

JWT signed with ES256 private key (max 6-month validity)

ID Token

Only returned on first authorization; subsequent logins may return only the authorization code

User Info

Name and email returned in the POST body of the first authorization callback only (not via userInfo endpoint)

Subject Identifier

Opaque string, unique per developer team, stable

Email Relay

Users can choose "Hide My Email" — Apple provides a relay address

Scopes

name and email only (no openid scope needed, but Apple returns an ID token regardless)

PKCE

Supported and recommended

7. Important Caveats

  1. First-login-only user data: Apple only sends the user’s name in the initial authorization. The application must capture and store it during the first login. Subsequent logins do not include the name.

  2. Private Relay Email: When users select "Hide My Email", Apple generates a unique relay address (e.g., [email protected]). The relay address is stable per app per user.

  3. Client Secret Rotation: The JWT client secret expires. Implement automated generation from the stored private key rather than manual rotation.

  4. Form POST Response Mode: Apple’s authorization endpoint uses response_mode=form_post by default, returning the authorization code via POST. Spring Security handles this, but custom configurations should be aware.