You added Sign in with Apple and Google sign-in to an app that Cursor, Lovable, Bolt, or FlutterFlow scaffolded for you. The build went up to TestFlight, and Apple rejected it under Guideline 5.1.1(v) with the note that the app supports account creation but does not include an in-app option to initiate account deletion. This page is for the developer who needs to ship a working fix in the next day.
Short answer
Apple's Guideline 5.1.1(v) treats a Sign in with Apple, Google, or Facebook account as a created account, so the in-app deletion requirement applies the same way it applies to an email signup. Per Apple's support page on offering account deletion, in force since June 30, 2022, the delete control must live inside the app, must remove the account record and associated personal data, and (for Sign in with Apple) must revoke the user's Apple tokens through the REST API.
What you should know
- A social login still counts as account creation. The trigger is the user record in your auth provider, not the method by which it was created.
- Sign in with Apple has an extra requirement. The Sign in with Apple REST API revoke tokens endpoint must be called during deletion if you hold a refresh or access token.
- Reviewers test by signing in, deleting, and signing in again. A sandbox account that comes back with its data intact will fail review.
- The Delete Account entry must be reachable in Settings. A mailto link, a website redirect, or a flow that hides behind a re-login does not pass.
- Guest and anonymous sessions are in scope. Firebase anonymous users and Supabase anonymous sign-ins also need a delete path.
- AI scaffolds rarely add the revoke call. They wire up the OAuth button and the user row, then stop because the prompt did not ask for more.
Why does 5.1.1(v) trigger on social login at all?
The literal text in Guideline 5.1.1(v) reads: "If your app supports account creation, you must also offer account deletion within the app." The supporting Apple support article on offering account deletion clarifies that the requirement is triggered by account creation, period. It does not enumerate authentication methods. The trigger is the existence of a user record that the app or its backend can identify the user by.
That covers every common social login path. A Sign in with Apple flow that returns a credential, exchanges it at your backend, and creates a row in auth.users is account creation. A Google sign-in handled through Firebase Authentication that creates a uid is account creation. A Facebook login through your custom backend that issues a session is account creation. The deletion gate applies in all three.
The support article also addresses a question developers ask often: if the app links out to a browser to handle authentication, does the deletion requirement still apply? Apple answers yes, and the answer does not change when the link out is to Apple, Google, or Facebook. The path back into your app to start deletion has to be present.
What does the rejection notice from App Review usually look like?
The standard rejection message in App Store Connect Resolution Center reads, in essence: Guideline 5.1.1, Legal, Privacy, Data Collection and Storage. The app supports account creation but does not include an option to initiate account deletion. Please revise your app to include a mechanism for account deletion. Account deletion must result in the deletion of the user's account from the app developer's records along with any data associated with the account.
When the rejection cites social login specifically, the reviewer note often adds that the app offers Sign in with Apple or another third-party provider, and that the Delete Account flow either is missing, only signs the user out, or directs the user to an external website. The phrasing has been stable since the June 30, 2022 enforcement date Apple announced in Developer News.
Three review patterns reliably trigger the rejection on a social-login app. First, the Settings screen carries a Sign Out button and no Delete Account row. Second, the Delete Account row calls signOut on the local session but leaves the row in the database, so the reviewer can sign back in with the same Apple ID and find their data intact. Third, the Delete Account row opens a webview, an email composer, or a customer-support page instead of completing the deletion in the app.
What does the Sign in with Apple revoke flow actually look like?
If your app offers Sign in with Apple, the Apple support page on offering account deletion requires a call to the Sign in with Apple REST API's revoke endpoint. The endpoint is POST https://appleid.apple.com/auth/revoke. The body carries client_id (your bundle identifier or service identifier), client_secret (a signed JWT generated with your team key), token (the user's refresh token or access token), and token_type_hint set to refresh_token or access_token.
The signed JWT is the same one used to validate Sign in with Apple authorization codes at sign-in, so most apps that already integrated the REST API have the generation code in place. If you only verified the identity token client-side and never called /auth/token at sign-in, you do not hold a refresh token. The next section covers that case.
A successful revoke returns HTTP 200 with an empty body. Per Apple's technote TN3194 on handling account deletions, calling revoke is functionally equivalent to the user toggling "Stop using Apple ID" in iPhone Settings, Password & Security, Apps using Apple ID.
What if I never stored the Apple refresh token?
This is the common situation in AI-coded apps. Cursor and Lovable scaffolds that connect Sign in with Apple to Supabase or Firebase usually verify the identity token client-side, exchange it for a Supabase or Firebase session, and discard the original authorization code without ever calling Apple's /auth/token endpoint. The refresh token never reaches your server.
Apple Developer Technical Support has published a workaround in the developer forums thread linked from TN3194. The short version: you still must delete the user's data on your end, and you still must inform the user that to fully revoke Apple's link they need to open iPhone Settings, tap their Apple ID, select Sign in with Apple, find your app, and choose Stop Using Apple ID. Showing this guidance during the deletion flow satisfies the requirement when no token is available.
For new sign-ins from that point on, the recommended pattern is to capture the authorization code on the client, send it to a server function, call Apple's /auth/token endpoint, and store the returned refresh token against the user record. The next time the user deletes, the revoke call works without manual steps.
| Provider | Revoke method | Where it runs |
|---|---|---|
| Sign in with Apple | POST /auth/revoke with refresh token and client secret JWT | Server or edge function |
| Google Sign-In | GIDSignIn.sharedInstance.disconnect on iOS plus server OAuth state clear | Client and server |
| Facebook Login | LoginManager.logOut plus a delete-permissions Graph API call | Client and server |
| Supabase auth user | supabase.auth.admin.deleteUser(userId) with the service role | Edge function |
| Firebase auth user | admin.auth().deleteUser(uid) from the Admin SDK | Cloud function |
How do you wire the in-app delete entry without breaking review?
The shortest path that reviewers consistently accept is a Delete Account row in Settings that opens a confirmation modal, then calls a single backend function. The backend function does the privileged work that cannot run safely from the client:
- Look up the user's Apple refresh token if Sign in with Apple was used, and call
/auth/revoke. - Clear any Google or Facebook tokens cached on the device and call the relevant provider sign-out.
- Delete the auth user through the Supabase or Firebase Admin SDK.
- Delete the dependent rows via
ON DELETE CASCADEforeign keys or explicit deletes inside the same transaction. - Sign the local session out and route the user back to the launch screen.
The service role or Admin SDK key never ships in the binary. If it does, your build has a separate problem covered elsewhere on PTKD.com (https://ptkd.com).
For active App Store subscriptions, follow the support page guidance: on iOS 15 and later, call showManageSubscription from StoreKit 2 before the deletion completes, and present a short notice that App Store billing continues until the user cancels through Apple. On older targets, link to https://apps.apple.com/account/subscriptions. Reviewers want to see the user told about billing, they do not require you to cancel the subscription on the user's behalf.
What to watch out for
A few patterns derail otherwise correct submissions.
The Apple token revoke call silently fails when the client secret JWT has the wrong audience claim or has expired. Per Apple's reference on generating and validating tokens, the audience must be https://appleid.apple.com and the JWT lifetime cannot exceed six months. A 400 response from /auth/revoke with invalid_client usually means the JWT failed validation; reviewers do not see that error, but a returning user who can still sign in does.
The Delete Account row is sometimes hidden behind a re-authentication wall that prompts for the original provider. Reviewers running on test Apple IDs do not always complete that re-auth, especially when it bounces back to a browser. Keep the confirmation in-app and avoid re-auth unless your threat model genuinely calls for it.
Guest deletion is forgotten. AI scaffolds that combine Sign in with Apple with optional anonymous sessions often expose Settings only to signed-in users. A reviewer who launches the app, taps "Continue without signing in", and then looks for a delete control finds nothing. The Apple support article puts automatically generated accounts in scope, so the control must exist for guests too.
The mailto-link compromise. A button that opens an email composer to [email protected] is the support flow that Apple explicitly disallows for non-regulated apps. Highly regulated industries get a carve-out under Guideline 5.1.1(ix); a Lovable or FlutterFlow consumer app does not.
Key takeaways
- Account creation is the trigger for 5.1.1(v), not the authentication method. Treat Sign in with Apple, Google, and Facebook the same as an email signup.
- Sign in with Apple adds a mandatory
/auth/revokecall. If you do not hold a refresh token, follow TN3194's manual workaround and start storing the token on the next sign-in. - The Delete Account control belongs in Settings, in-app, reachable to guests, and must remove the row, not the session.
- Tell the user that App Store billing is separate before deletion, using
showManageSubscriptionor the manage subscriptions URL. - Some teams outsource the build-side check by running their compiled IPA through PTKD.com (https://ptkd.com), which scans for missing Sign in with Apple revoke wiring and other 5.1.1 patterns before submission.




