Signing API

iOS, Android, and Windows Phone apps need to be digitally signed before they can be distributed to your mobile users. Signing (also known as “code signing”) is a process by which an app is sealed and identified as yours using public key cryptography. EASE provides a signing server that lets you sign iOS and Android apps directly through EASE. This is useful when, for example, you want to re-sign an app that has an expired certificate or sign an app after wrapping it with application policies.

Using the Signing API, you can interface with the signing server to:

  • List all signing credentials stored in EASE.
  • Add signing credentials to EASE.
  • Sign an app using a set of stored credentials.
  • Delete signing credentials from EASE.

Before you can sign any apps using the Signing API, you must first use the EASE Portal to upload the signing credentials you need. For instructions, see Manage Signing Credentials.

For information on what is needed to sign applications based on the application type, see Signing Requirements.

Resources

GET /v1/credentials/

List All Signing Credentials

Requires user context. Authenticate as a valid EASE user.

Returns data about all signing credentials stored in the EASE database for the authenticated user’s organization. An EASE administrator can add signing credentials to EASE through the Settings page in the EASE Portal. For more information on adding signing credentials, see Manage Signing Credentials.

When signing credentials are added to EASE, a unique identifier (credentials_id) is assigned to the set of components that comprise the credentials. With both iOS and Android, signing credentials include a certificate in PKCS (Personal Information Exchange File) #12 format. With iOS, signing credentials must also include at least one mobile distribution provisioning profile that associates the certificate with an app ID or wildcard ID. For iOS apps that contain extensions, signing credentials will need to include multiple provisioning profiles to use for signing the app and each extension in the app. Whether a set of signing credentials includes one or multiple provisioning profiles, it will still be identified with a single credentials_id. For more on the signing credentials needed for Android and iOS apps, see Signing Requirements.

URLs

Environment URL
North America https://na01ws.apperian.com/v1/credentials/
Europe https://eu01ws.apperian.eu/v1/credentials/

URL Parameters

None

Header Parameter

X-TOKEN
(Required) Session token returned by POST /users/authenticate.

Data Parameters

None

Example Request

curl -X GET https://na01ws.apperian.com/v1/credentials/ --header "X-TOKEN: eTg8ktZXRqKIBJTHunwP6A"

Example Response

This response returns data for the Android and iOS signing credentials stored in EASE for the organization. Use the psk value for credentials_id when signing an app with the PUT /applications/<app_psk>/credentials/<credentials_id> resource or deleting credentials with the DELETE /credentials/<credentials_id> resource. Use the expiration_date field in the response to identify any expired certificates. Note the last set of signing credentials (Hello World Credentials) includes multiple provisioning profiles since the Hello World app includes extensions and needs to be signed with a provisioning profile for each component.

{
     "credentials": [
       {
         "psk": "jQAqZdfQS3G9saW4SPDEIA",
         "platform_metadata": {
           "provisioning_profile_names": "[null]",
           "identity": "Michael Harrison"
         },
         "expiration_date": "2048-02-01T00:00:00+00:00",
         "description": "Android Cert",
         "platform": 2
       },
       {
         "psk": "W4SPjQAqZdfQS3G9saDEIA",
         "platform_metadata": {
           "provisioning_profile_names": "[null]",
           "identity": "Example Company"
         },
         "expiration_date": "2054-12-11T00:00:00+00:00",
         "description": "Android",
         "platform": 2
       },
       {
       "psk": "DEIAjQAqZdfQS3G9saW4SP",
         "platform_metadata": {
           "provisioning_profile_names": "["Provisioning Profile Name"]",
           "identity": "iPhone Distribution: Apperian"
         },
         "expiration_date": "2015-08-05T00:00:00+00:00",
         "description": "iOS Wildcard",
         "platform": 1
       },
       {
         "psk": "G9saW4SPjQAqZdfQS3DEIA",
         "platform_metadata": {
           "provisioning_profile_names": "["Enterprise General"]",
           "identity": "iPhone Distribution: Apperian"
       },
         "expiration_date": "2017-09-03T00:00:00+00:00",
         "description": "iOS Enterprise",
         "platform": 1
       },

       {
         "psk": "PDEIAjQAqZdfQS3G9saW4S",
         "platform_metadata": {
           "provisioning_profile_names": ["Test App (com.apperian.testappi",
                                          "Test Application Extension",
                                          "Test Application Watchkit App",
                                          "Apperian Enterprise General"],
           "identity": "iPhone Distribution: Apperian"
         },
         "expiration_date": "2017-09-03T00:00:00+00:00",
         "description": "Hello World App Credentials",
         "platform": 1
       }
     ]
}
POST /v1/credentials/

Add Signing Credentials to EASE

Authenticate as a valid EASE user.

Use this API to upload and store Android and iOS signing credentials in EASE. The credentials you upload via this API will be assigned a unique ID (credentials_id) that you can then specify when signing an app using the PUT /applications/<app_psk>/credentials/<credentials_id> resource. These credentials will also display in the list of stored credentials when signing an app through the EASE Portal.

Signing Requirements

The following table summarizes what comprises “signing credentials” for iOS and Android. For more detail, see Signing Requirements.

Platform What You Need to Upload
iOS
  • A distribution certificate (paired with a private key) exported to a .p12 file. This is a distribution certificate that has been exported, along with its associated private key, from a Login keychain to PKCS (Personal Information Exchange File) #12 format. If a password was defined during the export, you will need to provide that password with this API request.

    For instructions on creating a distribution certificate, see Create a Distribution Certificate.

    If you already have a distribution certificate on your Login keychain but need to export it, see Export a Distribution Certificate to a PKCS #12 File.

  • A distribution provisioning profile stored as a file with a .mobileprovision extension.

    For instructions on creating a distribution provisioning profile, see Create a Distribution Provisioning Profile.

    If you already created the profile but need to download it, see Download a Distribution Provisioning Profile.

    If you are storing credentials that will be used to sign an app that includes a WatchKit app and/or extensions, you may need multiple distribution provisioning profiles (see App Extensions and WatchKit Apps). With this API resource, a single credentials_id can be associated with multiple distribution provisioning profiles.

Android
  • A private key in PKCS (Personal Information Exchange File) #12 format. The file must have a .p12 extension. To create this file, import the JKS to a .p12 file. For instructions, see Import a Java KeyStore to a PKCS #12 File.

    For general information on signing Android applications, including more detailed instructions on using Keytool, see the Android documentation.

Note

Converting Certificates and Provisioning Profiles to Base64 Strings

With this API, you must upload certificates and distribution provisioning profiles as base64 strings. Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-64 representation. There are many tools available for converting a .p12 or .mobileprovision file to a base64 string. Click here to go to a web site that lets you drag and drop any binary file into your browser window to instantly display a base64 string.

URLs

Environment URL
North America https://na01ws.apperian.com/v1/credentials/
Europe https://eu01ws.apperian.eu/v1/credentials/

URL Parameters

None

Header Parameter

X-TOKEN
(Required) Session token returned by POST /users/authenticate.
Content-Type
(Required) Specifies the content type of the body of data sent with the request. Set to: application/json

Data Parameters

Required for both iOS and Android

description
(Required) A description for the signing credentials. This description will be returned by the GET /credentials resource, and will also display in the list of stored credentials in the EASE Portal.
platform

(Required) The operating system platform:

  • 1 for iOS
  • 2 for Android
p12_file_name
(Required) The file name of the certificate.
p12_file
(Required) A base64 string representing the certificate.
password

(Required) The password associated with the certificate, if applicable. If the certificate is not password-protected, this parameter is still required and you should provide an empty string:

"password": ""

Required for iOS only

provisioning_profile_file_names

(Required) The file names of one or more distribution provisioning profiles that are associated with the certificate you are uploading. Each file name must have a .mobileprovision extension.

Enclose the list (one or more profiles) with brackets. If you are uploading multiple profiles, separate the strings with commas. For example:

"provisioning_profile_file_names": ["profile1.mobileprovision", "profile2.mobileprovision"]

provisioning_profiles_base64

(Required) Base64 strings representing each of the profiles listed with the provisioning_profile_file_names parameter.

Enclose the list (one or more profiles) with brackets. If you are uploading multiple profiles, separate the strings with commas. Be sure to list the strings in the same order as the corresponding files in the provisioning_profile_file_names parameter.

Example Requests

Adding Android Signing Credentials

The following example uploads a certificate for signing Android applications. Note that [...] is used to represent most of the characters of the base64 strings.

curl -X POST https://na01ws.apperian.com/v1/credentials --header "X-TOKEN: NS6Lv3boSD2gvZVKA_S_Vw" --header "Content-Type: application/json" --data '{"description":"Android Signing Certificate", "platform":"2", "p12_file_name": "androidcert.p12", "password": "topsecret", "p12_file": "MIIJ4AIBAzCCCZoGC[...]SqGSDQEHAaCCCYsEg"}'

Adding iOS Signing Credentials

The following example uploads a distribution certificate and two distribution provisioning profiles to signing an iOS application that includes one extension. Note that [...] is used to represent most of the characters of the base64 strings.

curl -X POST https://na01ws.apperian.com/v1/credentials --header "X-TOKEN: XLOtB_MnTxCXydYdw1SuVQ" --header "Content-Type: application/json" --data '{"description":"iOS Signing Certificate", "platform":"1", "p12_file_name": "ioscert.p12", "password": "abcxyz", "p12_file": "zCC4AIBAzCCCZoGC[...]SqGSDQEHAaCCAzC", "provisioning_profile_names": ["Actions App Profile", "Actions App Extension Profile"], "provisioning_profile_file_names": ["profile1.mobileprovision", "profile2.mobileprovision"], "provisioning_profiles_base64": ["4AIBAzCCCZoGC[...]SqGSDQEHAaCC", "4AIBAzCCCZoGC[...]BAzCDQEHAaCC"]}'

Example Response

When the credentials are successfully added, EASE returns a unique ID (the credentials_id).

{
  "credentials_id": PDEIAjQAqZdfQS3G9saW4S
}
PUT /v1/applications/(app_psk)/credentials/(credentials_psk)

Sign an Application

Requires administrator privileges. Authenticate as an EASE administrator.

Signs an iOS or Android application using signing credentials that were previously stored in EASE for the authenticated user’s organization. To specify which credentials to use, you need to specify the credentials_id, which is the unique identifier assigned to the credentials when they are uploaded to EASE. The credentials_id is the psk value returned by a request to the GET /credentials API.

For iOS apps that contain extensions, signing credentials need to include multiple provisioning profiles to use for signing the app and each extension in the app. Whether a set of signing credentials includes one or multiple provisioning profiles, it will still be identified with a single credentials_id.

Note

If a signing certificate is password-protected, the password must be stored in EASE with the signing credentials in order for you to use those credentials when signing through the API; you cannot send the password with your signing API request. If a certificate is password-protected and you do not want to store the password in EASE, you can sign the app through the EASE Portal; EASE will display a Password field in which you can enter the password before you click Sign.

The signing process is asynchronous. If the API returns this successful JSON response, it means the process has successfully started:

{
  "signing_status": "in_progress"
}

If the process does not start successfully, you will receive an error. See the list of possible Error Messages below.

Note that if if the immediate status is in_progress, there there may still be an error completing the process. To monitor the status of the asynchronous process, send additional requests to the GET /applications/<app_psk> API resource. The JSON response from that resource will include a signing_status field plus a ` signing_status_details` field with additional information about the signing status. The signing_status_details field is useful primarily when the signing status is an error. For example:

The cert or profile is expired and will not run on any device.

Field Description
signing_status

The current status of the signing process. Valid values include:

  • in_progress
  • signed
  • cancelled
  • error
signing_status_details Additional information about the signing status. This field is useful primarily when the signing status is error. For example: The cert or profile is expired and will not run on any device.

See GET /applications/<app_psk> for more information on monitoring signing status, including a list of possible error messages.

URLs

Environment URL
North America https://na01ws.apperian.com/v1/applications/<app_psk>/credentials/<credentials_id>
Europe https://eu01ws.apperian.eu/v1/applications/<app_psk>/credentials/<credentials_id>

URL Parameters

app_psk
(Required) Unique ID for the app. DATA TYPE: integer
credentials_id

(Required) Unique ID for a set of signing credentials. If the signing certificate is password-protected, the password must be stored with the signing credentials or you will receive an error. The credentials_id is the psk value returned by a request to the GET /credentials API. DATA TYPE: integer

For more information on the signing credentials needed for Android and iOS apps, see Signing Requirements.

Header Parameter

X-TOKEN
(Required) Session token returned by POST /users/authenticate.
Content-Type
(Required) Specifies the content type of the body of data sent with the request. Set to: application/json

Data Parameters

None

Example Request

curl -X PUT https://na01ws.apperian.com/v1/applications/123/credentials/jQAqZdfQS3G9saW4SPDEIA  --header
     "Content-Type: application/json" --header "X-TOKEN: eTg8ktZXRqKIBJTHunwP6A"

Example Response

This is a successful response, indicating that the process has successfully started. Note that there may still be an error completing the process; use GET /credentials to monitor the status to ensure it changes to signed.

{
     "signing_status": "in_progress"
}

The following response indicates that the signing was not able to successfully start because of expired credentials. See Error Messages below for a list of the possible errors.

{
     "error": {
       "code": 20,
       "message": "Credentials jQAqZdfQS3G9saW4SPDEIA has expired.",
       "guid": "00101f19-4a2f-4c35-b53e-85b55bb45e1c",
       "error_details": null
     }
}

For a list of signing error messages, see Signing Status Messages.

DELETE /v1/credentials/(credentials_psk)/

Delete Signing Credentials

Requires administrator privileges. Authenticate as an EASE administrator.

Delete signing credentials that are stored in EASE for your organization. Use credentials_id to specify which credentials to delete; this is the unique identifier assigned by EASE when you add credentials either using the POST /credentials API resource or the EASE Portal.

To get a list of all credentials (and their assigned IDs) stored for your organization, use GET /credentials.

What comprises “signing credentials” varies for Android and iOS. For Android, signing credentials include a certificate paired with a private key and saved in PKCS #12 format. For iOS, signing credentials include a distribution certificate in PKCS #12 format and one or more distribution provisioning profiles (.mobileprovision files). Deleting credentials deletes all the components associated with the specified credentials_id.

URLs

Environment URL
North America https://na01ws.apperian.com/v1/credentials/<credentials_id>/
Europe https://eu01ws.apperian.eu/v1/credentials/<credentials_id>/

URL Parameters

credentials_id
(Required) Unique identifier assigned by EASE when you add credentials either using the POST /credentials API resource or the EASE Portal. It is the value of the psk parameter returned by the GET /credentials resource. DATA TYPE: integer

Header Parameter

X-TOKEN
(Required) Session token returned by POST /users/authenticate.

Data Parameters

None

Example Request

Use the -i (include) argument if you want to return the HTTP header in the output so that you can see the HTTP status message. Without -i, a successful request returns a blank response.

curl -i -X DELETE "https://na01ws.apperian.com/v1/credentials/qnBkhdHw83WnOCQdUlbA1w"
     --header "X-TOKEN: eTg8ktZXRqKIBJTHunwP6A"

Example Response

This is an example of a response to a curl command with the -i argument. An HTTP 204 message indicates that the signing credentials were successfully deleted.

HTTP/1.1 204 NO CONTENT
Date: Wed, 09 Mar 2016 11:50:32 GMT
Server: Apache
Content-Length: 0
Access-Control-Allow-Origin: null
Connection: close
Content-Type: text/html; charset=utf-8