Sansan Tech Blog

Sansanのものづくりを支えるメンバーの技術やデザイン、プロダクトマネジメントの情報を発信

アプリ開発者が Privacy Manifests 対応でやることについて調べてみた

はじめに

こんにちは。技術本部 Mobile Application グループで iOS アプリエンジニアをやっている多鹿です。

さて、 WWDC 2023 にて Privacy Manifests が発表されましたね。そして、2024年春にはこの対応がされていないアプリはリジェクト対象になるというではありませんか。
ある日突然リジェクトされて慌てたくはないので、事前にどのような対応が必要か調べてみました。

Privacy Manifests とは?

WWDC 2023 にて発表されたプライバシーに関する機能です。これまでもアプリ内でのプライバシー情報の扱いに関してはユーザに対して明確になるように求められてきました。Privacy Manifests によって Third-party SDK も含めてより透明度を上げるような要件が追加されます。

これまで App Store Connect 上でもアプリが扱うプライバシーデータはユーザに分かるように明確に設定していましたが、Privacy Manifests ではそれらをファイルとして定義するようになります。

また、前述の通り、2024年春以降に Privacy Manifests への対応が審査観点として追加され、要件を満たさないアプリを審査に出した場合はリジェクト対象となります。(審査時に見られるものなので、既にストアに出ているアプリに対する影響はなさそうです。)

そして、それだけでなく Apple Developer Program License Agreement にも Privacy Manifests に関連する要件が追加されています。この対応を適切に行うことは開発者の責務であり、対応しないことは Apple Developer Program License に違反することになってしまいます。

アプリ開発者がやるべきこと

ということで、アプリ開発者として何をやるべきかを調べてみました。

最初にお断りを、、

まずお断りとなりますが、本記事の執筆時点において Apple から公開されている情報には明瞭さに欠ける部分があり、解釈の幅が持てるような状態となっています。
そのため、誤った解釈を含む可能性があることをご了承ください。
また、執筆内容は調査内容の共有のみであり、実際に調査内容をアプリに反映させて審査に提出するには至っておりません。

本記事における解釈について

前置きが続き申し訳ないですが、前述のように明瞭な解釈をしづらい状況の中で執筆しているため、本記事で筆者が情報をどのように解釈するのかについて先に述べておきます。

本記事では公開情報の内容を 悲観的に*1 捉えて、やるべきことを整理します。
例えば、公開情報から得られる情報の中で対応事項が OPTIONAL なのか MUST なのか判断つきづらい場合は MUST と捉えます。
この解釈の仕方のトレードオフとして、 OPTIONAL だった場合、本来不要だった過剰な対応に工数を割いてしまうことが挙げられますが、楽観的に捉えて MUSTOPTIONAL と誤解釈してしまう場合のリスクの方が大きいと判断してこのように捉えることとしました。

やるべきことの概要

アプリ開発者がやるべきことは大きく分けて 2つ です。

  1. アプリ側で Privacy Manifests の宣言をする
  2. アプリが利用している Third-party SDK を Privacy Manifests 対応バージョンにアップデートする

それぞれについて見ていきましょう。

1. アプリ側で Privacy Manifests の宣言をする

アプリのプロジェクトに PrivacyInfo.xcprivacy というプロパティリスト形式のファイルを作成し、そこに必要な情報を宣言します。

Privacy Manifests ファイルの作成

ファイルの作成方法についてはドキュメントや他の第三者の方の記事でも触れられており、それほど難しくもないのでここでは割愛します。
注意点としてはファイル名は PrivacyInfo.xcprivacy から変えてはいけないということと、Xcode 15 以降でないと作成できないくらいかなと思います。

developer.apple.com

この PrivacyInfo.xcprivacy には次の 4つのキーを宣言します。

  1. NSPrivacyTracking
  2. NSPrivacyTrackingDomains
  3. NSPrivacyCollectedDataTypes
  4. NSPrivacyAccessedAPITypes

Xcode 上での PrivacyInfo.xcprivacy の見え方のサンプル

それぞれのキーがどういったものかを見てみましょう。

NSPrivacyTracking
  • データ形式
    • ブール値

App Tracking Transparency framework で追跡データとして定義されているデータを使用する場合は true にします。
広告ID (IDFA) を利用している場合などは true にする必要がありそうです。

NSPrivacyTrackingDomains
  • データ形式
    • 文字列の配列

上記 NSPrivacyTracking を true にしている場合に記載が必要になる項目です。
トラッキングを行うインターネットドメインの文字列を配列で列挙します。
また、 App Tracking Transparency framework を通じてユーザからトラッキングの許可を得られなかった場合、ここに記載したインターネットドメインへの通信はブロックされ、エラーとなります。

ドキュメントの記載の通りだとすると、例えば、自社サーバーへトラッキングデータを送っており、トラッキング API のエンドポイントのドメインとサービスの機能 API のエンドポイントを同一ドメインで扱っている場合は注意が必要かもしれません。
ユーザがトラッキングを拒否した場合にトラッキングの API への通信と同時に機能 API への通信もブロッキングされ、トラッキングとは関係ない機能まで利用できなくなる可能性があります。
上記のようなケースでは、トラッキング用のドメインと機能 API のドメインを分ける方が良いかもしれません。 例えば、トラッキング API のドメインを tracking.example.com とし、機能 API のドメインを api.example.com とすることでトラッキングを拒否しても通信がブロックされるのは tracking.example.com の方だけなのでアプリの機能 API は利用できるはずです。

下記記事にも詳しく紹介されているので併せてご確認ください。

www.branch.io

また、執筆時点ではトラッキングを拒否しても列挙したドメインへの通信がブロックされないというレポートが上がっており、まだまだ情報が錯綜していそうです。

NSPrivacyCollectedDataTypes
  • データ形式
    • 辞書の配列

アプリおよび Third-party SDK が収集するデータタイプを記述します。
この項目に関しては、新しい話ではなく、すでに App Store Connect 上で管理しているプライバシーデータ相当のものをこちらに記載することになります。

App のプライバシーの管理 - App 情報の管理 - App Store Connect - ヘルプ - Apple Developer

例えば、Sansan の iOS アプリは App Store 上でユーザからは次のようなものが見えていると思いますが、開発者としては App Store Connect 上でこれらの値を設定しています。

Sansan iOS アプリの App Store 上でのプライバシー項目の見え方

この設定を PrivacyInfo.xcprivacy のこの NSPrivacyCollectedDataTypes 項目で記載していきます。

App Store Connect の GUI 上で設定できる項目に対応するプロパティリストの Key-Value が定義されているので、その定義と既存の App Store Connect の設定を見ながらマニフェストファイルを作成するとよさそうです。

ここでは、 App Store Connect の既存の定義を参考にして Privacy Manifests を作成するという手段を紹介しました。しかし、そもそもの Apple の意図としては「Privacy Manifests をメンテナンスすることで App Store Connect 上の値をより正確に更新していけ」というものです。したがって、作成後は Privacy Manifests の更新とともに App Store Connect の設定も更新しましょう。

ちなみにですが、現時点で Privacy Manifests の値を App Store Connect の設定に自動で反映してくれるような機構は残念ながらなさそうなので、 Privacy Manifests 導入後もこれまで通り手動で App Store Connect の値を更新する必要があります。

それでは既存の App Store Connect の設定と Privacy Manifests の二重管理になるだけでは?と思いますが、 Privacy Manifests のメリットとしては、Third-party SDK の Privacy Manifests の内容も含めて App Store Connect に設定すべきプライバシーデータの内容を PDF 出力してくれる点にあります。
これまで Third-party SDK が収集するデータに関しては、アプリ開発者が調べて App Store Connect に反映させる必要がありました。一方 Privacy Manifests 導入後は、Third-party SDK が収集するデータは Third-party SDK 開発者が用意した Privacy Manifests に書かれており、アプリ開発者はアプリ側の Privacy Manifests の情報とマージされたものを出力できます。これによって App Store Connect への設定において抜け漏れが少なくなることが見込まれます。

NSPrivacyAccessedAPITypes
  • データ形式
    • 辞書の配列

理由が必要な API (Required reason API) を使用している場合、どの種類の API を利用しているかと、どういった理由で利用しているかを既定のリストから選択します。

Apple が列挙している API はいずれもユーザ特定の一助となるような、フィンガープリントとして利用され得るものになるので、用途を明確に宣言する必要があります。

これらの API の中でも多くのアプリ開発者にとってインパクトがあるのが UserDefaults の利用かと思います。 UserDefaults では AppleKeyboards というキーでキーボードの情報が入手でき、こういった情報がフィンガープリントとして利用できるようです。したがって、利用用途を宣言する API として含まれているようです。

ということで多くのアプリ開発者にとって影響がありそうな UserDefautls は利用理由の選択肢を取り上げてみようと思います。

利用理由 説明
CA92.1 一般的にアプリ内の情報を永続化する目的で利用している場合はこちらで良さそうです。
1C8F.1 上記の利用に加え、Extension や 同じ App Group の別アプリに情報を共有している場合はこちらになりそうです。
C56D.1 これはアプリ開発者にはあまり関係なさそうです。Third-party SDK 開発者が SDK 利用者に UserDefautls のラッパーを提供する場合に選択するようなものになります。
Privacy Manifests 発表当初はこの理由は用意されていませんでした。Flutter の issue などでも言及されており、こういったフィードバックをもとに追加されたものと考えられます。
AC6B.1 MDM の設定でアプリの挙動を制御するようなアプリはこちらを選択します。
Sansan の iOS アプリも MDM の情報を取得して挙動を変える機能を有しているのでこちらを選択する必要がありそうです。

ちなみに、選択肢は複数選択可能なようなので、用途が複数あれば該当するものを全て選択することになりそうです。

2. アプリが利用している Third-party SDK を Privacy Manifests 対応バージョンにアップデートする

次に、アプリが利用している Third-party SDK のアップデートを行います。

アプリ開発者は、自身が作成する機能はもちろんのこと、アプリが利用する Third-party SDK の利用でもユーザのプライバシーを守る責任を負います。
つまり、Third-party SDK がプライバシーデータを利用するような機能を有している場合でも、それを利用するアプリ開発者が把握した上で適切にユーザから許可を得る必要があるということです。
そのため、利用している Third-party SDK についても今回の Privacy Manifests 対応がされたバージョンにアップデートする必要があります。

また、2023年12月7日に Apple から「一般的に使用される Third-party SDK」が公表されました。

developer.apple.com

これらの SDK とそれ以外の Third-party SDK では少し条件が違ってきそうなので、別で見ていきます。

Apple が公表した「一般的に使用される Third-party SDK」について

SDK 開発者の対応
  • 署名対応が必須。
  • Privacy Manifests 対応が必須。
アプリ開発者の対応
  • 対応されているバージョンにアップデートする。
  • アプリ側の Privacy Manifests 対応が必須。
  • 対応されない場合、SDK の乗り換えを検討する。
    • 例えば、リストに上がっている AFNetworking は既にメンテナンスが終了しており、対応される見込みがないので、別の SDK を利用するといったことを検討する必要がある。

その他の Third-party SDK について

SDK 開発者の対応
  • プライバシーデータの収集をしている場合もしくは理由が必要な API を使用している場合、Privacy Manifests 対応が必須。
アプリ開発者の対応
  • アプリで利用しているどの Third-party SDK が Privacy Manifests 対応の対象かを把握する。
    • 全ての SDK が対応してくれるとは限らないので、アプリ開発者としても利用している SDK のうちどれが Privacy Manifests 対応が必要なのかを把握しておくことで SDK 開発者にコミュニケーションを取るなどの手段が取れるでしょう。
  • 対象の SDK を対応されているバージョンにアップデートする。
  • 対応されない場合、 SDK の乗り換えを検討する。

アプリ内や Third-party SDK で利用されている Required reason API を調査する方法

現状、 Apple から Required reason API を使っているアプリや SDK を調査するツールなどは用意されていません。したがって、自分たちで調査するしかありません。

調査方法としては次のようなものが考えられます。

  1. ソースコード内の文字列を検索
  2. アプリや SDK のバイナリのシンボルを検索
方法 1. ソースコード内の文字列を検索

こちらは、自身のアプリや Third-party SDK のソースコードが手に入るのであれば、やり方としてはシンプルな方法です。

一方、単なるテキスト検索なので、自身で定義した別の変数やメソッド名にこれらの API の文字列が含まれる場合やコメント内の文字列も引っかかります。また、これらの API を宣言していても実際には使われていない場合なども引っかかる可能性があり、検索結果にノイズが多くなる可能性は高いです。

また、注意点として Required reason API で列挙されている API はそれぞれ Objective-C のメソッド名と Swift でのメソッド名があるのでそれぞれ網羅できるように検索する必要があるということです。

方法 2. アプリや SDK のバイナリのシンボルを検索

こちらの方法では、アプリや SDK のバイナリに対して nm コマンドを使ってシンボルを吐き出し、シンボルの中から Required reason API を検出する方法になります。

こちらに関しては nm コマンド自体があまり利用頻度が高いものではないと思うので馴染みが薄いという方も多いかもしれません。そういう意味では取っ付きにくい方法かもしれませんが、ソースコードのテキストを検索するよりは精度高く検出できそうです。

シンボルを検出するので、コメントなどの文字列は当然検出対象外になります。また、ソースコード上で Swift で Required reason API を記述していてもシンボルでは Objective-C にブリッジされているようなのでテキスト検索の方法のように Swift でのメソッド名の検索も省けるメリットがあります。

nm コマンドでの具体的な検出も説明しようかと思いましたが、 nm コマンドを利用した検出ツール(スクリプト)を作っている方がいたのでそちらを紹介しようと思います。 nm コマンドの使い方が気になる方はスクリプトの中も参考にしていただければと思います。

検出ツール(スクリプト)の紹介

github.com

先ほど紹介したテキスト検索とバイナリ検索の 2パターンのスクリプトを用意してくれています。
これを使うことで比較的簡単にアプリや Third-party SDK 内で Required reason API を利用している箇所を調査できるかもしれません。
前述した nm コマンドもスクリプトを見ていくと使われていることが分かります。

もう一歩踏み込んでみる

上記スクリプトの動作確認用デモアプリの中にも記載されていますが、 Swift の API での ProcessInfo.processInfo.systemUptimeUITextInputMode.activeInputModesnm コマンドでもシンボルとして検出できません。
これらも含めて検出するには、どうすれば良いでしょうか? 調査の結果、手元にソースコードがある場合、オブジェクトファイル .o を作って nm コマンドに食わせると Swift の ProcessInfo.processInfo.systemUptimeUITextInputMode.activeInputModes API も検出可能になっていました。
この辺りの挙動は興味がある方は調べてみると面白いかもしれません。

Privacy Manifests 対応調査時に出てきた疑問点

冒頭にも書きましたが、本記事の執筆時点で情報の明瞭さに欠ける部分があり、 Privacy Manifests 対応の調査を行なっている最中にいくつか疑問点が出てきたのでこちらにまとめておきます。
疑問点のうち、解決したものもあれば、そうでないものもありますがご了承ください。

  • 2024年春 って具体的にはいつ?
    • 不明です。
    • Apple Developer Program のサポートに問い合わせても回答はありませんでした。追加の情報を待つしかなさそうです。
  • Apple が公開した「一般的に使用される Third-party SDK」のリストにある SDK 以外の Third-party SDK も Privacy Manifests 対応の対象か?
    • 記事中に記載の通り、データ収集を行なっているか、Required reason API を使っている場合は全て対象になるそうです。
    • こちらの Apple Developer Forum の Apple の回答を参照ください。Apple Developer Program のサポートに問い合わせてもこの Forum の回答が正しいという回答をもらいました。
  • Third-party SDK が Privacy Manifests 対応されない場合、アプリ側の Privacy Manifests に Third-party SDK の分も追加して良いか?
    • 不明です。
    • Apple Developer Forum に同様の質問が投げられていますが、記事執筆時点で回答がありません。

おわりに

最後にもう1点、開発者として重要な「やること」があります。それは 「引き続き Apple からの情報をキャッチすること」 です。
冒頭にも述べたように、まだまだ情報としては明確になっていないことが多く、多くの開発者が混乱している状況のように思います。(具体的な対応期日も出てこないのは辛いですね、、)したがって、今後の Apple の公式情報をしっかりウォッチしておき、適切に対応していく必要があります。

今回この調査を通じて、改めて、アプリ開発者として自身が書くコードだけでなく、 Third-party SDK の利用においてもユーザのプライバシーデータを適切に扱えるように責任を持って開発する必要があるということを再認識できたように思います。
Apple からの情報の少なさには大変な思いをさせられますが、今回の件でアプリのデリバリーを途切れさせることなく、継続してユーザに価値を届けたいですね。そして、プライバシーに関しても安心して使っていただけるようなアプリを作っていければと思います。

不明瞭な点も多いですが、この記事がアプリ開発者の皆様の役に立てれば幸いです。

仲間募集中!

共にSansan / Eight のモバイルアプリ開発していく仲間を募集中です! 選考評価無しで現場のエンジニアのリアルな声が聞けるカジュアル面談もあるので、ご興味ありましたらぜひ面談だけでもお越しいただけたら幸いです!

open.talentio.com

*1:開発者として対応事項が多くなるという意味であり、もちろんユーザから見て悲しむべきことではないです。

© Sansan, Inc.