security cms -D

プロビジョニングプロファイル(.mobileprovision)は、plistをCMS(PKCS#7)形式で署名したバイナリファイルである。 テキストエディタで開いても、署名データが混ざっていて読みにくい。

macOSのsecurity cms -Dを使うと、署名を外して中身のplistをXMLで表示できる。

$ security cms -D -i [プロファイルのパス]

-DはCMSメッセージのデコード、-iは入力ファイルの指定である。

$ security cms -D -i MyApp_AppStore.mobileprovision
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>AppIDName</key>
	<string>MyApp</string>
	<key>ApplicationIdentifierPrefix</key>
	<array>
	<string>ABCDE12345</string>
	</array>
	<key>CreationDate</key>
	<date>2026-06-05T09:06:31Z</date>
...

-oで出力先のファイルを指定できる。

$ security cms -D -i MyApp_AppStore.mobileprovision -o profile.plist

プロファイルの保存場所

Xcodeがダウンロードしたプロファイルは以下のディレクトリに保存される。 ファイル名はプロファイルのUUIDである。

~/Library/Developer/Xcode/UserData/Provisioning Profiles/

古いバージョンのXcodeでは以下のディレクトリに保存されていた。

~/Library/MobileDevice/Provisioning Profiles/

ビルドしたアプリでは、.app内のembedded.mobileprovisionがプロファイルである。 .ipaの場合はunzipで展開するとPayload/[アプリ名].app/embedded.mobileprovisionに含まれている。

主なキー

plutil -pに渡すと、キーと値を読みやすい形式で表示できる。

$ security cms -D -i MyApp_AppStore.mobileprovision | plutil -p -
{
  "AppIDName" => "MyApp"
  "ApplicationIdentifierPrefix" => [
    0 => "ABCDE12345"
  ]
  "CreationDate" => 2026-06-05 09:06:31 +0000
  "DER-Encoded-Profile" => {length = 3405, bytes = 0x30820d4906092a864886f70d010702a0 ... b9758b2bc2adc6b2}
  "DeveloperCertificates" => [
    0 => {length = 1463, bytes = 0x308205b33082049ba003020102021069 ... aef83a24b3c6da45}
  ]
  "Entitlements" => {
    "application-identifier" => "ABCDE12345.com.example.MyApp"
    "beta-reports-active" => true
    "com.apple.developer.applesignin" => [
      0 => "Default"
    ]
    "com.apple.developer.team-identifier" => "ABCDE12345"
    "get-task-allow" => false
    "keychain-access-groups" => [
      0 => "ABCDE12345.*"
      1 => "com.apple.token"
    ]
  }
  "ExpirationDate" => 2027-04-26 01:30:39 +0000
  "IsXcodeManaged" => false
  "Name" => "MyApp AppStore deployment"
  "Platform" => [
    0 => "iOS"
    1 => "xrOS"
    2 => "visionOS"
  ]
  "TeamIdentifier" => [
    0 => "ABCDE12345"
  ]
  "TeamName" => "Taro Yamada"
  "TimeToLive" => 324
  "UUID" => "00000000-1111-2222-3333-444444444444"
  "Version" => 1
}

よく確認するキーは以下のとおり。

キー内容
Nameプロファイル名
UUIDプロファイルのUUID
TeamIdentifierチームID
ExpirationDate有効期限(UTC)
Entitlementsアプリに許可されるEntitlements
DeveloperCertificates署名に使える証明書(DER形式)
ProvisionedDevicesインストールできるデバイスのUDID一覧
IsXcodeManagedXcodeが自動管理しているプロファイルかどうか

具体例

特定のキーの値を取り出す

plutil -extract [キー] raw -で、標準入力から受け取ったplistの値を取り出せる。

$ security cms -D -i MyApp_AppStore.mobileprovision | plutil -extract ExpirationDate raw -
2027-04-26T01:30:39Z

ネストしたキーは.で区切って指定する。

$ security cms -D -i MyApp_Development.mobileprovision | plutil -extract Entitlements.get-task-allow raw -
true

配列にrawを指定すると要素数を出力する。 以下はProvisionedDevicesに登録されたデバイスの数を確認する例。

$ security cms -D -i MyApp_Development.mobileprovision | plutil -extract ProvisionedDevices raw -
8

参考: 【plutil】-extractでplistから値を抽出する

Entitlementsだけを表示する

plutil -extractでxml1を指定すると、Entitlementsの辞書をXMLのまま取り出せる。 Push NotificationやApp Groupsなどの設定がプロファイルに含まれているかを確認する場合に使う。

$ security cms -D -i MyApp_AppStore.mobileprovision | plutil -extract Entitlements xml1 -o - -
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>application-identifier</key>
	<string>ABCDE12345.com.example.MyApp</string>
	<key>beta-reports-active</key>
	<true/>
	<key>com.apple.developer.applesignin</key>
	<array>
		<string>Default</string>
	</array>
	<key>com.apple.developer.team-identifier</key>
	<string>ABCDE12345</string>
	<key>get-task-allow</key>
	<false/>
	<key>keychain-access-groups</key>
	<array>
		<string>ABCDE12345.*</string>
		<string>com.apple.token</string>
	</array>
</dict>
</plist>

プロファイルの種類を見分ける

プロファイルの種類はget-task-allowとProvisionedDevicesの有無で見分けられる。

種類get-task-allowProvisionedDevices
Developmenttrueあり
Ad Hocfalseあり
App Storefalseなし

get-task-allowがtrueのプロファイルは、デバッガの接続を許可する開発用である。 EnterpriseプロファイルはProvisionedDevicesの代わりにProvisionsAllDevicesがtrueになる。

手元のプロファイルの有効期限を一覧表示する

保存場所のプロファイルをループで処理すると、有効期限と名前を一覧表示できる。 期限切れのプロファイルを探す場合に便利である。

cd ~/Library/Developer/Xcode/UserData/Provisioning\ Profiles
for f in *.mobileprovision; do
  plist=$(security cms -D -i "$f")
  printf '%s\t%s\n' "$(echo "$plist" | plutil -extract ExpirationDate raw -)" "$(echo "$plist" | plutil -extract Name raw -)"
done
2027-04-26T01:30:39Z	MyApp AppStore deployment
2027-04-26T01:30:39Z	OtherApp Adhoc deployment
2026-05-25T04:31:35Z	MyApp Adhoc deployment
2027-06-04T12:14:47Z	iOS Team Provisioning Profile: com.example.MyApp
2027-06-05T08:40:46Z	iOS Team Store Provisioning Profile: com.example.MyApp

含まれている証明書を確認する

DeveloperCertificatesには、プロファイルで署名できる証明書がDER形式で入っている。 plutil -extractでrawを指定するとBase64で出力されるため、デコードしてからopenssl x509に渡す。

$ security cms -D -i MyApp_AppStore.mobileprovision \
  | plutil -extract DeveloperCertificates.0 raw - \
  | base64 -d \
  | openssl x509 -inform DER -noout -subject -enddate
subject= /UID=ABCDE12345/CN=iPhone Distribution: Taro Yamada (ABCDE12345)/OU=ABCDE12345/O=Taro Yamada/C=JP
notAfter=Apr 26 01:30:39 2027 GMT

上記はmacOS標準のopenssl(LibreSSL)の出力である。 HomebrewのOpenSSLではsubject=UID=ABCDE12345, CN=...のようにカンマ区切りで表示される。

キーチェーンにある証明書と照らし合わせると、署名に使う証明書がプロファイルに含まれているかを確認できる。

参考: 【openssl】証明書ファイルの有効期限を確認する

エラー

プロファイル以外のファイルを指定すると、デコードに失敗する。

$ security cms -D -i sample.txt
security: failed to add data to decoder: UNKNOWN (-8183(d)
security: problem decoding

動作確認した環境

macOS 27.2.1で動作を確認した。

参考