SAST Scanning via API Keys

The following steps allow organizations to automatically scan releases of their source code using existing developer tools and processes. DevOps can fully automate the SDLC by integrating our API to existing CI/CD tools such as Azure DevOps, Travis CI, Jenkins, Bitrise, fastlane, Xcode server, etc.

Note: If your organization is using Github, Bitbucket or Gitlab, we recommend using the fully-integrated Data Theorem SAST plugins, see onboarding steps from the DevSecOps page in the Data Theorem portal:

https://www.securetheorem.com/devsecops/v2/sast-code-analysis

Quickstart guide

Step 1: Retrieving the SAST Scanning API key

First, you will need to retrieve/create an API Key from the Data Theorem portal, at ​https://www.securetheorem.com/devsecops/v2/results_api_access

Make sure that the SAST Scanning permission is enabled for this API Key

sast-api-key.png

 

Step 2: Configuring an upload step in CI/CD

Most CI/CD systems (Travis CI, Bitrise, CircleCI, etc.) allow running a bash script as a step within the CI pipeline. A new step should be added at the end of your existing pipeline to request a SAST scan from Data Theorem.

This new upload step requires:

  • The API key retrieved in step 1 to be available in the CI system
    via the DT_SAST_SCANNING_API_KEY environment variable.

  • The name of the source code repository to be available in the CI system
    via the DT_SAST_SCANNING_REPOSITORY_NAME environment variable.

The following bash script can then be used as the upload step:

#!/bin/env bash # Fail if any commands fails set -e if [ -z "$DT_SAST_SCANNING_API_KEY" ]; then echo "DT_SAST_SCANNING_API_KEY is not set!" exit 1 fi if [ -z "$DT_SAST_SCANNING_REPOSITORY_NAME" ]; then echo "DT_SAST_SCANNING_REPOSITORY_NAME is not set!" exit 1 fi file_name="${DT_SAST_SCANNING_REPOSITORY_NAME}.bundle" echo "Preparing for upload" git bundle create $file_name HEAD --all file_size=$(stat -c%s $file_name) echo "Requesting upload URL from Data Theorem" upload_init_response=$(curl -s -w "%{http_code}" -X POST -H "Authorization: APIKey ${DT_SAST_SCANNING_API_KEY}" -H "Content-Type: application/json" -d "{\"file_name\": \"$file_name\", \"file_size\": $file_size}" "https://api.securetheorem.com/apis/devops/v1/asset_scans/sast_scans") http_code=${upload_init_response: -3} response_body=${upload_init_response::-3} # Check that http status code is 200 [ ! ${http_code} -eq 200 ] && echo ${response_body} && exit 1 upload_url=$(echo ${response_body} | jq -r ".upload_url") if [ -z "$upload_url" ]; then exit 1 fi echo "Starting upload" upload=$(curl -X PUT --data-binary "@$file_name" $upload_url) if [ $? -ne 0 ]; then echo "Upload Failed!" exit 1 fi echo "Done"

 

Scanning is done in the background and should take a few minutes to complete.
Log into the Data Theorem Portal at ​https://www.securetheorem.com/api/v2/security/sast to view the scan results.

Step 3 (Optional): Track scan status

Data Theorem provides APIs that can check the status of the SAST scan, it can for example be used to make your CI/CD pipeline wait for the end of the scan

Sample Script:

#!/bin/env bash # Fail if any commands fails set -e if [ -z "$DT_SAST_SCANNING_API_KEY" ]; then echo "DT_SAST_SCANNING_API_KEY is not set!" exit 1 fi if [ -z "$DT_SAST_SCANNING_REPOSITORY_NAME" ]; then echo "DT_SAST_SCANNING_REPOSITORY_NAME is not set!" exit 1 fi file_name="${DT_SAST_SCANNING_REPOSITORY_NAME}.bundle" base_url="https://api.securetheorem.com/apis" echo "Preparing for upload" git bundle create $file_name HEAD --all file_size=$(stat -c%s $file_name) echo "Requesting upload URL from Data Theorem" upload_init_response=$(curl -s -w "%{http_code}" -X POST -H "Authorization: APIKey ${DT_SAST_SCANNING_API_KEY}" -H "Content-Type: application/json" -d "{\"file_name\": \"$file_name\", \"file_size\": $file_size}" "{$base_url}/devops/v1/asset_scans/sast_scans") http_code=${upload_init_response: -3} response_body=${upload_init_response::-3} # Check that http status code is 200 [ ! ${http_code} -eq 200 ] && echo ${response_body} && exit 1 upload_url=$(echo ${response_body} | jq -r ".upload_url") if [ -z "$upload_url" ]; then exit 1 fi request_id=$(echo ${response_body} | jq -r ".request_id") if [ -z "$upload_url" ]; then exit 1 fi echo "Starting upload" upload=$(curl -X PUT --data-binary "@$file_name" $upload_url) if [ $? -ne 0 ]; then echo "Upload Failed!" exit 1 fi max_wait_seconds=600 # 10 minutes max current_wait=0 wait_step=10 while [ "$current_wait" -lt "$max_wait_seconds" ]; do sleep "$wait_step" ((current_wait += wait_step)) scan_response=$(curl --silent -H "Authorization: APIKey ${DT_SAST_SCANNING_API_KEY}" \ "${base_url}/devops/v1/asset_scans/sast_scans/${request_id}") scan_status=$(echo "$scan_response" | jq -r '.status // "QUEUED"') echo "Checking scan status: $scan_status" if [ "$scan_status" = "FAILED" ]; then exit 1 fi if [ "$(echo "$scan_response" | jq -r '.results')" != "null" ]; then echo "Scan results are available!" echo "$(echo "$scan_response" | jq -c .)" break fi done