Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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 anAPI 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.pngImage Modified

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:

Code Block
#!/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:

Code Block
#!/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