# Family Sharing entitlements handled

- **Pattern:** `ab-000408` (`app-store-iap-subscriptions.restore-entitlements.family-sharing`)
- **Severity:** low
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000408
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000408)

## Why it matters

When Family Sharing is enabled for an IAP subscription in App Store Connect, up to five family members share the entitlement. A family member's receipt carries `inAppOwnershipType == .familyShared` rather than `.purchased`. Apps that validate receipts without handling this ownership type will incorrectly deny access to paying family members — users who legitimately share the subscription but are treated as non-subscribers. Apple's Family Sharing IAP documentation specifies that apps must handle `FAMILY_SHARED_MEMBER_JOINED` App Store Server Notification v2 events when Family Sharing is enabled. The check is low severity because Family Sharing is disabled by default and most apps do not enable it.

## Severity rationale

Low because it only applies when Family Sharing is explicitly enabled in App Store Connect, which is not the default configuration for most apps.

## Remediation

If you enable Family Sharing in App Store Connect, update your entitlement validation to accept the `familyShared` ownership type in addition to `purchased`.

```swift
// StoreKit 2 — Swift
for await transaction in Transaction.currentEntitlements {
  if case .verified(let tx) = transaction {
    let isOwnerOrFamily = tx.ownershipType == .purchased || tx.ownershipType == .familyShared
    if isOwnerOrFamily { unlockPremium() }
  }
}
```

For RevenueCat users: Family Sharing is handled automatically — no extra code required. For custom App Store Server Notification v2 webhook handlers (`POST /api/apple/notifications` or equivalent), add a handler branch for the `FAMILY_SHARED_MEMBER_JOINED` notification type to grant access to the family member's user record.

## Detection

- **ID:** `family-sharing`
- **Severity:** `low`
- **What to look for:** Count all relevant instances and enumerate each. Determine if Family Sharing is enabled for the app's IAP products (Apple's Family Sharing allows up to 5 family members to share a subscription). Look for Family Sharing signals: `isFamilyShareable` in StoreKit 2 `Product` objects, RevenueCat entitlement handling documentation, or any code that handles the `FAMILY_SHARED_MEMBER_JOINED` App Store Server Notification v2 event. If Family Sharing is enabled in App Store Connect, the app must handle entitlements for family members who did not initiate the purchase — their receipt will have `inAppOwnershipType == .familyShared`. Check if the entitlement validation flow accounts for this ownership type.
- **Pass criteria:** Family Sharing is not enabled (skip), or if enabled, the entitlement flow handles `familyShared` ownership type correctly. At least 1 implementation must be verified.
- **Fail criteria:** Family Sharing is enabled in the app but the entitlement validation code only accepts `PURCHASED` ownership type, causing family members to be incorrectly denied access.
- **Skip (N/A) when:** Family Sharing not enabled for any IAP products (most common case — default is disabled), or using Android only (Google Play Family Library has different mechanics handled differently), or cannot be determined from codebase alone.
- **Detail on fail:** `"App Store Server Notifications handler in api/apple/notifications.ts does not handle FAMILY_SHARED_MEMBER_JOINED event type despite Family Sharing enabled for subscription product"`
- **Remediation:** If you enable Family Sharing in App Store Connect, verify your entitlement flow:
  1. RevenueCat handles family sharing automatically — no extra code needed
  2. For custom validation, check `inAppOwnershipType` in the signed transaction:
     ```swift
     // StoreKit 2
     for await transaction in Transaction.currentEntitlements {
       if case .verified(let tx) = transaction {
         let isOwnerOrFamily = tx.ownershipType == .purchased || tx.ownershipType == .familyShared
         if isOwnerOrFamily { unlockPremium() }
       }
     }
     ```

## External references

- external apple-family-sharing-iap — https://developer.apple.com/documentation/storekit/in-app_purchase/supporting_family_sharing_in_your_app

Taxons: access-control

HTML version: https://auditbuffet.com/patterns/ab-000408
