{"registry_version":"2026.1025.387","generated_at":"2026-10-25T06:27:00Z","content_sha256":"089d16f627d9365e3d0663cc8069203706d7cb23a76c332226e29686968811a5","signed":true,"signature":{"key_id":"ed25519:74ca19268e364242","algorithm":"ed25519","expires_at":"2026-11-24T06:27:09Z","expired":false,"manifest":"/registry/manifest.json"},"entry_sha256":"dade1a1d71f8203c5585e3019f3f8fa8f49a911199cb586804f1dd13dcf9fbb1","entry":{"id":"apple/sign-in-with-apple","name":"Sign in with Apple (web and non-Apple platforms)","vendor":"Apple","summary":"Set up Sign in with Apple for a website or a non-Apple platform: enable it on a primary App ID, create a Services ID with your domains and return URLs, create a private key, and sign a client secret (JWT) that must be renewed at least every six months. Optionally register email sources so you can email users who hide their address behind Apple's private relay.","aliases":["SIWA","Apple Sign In","Apple ID login","Sign in with Apple JS"],"category":"auth","group":"B","homepage":"https://developer.apple.com/sign-in-with-apple/","docs":["https://developer.apple.com/documentation/signinwithapple/configuring-your-environment-for-sign-in-with-apple","https://developer.apple.com/help/account/configure-app-capabilities/configure-sign-in-with-apple-for-the-web","https://developer.apple.com/documentation/accountorganizationaldatasharing/creating-a-client-secret","https://developer.apple.com/help/account/configure-app-capabilities/configure-private-email-relay-service"],"status":"researched","last_verified":null,"last_researched":"2026-10-25","sources":[{"id":"configure-env","url":"https://developer.apple.com/documentation/signinwithapple/configuring-your-environment-for-sign-in-with-apple","title":"Configuring your environment for Sign in with Apple","accessed":"2026-10-25","supports":"Associate a Sign in with Apple-enabled primary App ID with a Services ID and private key; \"you must have an existing app in the App Store that uses Sign in with Apple\" for web authentication; primary vs grouped App IDs; register and verify all domains and subdomains; organisations up to 100 website URLs, individuals 10; return URLs absolute with scheme, host and path; max two private keys per primary app; rotate compromised keys; email sources (100 org / 32 individual) with SPF and/or DKIM; server-to-server notification endpoint (TLS 1.2+, one per app group).","kind":"official"},{"id":"web-config","url":"https://developer.apple.com/help/account/configure-app-capabilities/configure-sign-in-with-apple-for-the-web","title":"Configure Sign in with Apple for the web - Apple Developer Help","accessed":"2026-10-25","supports":"Services ID creation steps; associate with a primary App ID; at least one domain or subdomain; no file upload needed to register domains; removing the association affects services.","kind":"official"},{"id":"client-secret","url":"https://developer.apple.com/documentation/accountorganizationaldatasharing/creating-a-client-secret","title":"Creating a client secret","accessed":"2026-10-25","supports":"Client secret JWT fields - ES256 (P-256, SHA-256), kid, iss = Team ID, iat, exp no more than 15777000 seconds (six months) ahead, aud https://appleid.apple.com, sub = App ID or Services ID (case-sensitive).","kind":"official"},{"id":"rest-tokens","url":"https://developer.apple.com/documentation/signinwithapplerestapi/generate-and-validate-tokens","title":"Generate and validate tokens - Sign in with Apple REST API","accessed":"2026-10-25","supports":"client_id is the App ID or Services ID; client_secret is the developer-generated JWT.","kind":"official"},{"id":"email-relay","url":"https://developer.apple.com/help/account/configure-app-capabilities/configure-private-email-relay-service","title":"Configure private email relay service - Apple Developer Help","accessed":"2026-10-25","supports":"Register email domains or addresses; SPF check shown; SPF and/or DKIM required, envelope sender or DKIM d= must match the registered domain; unregistered sources bounce; required role Account Holder or Admin.","kind":"official"},{"id":"create-key","url":"https://developer.apple.com/help/account/keys/create-a-private-key/","title":"Create a private key - Keys - Account - Help - Apple Developer","accessed":"2026-10-25","supports":"Keys are created under Certificates, Identifiers & Profiles > Keys; saved as .p8; one download only; required role Account Holder or Admin.","kind":"official"},{"id":"guidelines","url":"https://developer.apple.com/app-store/review/guidelines/","title":"App Review Guidelines - Apple Developer","accessed":"2026-10-25","supports":"4.8 Login Services (apps using third-party login must offer an equivalent privacy-preserving option, with exceptions); 5.1.1(v) apps that support account creation must offer account deletion in the app.","kind":"official"},{"id":"adpla","url":"https://developer.apple.com/support/terms/apple-developer-program-license-agreement/","title":"Apple Developer Program License Agreement","accessed":"2026-10-25","supports":"You must safeguard keys and tokens associated with your developer account.","kind":"official"}],"allowed_domains":["developer.apple.com","appleid.apple.com"],"account_model":{"summary":"Everything sits inside one Apple Developer Program team: a primary App ID with the Sign in with Apple capability, one Services ID per web service (the OAuth client_id), and up to two private keys tied to the primary App ID. Domains and email sources are registered to the team's Team ID.","accounts":[{"name":"Apple Developer Program membership","kind":"developer","owned_by":"the company (or individual developer)","required":true,"note":"Organisations can register up to 100 website URLs per Services ID, individuals 10."},{"name":"Primary App ID (Sign in with Apple enabled)","kind":"project","parent":"Apple Developer Program membership","required":true},{"name":"Services ID","kind":"project","parent":"Primary App ID (Sign in with Apple enabled)","required":true,"note":"Used as client_id on the web."}],"notes":["Grouping related App IDs under one primary App ID means users consent once per group of apps and websites.","Users who hide their email get a private relay address; you can only email them from registered sources."]},"prerequisites":[{"entry":"apple/developer-program-org","note":"Any paid membership works; an organisation membership gets higher URL and email-source limits."},{"need":"The website domain(s) and exact HTTPS return URL(s) for your OAuth callback."},{"need":"Access to DNS for your sending domain if you will email relay users (SPF/DKIM)."}],"have_ready":[{"kind":"other","description":"Account Holder or Admin access to the Apple Developer account.","why":"Required to create keys and register email sources.","needed_for":["private-key","email-sources"],"auto_check":"none","source":"create-key"},{"kind":"live_website","description":"Your production domain(s) and absolute return URLs, e.g. https://example.com/auth/callback/apple.","why":"Each return URL must include scheme, host and path.","needed_for":["services-id"],"auto_check":"website_live","source":"configure-env"},{"kind":"other","description":"SPF (and ideally DKIM) records on the domain your transactional email is sent from.","why":"Apple's private relay only delivers authenticated mail from registered sources.","needed_for":["email-sources"],"auto_check":"dns_record","source":"email-relay"}],"steps":[{"id":"sign-in","title":"Sign in to Certificates, Identifiers & Profiles","summary":"Sign in to the Apple Developer account as Account Holder or Admin.","route":"guided","depends_on":[],"gate":"2fa","url":"https://developer.apple.com/account/resources"},{"id":"primary-app-id","title":"Enable Sign in with Apple on a primary App ID","summary":"Edit your app's App ID (or enable the capability in Xcode) and switch on Sign in with Apple as a primary App ID, or group it with an existing primary App ID for a related app.","route":"guided","depends_on":["sign-in"],"gate":"human_submit","url":"https://developer.apple.com/account/resources","sources":["configure-env"]},{"id":"services-id","title":"Create and configure a Services ID","summary":"Identifiers > + > Services ID; enter a description and unique identifier (e.g. com.example.web). Select it, tick Sign in with Apple, click Configure, choose the primary App ID, and enter your domains, subdomains and return URLs as a comma-separated list. Save. No verification file upload is needed.","route":"guided","depends_on":["primary-app-id"],"gate":"human_submit","url":"https://developer.apple.com/account/resources","recovery":[{"hiccup":"Apple rejects the sign-in request with a client or redirect error.","fix":"Check the client_id is the Services ID (not the bundle ID unless signing in from the app) and that the return URL matches a registered one exactly, including path. [to verify] exact error strings.","source":"configure-env"},{"hiccup":"You hit the website URL limit.","fix":"Individuals can register 10 URLs per Services ID, organisations 100. Enrol as an organisation or consolidate callbacks.","source":"web-config"}],"sources":["web-config","configure-env"]},{"id":"private-key","title":"Create a Sign in with Apple private key","summary":"Keys > +, name the key, tick Sign in with Apple, click Configure and choose the primary App ID. Confirm, then download the .p8 once and store it in your secret store. Each primary app can have at most two keys.","route":"guided","depends_on":["primary-app-id"],"gate":"human_submit","url":"https://developer.apple.com/account/resources","recovery":[{"hiccup":"The Download button is disabled and you have lost the file.","fix":"Create a second key (two allowed per primary app), move your server to it, then revoke the old key.","source":"configure-env"}],"capture":{"env":"APPLE_SIGNIN_PRIVATE_KEY","kind":"secret"},"sources":["create-key","configure-env"]},{"id":"client-secret","title":"Generate the client secret (JWT) on your server","summary":"Sign an ES256 JWT with kid = Key ID, iss = Team ID, iat = now, exp up to six months ahead, aud = https://appleid.apple.com, sub = the Services ID (case-sensitive). Send it as client_secret. Many auth libraries generate it for you from the key; otherwise put a reminder to regenerate it.","route":"guided","depends_on":["private-key","services-id"],"gate":"none","recovery":[{"hiccup":"Token requests start failing after months of working.","fix":"The client secret's exp has passed (maximum six months). Generate a new JWT; automate rotation.","source":"client-secret"},{"hiccup":"Client secret rejected immediately.","fix":"Check sub exactly matches the Services ID (case-sensitive), iss is the Team ID, kid is the key's ID and exp is not more than 15777000 seconds ahead.","source":"client-secret"}],"sources":["client-secret","rest-tokens"]},{"id":"email-sources","title":"Register outbound email sources for the private relay","summary":"Services > Sign in with Apple for Email Communication > Configure. Add your sending domains or exact addresses; the table shows whether each passed SPF. Make sure the envelope sender domain passes SPF or the mail is DKIM-signed for the From domain.","route":"guided","depends_on":["sign-in"],"gate":"human_submit","url":"https://developer.apple.com/account/resources","preflight":[{"rule":"dns_record_resolves","params":{"name":"{domain}","type":"TXT","value":"v=spf1"}}],"recovery":[{"hiccup":"Emails to users' private relay addresses bounce.","fix":"Register every sending domain or address and authenticate it with SPF and/or DKIM matching the registered domain exactly.","source":"email-relay"}],"optional":true,"sources":["email-relay"]},{"id":"notifications","title":"Register a server-to-server notification endpoint","summary":"Edit the App ID and add one HTTPS (TLS 1.2+) endpoint to hear when users change email forwarding or delete their Apple Account.","route":"guided","depends_on":["primary-app-id"],"gate":"human_submit","optional":true,"sources":["configure-env"]}],"outputs":[{"name":"APPLE_SIGNIN_CLIENT_ID","description":"The Services ID used as OAuth client_id on the web.","secret":false,"example_format":"com.example.web","from_step":"services-id"},{"name":"APPLE_SIGNIN_KEY_ID","description":"10-character Key ID of the Sign in with Apple private key (JWT kid).","secret":false,"example_format":"ABC123DEFG","from_step":"private-key"},{"name":"APPLE_SIGNIN_PRIVATE_KEY","description":"The .p8 private key used to sign client secrets. Secret.","secret":true,"example_format":"contents of AuthKey_<KEY_ID>.p8","from_step":"private-key"}],"terms_notes":[{"kind":"rules_say","severity":"amber","title":"Apple's docs say web use needs an App Store app","text":"Apple's configuration guide states that for users to authenticate with your web service you must have an existing app in the App Store that uses Sign in with Apple, and the Services ID must be tied to a primary App ID. \"[to verify] whether a published app is enforced for web-only use.\"","source":"configure-env"},{"kind":"rules_say","severity":"amber","title":"Third-party login in an iOS app needs an equivalent option","text":"Apps that use Google, Facebook, X or similar login for the primary account must also offer an equivalent login that limits data to name and email, lets users hide their email, and does not track for ads without consent - Sign in with Apple qualifies. Exceptions exist (own accounts only, enterprise/education, eID).","source":"guidelines"},{"kind":"rules_say","severity":"amber","title":"Account deletion","text":"If your app supports account creation it must offer account deletion within the app.","source":"guidelines"},{"kind":"rules_say","severity":"red","title":"Never share the private key","text":"Never share private keys outside your developer team. If one is compromised, create a new key, switch over, then revoke the old one.","source":"configure-env"}],"renewals":[{"what":"Client secret JWT (exp no more than six months ahead)","every":"6 months","every_days":180,"source":"client-secret"}],"pricing_notes":{"notes":"No separate price stated; requires an Apple Developer Program membership.","source":"configure-env"},"api_provisioning":{"available":"no","notes":"Services IDs, keys and email sources are configured in Certificates, Identifiers & Profiles on the web. \"[to verify] App Store Connect API coverage of Services IDs.\"","source":"web-config"}}}