Get credentials from Apple
Register an App ID
- Sign in to Apple Developer and go to Certificates, Identifiers & Profiles.
- Under Identifiers, click + and choose App IDs.
- Select App as the type, then fill in your bundle identifier (e.g.
com.example.app). - Scroll to Capabilities and enable Sign In with Apple.
- Save the App ID.
Create a Services ID
The Services ID is your OAuthclient_id for web and non-iOS flows.- Under Identifiers, click + and choose Services IDs.
- Enter a description and an identifier (e.g.
com.example.app.auth). - Enable Sign In with Apple.
- Click Configure next to Sign In with Apple:
- Set your Primary App ID to the one you just created.
- Add your domain (e.g.
auth.example.com, no trailing slash, no protocol). - Add your Return URL (e.g.
https://auth.example.com/auth/oauth/apple/callback).
- Save and register.
Create a private key
- Under Keys, click +.
- Name the key and enable Sign In with Apple.
- Click Configure and select your Primary App ID.
- Download the
.p8key file, you can only download it once. - Note your Key ID and Team ID (visible at the top right of the developer portal).
Configuration
lib/kavach.ts
Generate the client secret
Apple does not accept a static client secret. Instead, you generate a JWT signed with your.p8 private key. The JWT is valid for up to 6 months, so you can generate it once and rotate it before it expires.
scripts/generate-apple-secret.ts
APPLE_CLIENT_SECRET environment variable. Re-run before the 6-month window closes.
The
jose library is already a dependency of kavachos/core, so you do not need to install it separately.Environment variables
.env
APPLE_CLIENT_ID and APPLE_CLIENT_SECRET are needed at runtime. The Team ID and Key ID are only used when regenerating the secret.
iOS native apps
On iOS, use the App ID (bundle identifier, e.g.
com.example.app) as clientId, not the Services ID. The Services ID is for web only. Pass appBundleIdentifier in the provider config alongside clientId if your backend handles both flows.user object directly in the app. Forward both to your server and exchange the code for a session using the same /auth/oauth/apple endpoint.
Localhost and development
Apple requires HTTPS for redirect URIs.localhost will not work. Options:
- ngrok,
ngrok http 3000gives you a public HTTPS URL instantly. - cloudflared tunnel, persistent tunnel with a stable subdomain.
- mkcert + local proxy, run a local HTTPS reverse proxy with a self-signed cert trusted by your browser.
baseUrl config to match the tunnel URL while developing.
User data
Apple embeds user claims in theid_token JWT returned from the token endpoint. KavachOS decodes this automatically.
| Field | Notes |
|---|---|
id | Stable Apple user identifier, a 24-character opaque string |
email | May be a private relay address (random@privaterelay.appleid.com) if the user chose to hide their email |
name | Only available on the first authorization, store it on your side immediately |
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /auth/oauth/apple | Initiate Apple sign-in. Returns a redirect URL to send the user to. |
GET | /auth/oauth/apple/callback | Handle the callback from Apple after the user authorizes. |
oauth plugin is configured with id: 'apple'.