Signing profiles migration for users of pre-3.16 releases

RELEASE 3.16 MIGRATION

Required migration

This article describes changes for Blue Cedar Policy Console Release 3.16—users of pre-3.16 releases can use this information when upgrading. The Policy Console documentation covers signing profiles in detail.

Blue Cedar Policy Console Release 3.16 includes a new method for managing code signing parameters: signing profiles. When you upgrade to 3.16 from a previous release, the migration process uses the signing parameters set in the older policy console to create signing profiles ready for use.


About signing profiles

To code-sign apps with a 3.16 policy console, use a signing profile to specify the method for code signing and app-signing parameters. Unlike a policy profile, which is a collection of settings that can be applied with a policy to inject an app with security, a signing profile is a collection of code signing parameters. Managing signing profiles is very similar to managing policy profiles.

  • If your 3.16 policy console is a new policy console installation, see the policy console documentation for information about code signing apps.
  • This article describes the migration from policy consoles without profile-based signing to policy consoles with profile-based signing, and explains how to identify the migration-generated profiles so you can use or modify them for future securing and signing.

When you upgrade a policy console from a release without profile-based signing to a release with profile-based signing, the process creates profiles based on the most recent code-signing settings per app. 

Because code signing is platform-specific, each signing profile is unique to Android or iOS.

Migration-generated signing profiles in 3.16

For each app (Android and iOS) that was loaded and secured in a pre-3.16 version of the policy console, the migration process creates a signing profile. In some cases, more than one app may have been secured and signed with the same signing parameters, but the migration process creates a signing profile for each app, even if the only difference is the name of the signing profile, not the contents.

Custom Android signing profiles for 3.16

Important Android keystore change: Pre-3.16 policy consoles create a keystore per app for code signing. 3.16+ policy consoles do not create a keystore per app, but instead provide a single signing profile with keystore that you can use for any app. You can also create your own signing profiles with custom keystores.

For each Android app in the old console, the migration process creates a signing profile in the new console:

  • The signing profile is named after the app. The profile description specifies that it's a "Generated profile" for the app package name.
  • The signing profile includes the keystore file, plus the alias and password for the key last applied to the app.

Custom iOS signing profiles for 3.16

For each iOS app in the old console, the migration process creates a signing profile in the new console:

  • The signing profile is named after the app. The profile description specifies that it's a "Generated profile" for the app package name.
  • The signing profile includes the provisioning profile (a .mobileprovision file) last applied to the app.
  • The signing profile includes the signing certificate ID last applied to the app.

Global signing profiles

The migration process also creates these signing profiles which are not associated with a specific app. 

  • iOS Global Signing Profile: If the previous console version had global signing parameters set (provisioning profile and certificate ID), then the migration process creates this profile.
  • Android Grouped Apps Profile: You can use this grouped app signing profile for all Android apps, whether they're grouped or not. 

    Note: Previously, Android signing happened internally, and there were no signing parameters to set globally. Thus the console provides the grouped apps profile for convenience.

Signing profiles in the REST API with release 3.16

Note that the settings/ios-cert-id and settings/ios-provisioning APIs are removed in Release 3.16. If you have used these in a previous policy console release, the values are added to a signing profile.

Pre-3.163.16

Global settings: Pre-3.16, these API calls set the global values for the distribution certificate and provisioning profile.

  • settings/ios-cert-id
  • settings/ios-provisioning
Values set in pre-3.16 policy consoles are migrated to a signing profile (JSON object). Use app-market/policy with the signing_profile_id parameter to specify the signing profile.

Per-app custom values: Pre-3.16, you could override the global settings by specifying these parameters when applying policies with the app-market/policy API.

  • ios_provisioning
  • ios_certid
  • use_custom_entitlements
Use app-market/policy with the signing_profile_id parameter to specify the signing profile.

Using the REST API to identify a migration-generated signing profile

For complete details, see the Policy Console REST API Reference.

To use the migration-created signing profiles, follow these steps (details below):

  1. Choose a signing profile using one of these methods:
    • Find the app-specific signing profile ID (GET app-market/{app-ID})
    • Use another custom or global signing profile ID (GET profile/catalog/signing)
  2. Get the signing policy ID (GET app-policy/code/POLICY_CODE_SIGNING)
  3. Apply policies and sign the app (POST app-market/policy)

Step 1: Choose a signing profile and get the profile ID

Find the app-specific signing profile ID that includes the signing settings used last to secure the app (if not SKIP_CODESIGN).

On upgrade, the policy console migrates these settings into a signing profile and associates the profile with the app. To use this migration-generated profile the next time you apply policies, find this signing id.

GET app-market/{GUID} returns all policies for the app (specified by the app ID), security policies and signing policy. The policy_code (POLICY_CODE_SIGNING) identifies the policy; the policy_data provides the profile ID (signing_profile_id). Use the signing_profile_id from the signing policy data when you apply policies.

Get the policies for the app
https://bc.qwe.com/mocana-app-control/rest/app-market/2674cd63-e06e-4b04-b42f-58311e9cf4fe
Response
{
  "application": [{
    "activity_event_type": 5,
    "apk_url": "https://bc.qwe.com:443/mocana-app-control/rest/app-market/2674cd63-e06e-4b04-b46f-58311e9cf4ff/apk",
    "app_id": "2674cd63-e06e-4b04-b46f-58311e9cf4ff",
    "app_policies": [
      ...
      {
        "info_url": "https://bc.qwe.com:443/mocana-app-control/rest/app-policy/b8942401-b27e-45a4-b34e-ca9800b88f5e",
        "policy_code": "POLICY_CODE_SECURE_WEB_STACK",
        "policy_data": "{\"secure_web_stack_profile_id\":\"5d3bc859-3f6d-45fb-8976-13f4fbaf964c\"}",
        "policy_icon_url": "https://bc.qwe.com:443/mocana-app-control/rest/files/b8e08642-4b0e-4713-b338-44a27855a18c",
        "policy_id": "b8942401-b27e-45a4-b34e-ca9800b88f5e",
        "policy_name": "Secure Web Stack",
        "policy_profile_data": "4ada958b-711f-41ad-b450-6f2f7f7314cf",
        "policy_status": "active"
      },
      {
        "info_url": "https://bc.qwe.com:443/mocana-app-control/rest/app-policy/d05bbf47-d405-47a7-a668-a4bdb90e8bf4",
        "policy_code": "POLICY_CODE_SIGNING",
        "policy_data": "{\"signing_profile_id\":\"c8532101-ac96-4d9b-b196-0aea89797a7d\"}",
        "policy_icon_url": "https://bc.qwe.com:443/mocana-app-control/rest/files/fbb4375a-697c-42ff-b5c2-033b917d5627",
        "policy_id": "d05bbf47-d405-47a7-a668-a4bdb90e8bf4",
        "policy_name": "Signing",
        "policy_profile_data": "09c76865-b0f5-4fc4-b5b0-fac9817feedd",
        "policy_status": "active"
      }
    ],
    "can_wrap_map_legacy": false,
    "can_wrap_map_next": true,
    "icon_url": "https://bc.qwe.com:443/mocana-app-control/rest/app-market/2674cd63-e06e-4b04-b46f-58311e9cf4ff/icon",
    "info_url": "https://bc.qwe.com:443/mocana-app-control/rest/app-market/2674cd63-e06e-4b04-b46f-58311e9cf4ff",
    "is_compass_app": true,
    "is_mocana_app": true,
    "last_modified_at": "2017-06-05 09:51:25.0",
    "last_modified_by": "Policy Console",
    "name": "Compass.Next",
    "package_name": "com.mocana.Compass",
    "package_size": "2016687",
    "platform": "PLATFORM_IOS",
    "plist_url": "https://bc.qwe.com:443/mocana-app-control/rest/web-catalog/2674cd63-e06e-4b04-b46f-58311e9cf4ff.plist",
    "policy_hash": "e827eaa0-dcec-44a7-b73a-2bae324aba26",
    "signing": {"signing_type": "SIGN_EXTERNALLY"},
    "upload_info": {
      "uploaded_app_size": 2016687,
      "uploaded_as": "Compass-9.9.9-4429241.ipa",
      "uploaded_at": "2017-06-05 09:51:25.0",
      "uploaded_by": "Policy Console"
    },
    "version_code": "9.9.9",
    "version_name": "450",
    "wrapped_by_version": "9.9.9.750",
    "wrapped_package_size": "13775780"
  }],
  "message": "",
  "status": "OK"
}
  • In the response, find the app_policies object: this is the list of policies last applied to the app. Each item in this list has details on a policy that was applied and the associated profile that was used.
  • Find the policy_data key in the object where policy_code is POLICY_CODE_SIGNING. The policy_data key contains the signing_profile_id (in this example, c8532101-ac96-4d9b-b196-0aea89797a7d)

    ...
    	"policy_code": "POLICY_CODE_SIGNING",
        "policy_data": "{\"signing_profile_id\":\"c8532101-ac96-4d9b-b196-0aea89797a7d\"}",
    ...

OR Use another signing profile

GET profile/catalog/signing responds with all the signing profiles available on the policy console. Select one and use its profile_id.

Get all the signing policies
curl -b c.txt -c c.txt -X GET https://bc.qwe.com/mocana-app-control/rest/profile/catalog/signing
Response
Response:
{
  "message": "",
  "profiles": [
    {
      "data": {
        "profile_data": "{\"keystore_pass\":\"mocanamap\",\"keystore_alias\":\"mocanadev\",\"keystoreBlobId\":\"e67d91bf-047c-4cb8-aa68-a7d83801b97a\"}",
        "profile_data_id": "7c78ae14-f614-4e91-8c9a-a7de131150ad",
        "profile_data_stamp": "2017-05-30 14:43:54.0"
      },
      "profile_desc": "Generated profile for - com.bcn.shareddatastore.default",
      "profile_id": "0a630067-c9da-423f-a725-7f2cda79f318",
      "profile_name": "Android Grouped Apps Profile",
      "profile_type": "signing",
      "profile_url": "https://bc.qwe.com:443/mocana-app-control/rest/profile/0a630067-c9da-423f-a725-7f2cda79f318"
    },
    {
      "data": {
        "profile_data": "{\"keystore_pass\":\"mocanamap\",\"keystore_alias\":\"mocanadev\",\"keystoreBlobId\":\"e1e4017f-85d3-48ec-91fc-3cbe12d04e4c\"}",
        "profile_data_id": "6a7d4ae9-6003-47c8-a009-0db395c083d6",
        "profile_data_stamp": "2017-05-30 14:43:54.0"
      },
      "profile_desc": "Generated profile for - com.socialnmobile.dictapps.notepad.color.note",
      "profile_id": "2a1a7685-7b57-4972-831c-dd04fa8a53fb",
      "profile_name": "ColorNote",
      "profile_type": "signing",
      "profile_url": "https://bc.qwe.com:443/mocana-app-control/rest/profile/2a1a7685-7b57-4972-831c-dd04fa8a53fb"
    }
    {
      "data": {
        "profile_data": "{\"signing_cert_id\":\"iPhone Developer\",\"provisioningProfileBlobId\":\"f8e8db0e-ae99-4dd9-b7f1-c813756808ca\"}",
        "profile_data_id": "09c76865-b0f5-4fc4-b5b0-fac9817feedd",
        "profile_data_stamp": "2017-05-30 14:43:55.0"
      },
      "profile_desc": "Generated profile for - com.mocana.Compass",
      "profile_id": "c8532101-ac96-4d9b-b196-0aea89797a7d",
      "profile_name": "Compass.Next",
      "profile_type": "signing",
      "profile_url": "https://bc.qwe.com:443/mocana-app-control/rest/profile/c8532101-ac96-4d9b-b196-0aea89797a7d"
    },
	{
      "data": {
        "profile_data": "{\"signing_cert_id\":\"iPhone Distribution\",\"provisioningProfileBlobId\":\"fd0452d1-86ce-4987-9311-d17c5d2fa351\"}",
        "profile_data_id": "1b8c43db-fbe4-4404-b2a2-d76c5734aef0",
        "profile_data_stamp": "2017-05-30 14:43:54.0"
      },
      "profile_desc": "Global Signing Profile for iOS Apps",
      "profile_id": "99919947-421a-41fb-8ac7-f44cac1d4cfb",
      "profile_name": "iOS Global Signing Profile",
      "profile_type": "signing",
      "profile_url": "https://bc.qwe.com:443/mocana-app-control/rest/profile/99919947-421a-41fb-8ac7-f44cac1d4cfb"
    }
  ],
  "status": "OK"
}

In this example, to use the profile with profile_name "iOS Global Signing Profile", use the profile_id 99919947-421a-41fb-8ac7-f44cac1d4cfb.

Step 2: Get the signing policy ID

GET app-policy/code/POLICY_CODE_SIGNING returns information about the Signing policy, including the policy ID. (In this example, policy_id is d05bbf47-d405-47a7-a668-a4bdb90e8bf4.)

Get the signing policy ID
curl -b c.txt -c c.txt -X GET https://bc.qwe.com/mocana-app-control/rest/app-policy/code/POLICY_CODE_SIGNING
Response
{
  "app_policy": [{
    "applications": [
      {
        "apk_url": "https://bc.qwe.com/mocana-app-control/rest/app-market/1ee0e67f-e571-46f5-9a6f-4fbba91b9f87/apk"
		...
      }...
    ],
    "info_url": "https://bc.qwe.com/mocana-app-control/rest/app-policy/d05bbf47-d405-47a7-a668-a4bdb90e8bf4",
    "policy_code": "POLICY_CODE_SIGNING",
    "policy_icon_url": "https://bc.qwe.com:443/mocana-app-control/rest/files/fbb4375a-697c-42ff-b5c2-033b917d5627",
    "policy_id": "d05bbf47-d405-47a7-a668-a4bdb90e8bf4",
    "policy_name": "Signing",
    "policy_status": "active",
    "summary_count": 17
  }],
  "message": "",
  "status": "OK"
}

Step 3: Secure and sign the app

Use POST app-market/policy as before, but instead of specifying ios_provisioning and ios_certid, provide the signing_profile_id and signing policy_id inside the policyIds[] array along with any security policies.

Wrap and sign the app
curl -b c.txt -c c.txt -X POST https://bc.qwe.com/mocana-app-control/rest/app-market/policy \ 
-F appId=11eef64f-4d55-4637-ab3c-eef20a108596 \ 
-F policyIds[]=63ee4324-45f1-442c-9ead-b2b797c52b05 \ 
-F policyIds[]=d05bbf47-d405-47a7-a668-a4bdb90e8bf4 \ 
-F master_profile_id=2ee64c1b-729f-4139-bd4d-ffd44a0f13ca \ 
-F signing_profile_id=c8532101-ac96-4d9b-b196-0aea89797a7d\ 
-F signing="{\"signing_type\":\"SIGN_ON_CONSOLE\"}"