This document summarizes differences between Sign in with Apple (SIWA) and OpenID Connect (OIDC) and OAuth 2.0 standards. It notes several ways SIWA specifications and behaviors deviate from or violate OIDC standards, including not supporting standard authentication methods, response types, and claims. It also describes SIWA's characteristic identifier design which links multiple apps and services from the same developer together under a single user consent. Developer teams are limited to 10 linked apps/services and must create a new team for additional apps.
7. OIDC Spec Violations
❖ when nonce is provided in the code or code id_token grant types, it won’t be
included in the id_token returned #FIXED
❖ the code id_token response type does not include c_hash in the returned
id_token #FIXED
❖ the code id_token response type returns the response parameters as query
parameters, not in the fragment
❖ providing a prompt parameter with any value (e.g. login or consent) or empty
results in a 400 with no body #FIXED
❖ when max_age is requested, the id_token does not include an auth_time
claim #FIXED
http://bit.ly/diff-between-siwa-and-oidc
8. Peculiarities (奇妙な点)
❖ no Discovery document is published at https://appleid.apple.com/.well-known/openid-
configuration which makes developers have to read through the Apple docs to find out
about endpoints, scopes, signing algorithms, authentication methods, etc. #FEELS-OK
❖ no User Info endpoint is provided which means all of the claims about users have to be
included in the (expiring and potentially large) id_token
❖ does not include different claims in the id_token based on scope #PARTIALLY-FIXED
❖ the token endpoint does not accept client_secret_basic as authentication method
(required for OpenID Connect certification) and actually the default method to use for
Clients when there’s no Discovery document that says otherwise
http://bit.ly/diff-between-siwa-and-oidc
9. Peculiarities (奇妙な点)
❖ authentication towards the token endpoint requires a (custom) JWT assertion as a
client_secret in a client_secret_post authentication method whereas the more
appropriate private_key_jwt authentication method as defined in RFC7523 could have
been used
❖ using unsupported or wrong parameters (e.g. non-existing response_type, scope,
client_id, or redirect_uri) always results in the same message in the browser that says
“Your request could not be completed because of an error. Please try again later.”
without any explanation about what happened, why this is an error or how to fix it
#FEELS-OK #EXCEPT-FOR-SCOPE
❖ exchanging the authorization code according to https://developer.apple.com/
documentation/signinwithapplerestapi/generate_and_validate_tokens should present
a non-standard grant_type=authorization_token but using the standards-compliant
grant_type=authorization_code actually works whereas the former does not, so the
documentation is incorrect #FIXED
http://bit.ly/diff-between-siwa-and-oidc
10. Peculiarities (奇妙な点)
❖ the Authorization Code grant type (for public Clients?) does not use PKCE to avoid
code injection and code replay attacks #FEELS-OK
❖ when using the sample app available at https://github.com/aaronpk/sign-in-with-
apple-example, adding openid as a scope leads to an error message and it works just
with name and email as scope values; this behavior seems to be inconsistent across
Clients: for some it works, or at least does not lead to errors, for others it does not
work and ends with an error #FIXED?
❖ The scope value of only the very first request by an application is respected. If an
application initially requests only the name scope, and the user allows it, it is then
impossible to later also request the email scope.
http://bit.ly/diff-between-siwa-and-oidc
18. User ID (sub)
Team X
Primary App A
App A-3
App A-2
App A-1
Service A-1
Service A-2
Primary App B
App B-2
App B-1
Service B-1
19. Private Email
Team X
Primary App A
App A-3
App A-2
App A-1
Service A-1
Service A-2
Primary App B
App B-2
App B-1
Service B-1
20.
21.
22. User ID :
Apple User ID :
Public Emails :
Private Email :
12345
000123.abc2xyz.0012
foo@icloud.com
foo@me.com
for-team-x@privaterelay.appleid.com
Q1. Which address to use in each app’s context?
Q2. How to handle email changes after revocation?
23. Consent Screen
Team X
Primary App A
App A-3
App A-2
App A-1
Service A-1
Service A-2
Primary App B
App B-2
App B-1
Service B-1
24. Revocation Screen
Team X
Primary App A
App A-3
App A-2
App A-1
Service A-1
Service A-2
Primary App B
App B-2
App B-1
Service B-1
29. Client ID
Team X
Primary App A
App A-3
App A-2
App A-1
Service A-1
Service A-2
Primary App B
App B-2
App B-1
Service B-1
30. Private Key
Team X
Primary App A
App A-3
App A-2
App A-1
Service A-1
Service A-2
Primary App B
App B-2
App B-1
Service B-1
31. CLIENT_ID is of the app / service which originally received the
authorization code, not of the backend server which accesses the token
endpoint, even when refreshing tokens.
32. Private Email Relay Service
Team X
Primary App A
App A-3
App A-2
App A-1
Service A-1
Service A-2
Primary App B
App B-2
App B-1
Service B-1
34. For the 11th domain / address, setup new team !?!?
Primary App A sends emails from
App A-1 sends emails from
App A-2 sends emails from
Service A-1 sends emails from
no-reply@primary-app-a.example.com
no-reply@app-a1.example.com
no-reply@app-a2.example.com
no-reply@service-a1.example.com
: