storebound/skills/account-deletion/SKILL.md

5.1 KiB

name description
account-deletion Make account deletion pass App Store and Google Play review for an app with sign-up or sign-in - Apple Guideline 5.1.1(v) in-app deletion (the whole account, not deactivation; Sign in with Apple token revocation; subscription billing note), Google Play's in-app path plus a public web page declared in Data safety, the config (accounts.enabled, deletionUrl, inApp) and the storebound checks. Use when the app has accounts, when the user adds sign-up, or after a 5.1.1(v) / Play account deletion rejection.

Account deletion (both stores)

storebound scan finds sign-up and sign-in code (Firebase Auth, Supabase, Google / Facebook / Apple sign-in, custom endpoints) without a deletion path (5.1.1(v)) and accounts without accounts.deletionUrl (Play): run it after adding deletion.

Applies to every app that lets people create an account (email, phone, social sign-in, Sign in with Apple). Games without accounts can skip it. Sources: Apple, "Offering account deletion in your app" (https://developer.apple.com/support/offering-account-deletion-in-your-app/) and App Review Guideline 5.1.1(v) (https://developer.apple.com/app-store/review/guidelines/); Google Play, "Understanding Google Play's app account deletion requirements" (https://support.google.com/googleplay/android-developer/answer/13327111).

What the stores require

  • Apple 5.1.1(v): people can start deleting their account inside the app, easy to find (e.g. Settings > Account > Delete account). Delete the whole account and its personal data, not only deactivate it. A link to a web page that completes the deletion is fine; "email or call us" is only acceptable in highly regulated industries. With Sign in with Apple, revoke the user's tokens (Sign in with Apple REST API). With auto-renewable subscriptions, tell people that billing continues through Apple until they cancel, and how to cancel.
  • Google Play: if the app lets people create an account, it must offer deletion in the app and on a web page people can reach without the app (no reinstall needed). The URL goes into the Data safety form ("Data deletion"). People can also ask to delete some data without deleting the account; say how.

Steps

  1. Config: accounts: { enabled: true, deletionUrl: 'https://example.com/delete-account', inApp: 'Settings > Account > Delete account' }. storebound check errors without deletionUrl (Play) and warns without inApp (Apple); storebound apple review-details adds "Account deletion: " to the review notes.
  2. Web page at deletionUrl: names the app and developer, the steps to request deletion (sign in, or a form that verifies the email), what is deleted and what is kept (and for how long, e.g. invoices for tax law), and how long it takes. No login wall to read it. storebound validate --play checks that it answers.
  3. In the app: a clear entry, a confirmation step, then the deletion (or the web page). Sign people out afterwards.
  4. Play Data safety: accountCreation set to the sign-up methods you offer (not PSL_ACM_NONE). Say how people sign up in accounts.signUp and storebound scan proposes it: username (a name picked in the app, no password, no email; a server token on the device) is Play's "Username and other authentication" (PSL_ACM_USER_ID_OTHER_AUTH) with User ID as the only account data; username-password and email-password are "Username and password" (PSL_ACM_USER_ID_PASSWORD); email-link and phone are PSL_ACM_USER_ID_OTHER_AUTH; oauth is PSL_ACM_OAUTH; other is PSL_ACM_OTHER. An account alone never means an email address: declare Email only when the app asks for one. With accounts Play requires more rows, and storebound writes them: the delete-account URL (PSL_ACCOUNT_DELETION_URL = accounts.deletionUrl) and "Do you provide a way for users to request that their data is deleted?" (PSL_SUPPORT_DATA_DELETION_BY_USER, a single choice). The delete-account page is such a way, so the answer is yes (DATA_DELETION_YES); answering no next to a delete-account URL contradicts it and check flags it. The yes needs a "Delete data URL" (PSL_DATA_DELETION_URL): dataSafety.partialDeletionUrl when there is a page that deletes data without deleting the account (partialDeletion: true), else the delete-account page. storebound check and play data-safety --dry say missing: <id> (... set <field>) for any of them; without them Play answers 400 "Response missing for PSL_ACCOUNT_DELETION_URL". Play removed the old "users can request deletion" question, so dataSafety.deletionRequest is no longer used (check notes it; remove it).
  5. Privacy policy: a "Deleting your account" section with both paths (privacy-policy skill).
  6. Test it on a fresh account before every submission; the reviewer will.

Gotchas

  • "Deactivate" or "contact support" is not deletion for Apple.
  • Deleting the account does not cancel a store subscription: say so in the app and on the web page.
  • Keep the in-app path, the web page, Data safety and the privacy policy saying the same thing.