権限とruntime安全性
2層のpermission
Apsule Projectはまず、利用したい機能を宣言します。
{
"permissions": {
"network": true,
"storage": true,
"bluetooth": true,
"location": "whenInUse",
"camera": false,
"photos": false,
"notifications": false,
"liveActivities": false,
"localNetwork": false,
"music": false,
"authentication": false,
"weather": false,
"translation": false,
"nearbyInteraction": false,
"spotlight": false,
"wallet": false
}
}Hostは初回実行前に、projectが要求するpermission setを表示します。project updateで実効permission setが同じ、または縮小される場合は再確認しません。updateによってpermissionが追加・拡大された場合は、新たに要求された・拡大されたaccessだけをHostが表示し、その新しいpermissionを利用可能にする前に承認を求めます。iOS保護対象resourceを実際に要求する場合は、通常のiOS permission flowも引き続き使われます。
実行可能なHostは、承認済みpermission setをproject単位で自身のApplication Support containerに保存します。permissionを縮小した場合は即時反映し、保存済みの実効approvalも縮小します。そのため、あるrevisionで削除したpermissionを後のrevisionで再追加した場合は、再承認が必要です。新しいpermissionのapproval sheetに回答する前でもinstall update自体は受け入れられますが、新規・拡大されたHost API accessは拒否されたままとなり、自動runtime reloadも承認まで保留されます。決定待ちの間、既存codeは以前承認済みの実効permissionで動作し続けられます。
Apsule project permission
|
v
Host API call
|
v
iOS system permission (when required)Project permissionがiOS permissionを回避することはありません。
music: trueはすべてのhost.music.* APIをgateします。最初のMusicKit authorizationではAppleのsystem consent flowを使用します。Apple Music provider/user tokenはMusicKit/Host内に保持し、Project JavaScriptへ返しません。制限付きhost.music.api.request bridgeはdestinationをapi.music.apple.comに固定し、任意URLやpath traversalを拒否し、request headerをfilterするため、一般的なauthenticated HTTP proxyにはなりません。
authentication、weather、translation、nearbyInteraction、spotlight、walletは、それぞれ対応するHost API familyをgateします。host.wallet.addはProject sandbox内のpassを読むため、追加でstorage: trueが必要です。host.locationのregion/visit monitoringにはlocation: "always"が必要で、通常のforeground location APIは引き続きwhenInUseで利用できます。
Isolation
- Storage/database/keychain namespaceはproject単位。
- File writeはdefaultでproject sandbox内。
- あるprojectから別projectのsandboxを直接読み取れない。
- 将来、明示的なShared Container mechanismによって選択したproject同士が選択したdataを共有できるようにしてもよいが、opt-inでありdefault isolationを弱めてはいけない。
- sandbox外のuser fileへアクセスする場合は、明示的なpicker/handle flowが必要。
- projectが呼び出せるのは、自身が宣言し、user/Hostが許可したHost API familyだけ。
- secretを通常のlogやruntime state dumpに含めない。
JavaScript runtime control
Hostでは次を考慮します。
- execution time limit/watchdog。
- memory limitまたは実用的なguardrail。
- runaway asynchronous workのcancel。
- project stop時のsubscription cleanup。
- 1つのprojectがProject Manager stateを破壊しない、明確なcrash/error isolation。
project停止時にはactiveなJavaScript/runtime work(timer、live socket、scan、watch、subscription)を破棄しますが、persistent project dataは消去しません。関連Host APIで明示的にその動作を定義している場合、すでにiOSへcommitされたOS-managed workはJavaScript runtimeより長く存続できます。local notificationが最初の想定例です。
Network
初期のpersonal-use designでは、networkが付与されていれば任意のHTTPS endpointを許可して構いません。将来public distributionでdomain/transport policyを厳しくしてもproject semanticsが予期せず変わらないよう、このpolicyは明示しておきます。
localNetworkはInternet/network permissionとは別です。Bonjour discoveryやLAN deviceへの直接TCP/UDP接続をgateします。iOSが追加でLocal Network system promptを表示する場合があり、Bonjour browsingはHost buildで宣言したservice typeに制限されます。
Permissionと互換性
一部のiOS機能には、Host自体のInfo.plist usage description、entitlement、App Service、background mode、signing capabilityが必要です。project declarationからこれらを動的に追加することはできません。Runtime discoveryはインストール済みHostに含まれるcodeを報告します。entitlement依存APIは、現在のsignature/profileで利用できない場合、明示的に失敗しなければなりません。
Apple Musicは、Project permissionだけでは不十分な例の1つです。Hostにusage descriptionが含まれ、userがMusicKitをauthorizeし、signingに使うApp IDでMusicKit App Serviceが有効になっている必要があります。
同じルールはWeatherKit、Sign in with Apple/passkey、Nearby Interaction、NFC、HealthKit、HomeKitなどのplatform-gated familyにも適用します。Apsuleはrestricted entitlementをdefault projectへ強制追加しません。通常のdevelopment/sideload profileがsignできなくなるためです。実装が含まれるAPIはruntime discoveryへ出しますが、インストール済みsignatureでApple capabilityを利用できない場合はruntime/platform errorを明示的に返します。