本文へ移動

権限とruntime安全性 ​

2層のpermission ​

Apsule Projectはまず、利用したい機能を宣言します。

json
{
  "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で動作し続けられます。

text
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を明示的に返します。