Sign in with Apple Server to Server Notification Documentation
This video has some info, but not enough. Would love a documentation page equivalent: https://developer.apple.com/videos/play/wwdc2020/10173/.
I assume that this could/should be used to remove users from firebase (and our own database) if they decide to stop using their apple id to sign into our app.
This is not happening automatically and might cause a strange user experience if the user comes back to the app and is still logged in (or able to login).
It would still be nice to have some Apple docs reflecting this. Feels like I'm kinda operating in the blind.
Endpoint
The endpoint for the notifications can have any path desired. It's a POST request sending JSON. HTTPS is required. There is no authentication. Events are sent as signed JWTs using the OIDC JWS keys for verification.Body
The body is a simple json structure:Code Block { "payload": "<event Token>" }
Event Token Structure
Code Block { "iss": "https://appleid.apple.com", "aud": "<app id>", "exp": 1611852260, "iat": 1611765860, "jti": "<token id string>", "events": "<Event String>" }
The aud field will be the corresponding backend App ID for the source of the emission.
The events field is stringified json. So far I've only seen a single object, but based on the name an array doesn't seem impossible.
General Event Structure
Code Block { "type": "<event type>", "sub": "<apple user id>", "event_time": 1611765847700 }
Some event types have additional fields.
Event Types
Here are the events I've received so far.email-enabled
Sent when user enabled receiving email from service.
Additional Fields:
email - user's email
is_private_email - is the email an apple email proxy email.
Sent when a user disables email sending through the proxy.
Additional Fields:
email - user's email
is_private_email - is the email an apple email proxy email.
Sent when consent for using the application is revoked.
No additional fields.
Processing Changes for Sign in with Apple Accounts
We are also facing the same issues while trying to integrate.
The documentation leaves out too many questions unanswered and we have to rely on the community and third-party information in order to implement anything to start with and yet, a lot of try-n-error will be coming up most likely. Simply the fact that we have to search for answers outside of Apple's documentation has already made us 3 times the time we originally had planned for this integration.
The following is a review of the current documentation at Processing Changes for Sign in with Apple Accounts, respecting all pages it links to.
Overview
These notifications are JSON Web Tokens (JWTs) ...
This is wrong. The content seems to be a JSON object with only one field named payload
which contains the actual JWT.
Set Up the Endpoint URL
All JWTs arrive at the same endpoint URL.
What exactly is meant by "all" here?
The following information from Enabling Server to Server Notifications may have an impact here:
A Server to Server endpoint URL can only be registered on a primary App ID.
Combining those two, my interpretation of the sentence would be:
Notifications for all apps within the same App Group, identified by the primary App ID, arrive at the same endpoint URL.
That would clarify it a lot from the beginning, including resulting limitations.
Also:
Your server examines the JWT and performs work according to the type in the events array in the token.
What do you mean by "examine"? I am pretty sure you're talking about Validating a JWT, but it would be really helpful to use industry standards terminology to avoid uncertainty at the readers side.
Additionally, the events
is not an array, so that is misleading information here.
Open Questions:
- Which HTTP method will be used by Apple? Community says it is
POST
. - Which concrete structure does the request body have?
- How stable is the request body structure?
- Which values will request header
Content-Type
have? - Will request header
Content-Length
be correctly set? - How large can the request body get?
- Is there a list of IPv4/v6 addresses or CIDRs available for allow-listing Apple servers as valid clients to this endpoint?
- Can Apples clients be reliably reverse-resolved via DNS to allow maintaining a dynamic allow-list?
- Which requirements need to be met by the endpoint response?
- Which HTTP status codes are respected by Apple?
- How does it behave in case of a
503
or other5xx
status codes? - Does it follow redirects?
- What is the timeout for a request and how does Apple react in case of exceeding it?
- Is there any chance that Apple will refuse to send notifications to a specific endpoint URL and what are possible reasons?
- From where to get public keys for signature validation?
Would also be nice if there was some reference to the fact that AppleID (at least at the moment) conforms to the OpenID Provider Configuration (see https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig - fun fact: this forum blocks URL's for openid.net, maybe because of previous debates) by providing the following well-known location:
That tells us the location of the JWK Set for getting the public keys as well.
Examples
In section Process a User’s Email Forwarding Change we can see the following example (note the JSON syntax bug - I hope we won't see such things in real life):
{
"iss": "https://appleid.apple.com",
"aud": "com.mytest.app",
"iat": 1508184845,
"jti": "abede...67890",
"events": [
{
"type": "email-enabled",
"sub": "820417.faa325acbc78e1be1668ba852d492d8a.0219",
"email": "ep9ks2tnph@privaterelay.appleid.com",
"is_private_email": "true"
"event_time": 1508184845
}
]
}
Now, according to the example that @MikeNV provided and from other community sources that is simply wrong, since the events
claim is a string and not a JSON array.
Open Questions:
- Will claim
iss
always behttps://appleid.apple.com
? - Is claim
aud
an App ID? If so:- Will it contain the concrete App ID?
- Will it contain the primary App ID? If so:
- How do we determine the specific app related to the notification?
- If
events
is a string, how to parse it correctly?- Is it just plain serialized JSON?
- Is it base64 (URL-safe) encoded JSON?
- Is the decoded JSON guaranteed to be a single object?
- Which fields will events contain and what do they mean (apart from the incomplete examples provided)?
- Which values can the event
type
have and what do they refer to?
The situation is even worse.
On https://developer.apple.com/documentation/sign_in_with_apple/processing_changes_for_sign_in_with_apple_accounts Apple is stating, that "account-delete" is sent as a type in case a user deleted his or her apple id. The event type we actually saw in production was "account-deleted".
While we of course can't be sure if it is actually a typo, or some additional undocumented event type, I assume that this is a typo in the documentation.