Uploading Mobile Apps Using the DevOps API

The Mobile Security DevOps API can be used to upload pre-production and enterprise (internal) mobile binaries directly to Data Theorem for scanning.

This pages provides detailed documentation about how to use this API in order to upload mobile app binaries to Data Theorem. If you are trying to integrate Data Theorem scans into your existing CI/CD pipeline, a quickstart guide is available here – we may already have an integration that works with your CI/CD pipeline.

Overview

Uploading a mobile app binary is a two-step process:

  1. Make an API call in order to initialize the upload and receive the actual upload URL
  2. Upload the app binary (IPA, APK, etc.) along with some additional data (eg, comments or credentials needed for dynamic scanning) about the app to the provided upload URL.

Step 1 - Initialize the Upload

The upload process can be initialized by calling this method.

Authentication

Authentication is done by passing your organization’s Upload API key as part of the Authorization header:

1
Authorization: APIKey 1234567890abcdefgh

The Upload API key can be retrieved by users in the Data Theorem portal at https://www.securetheorem.com/sdlc/api_access within the “Upload API Key” section.

See API Conventions – Authentication and Authorization for more information.

Request

POST /apis/mobile_security/devops/v1/upload_init

For example, this method can be called via curl using:

1
curl -X POST -H "Authorization: APIKey AAAABBBBCCCCAJ82/iNaIQ=="  --data ""  https://api.securetheorem.com/apis/mobile_security/devops/v1/upload_init

Response

1
2
3
{
"upload_url": "https://prod-dopinder-v2.securetheorem.com/api/v1/upload/application/Aewsadw[...]"
}

The response contains the upload_url, to be used for uploading the mobile binary. This URL will only be valid for 10 minutes.

Step 2 - Upload the Mobile App

After retrieving the upload_url, the mobile app binary should be sent as a multipart/form-data request to upload the file with the following arguments:

  • file (file upload, required):
    • The mobile binary (APK, IPA, APPX or XAP) to be scanned.
  • release_type (optional, but strongly encouraged):
    • This should be set to PRE_PROD or ENTERPRISE, depending on whether the app being uploaded is a pre-production app (or a “test” app) or an enterprise (internal) app (an internal-only production app that will not be published to one of the app stores).
    • If the argument is omitted, then our backend will first try to match the build to any existing ENTERPRISE or PRE_PROD apps. If there is no matching app, then it will default to PRE_PROD.
  • username (optional):
    • Username to be used to log into the application for dynamic scanning.
  • password (optional):
    • Password to be used to log into the application for dynamic scanning.
  • comments (optional):
    • Miscellaneous comments regarding the upload.
  • release_id (optional):
    • A custom ID associated with the binary being submitted, since the app version may not change very often.
    • It is recommended that you use a unique value for this, such as the CI/CD job ID.
    • If not set, Data Theorem will assign the binary a release_id.
  • platform_variant (optional):
    • The variant of the platform to use for scanning; Accepted values are:
      • IOS_ON_MAC: Scan an iOS build on an Apple Silicon Mac instead of on an iOS device, in order to exercise code paths that are specific to Macs.
  • external_id (optional):
    • The external_id field represents your organization’s custom identifier for the app, if any.
  • sourcemap (file upload, optional):
  • is_enterprise_internal (optional, deprecated):
    • Setting this to true is equivalent to specifying a release_type of ENTERPRISE. It is ignored if release_type is specified.

Authentication

Since the upload_url is unique for each upload, there is no need to authenticate with the Upload API Key.

Request

POST {upload_url}

The request must be a standard multipart file upload, the mobile app binary is expected in the file field.

For example, this method can be called via curl using:

1
2
3
4
5
6
7
curl \
-F "file=@androidapp.apk" \
-F "comments=uploaded with curl" \
-F "username=testuser" \
-F "password=testpass" \
-F "release_type=PRE_PROD" \
"https://prod-dopinder-v2.securetheorem.com/api/v1/upload/application/Aewsadw[...]"

Note: Pay special attention to the @ character. It needs to be put in front of the file’s name for curl to upload the file.

If you need to submit a sourcemap file, it should also be provided as a file upload:

1
2
3
4
5
6
curl \
-F "file=@androidapp.apk" \
-F "sourcemap=@mapping.txt" \
-F "comments=uploaded with curl" \
-F "release_type=PRE_PROD" \
"https://prod-dopinder-v2.securetheorem.com/api/v1/upload/application/Aewsadw[...]"

Response

A successful upload returns a status code 200 and status text ok.

1
2
3
4
5
6
7
8
9
10
11
{
"mobile_app_id": "3456789012",
"bundle_id": "com.myapp",
"is_app_new": false,
"name": "My App",
"platform": "IOS",
"release_type": "PRE_PROD",
"scan_id": "<scan_id>",
"session_id": "<session_id>",
"status": "ok"
}

The mobile_app_id and scan_id fields contain identifiers that can later be used to query the state of the scan started for the uploaded app build.

Errors are also usually JSON formatted.

1
2
3
4
5
{
"status": "package_corrupted",
"error": "Build looks corrupted",
"session_id": "<session_id>"
}

Status/error code mapping

  • 200/ok: upload succeed
  • 401/unauthorized: unauthorized (bad credentials or the url may have expired)
  • 403/mobile_app_has_no_subscription: this mobile app has no active subscription, please contact Data Theorem
  • 415/unauthorized_package_extension: unauthorized extension, must be ipa/apk/xap/appx, case-insensitive
  • 422/package_corrupted: package corrupted
  • 500/error: internal server error