...
The machine running the scanner must have
docker
installedThe machine running the scanner must have internet access
We can recommend a base of 8GB RAM / 4 CPUs to run the scans, but note that scan time is proportional to the code base Here are our base spec recommendations for running the on-prem scanner
Repository Size | CPUs | RAM | Disk Size (SSD) |
---|---|---|---|
0-5 GB | 4 CPUs | 8 GB | 16 GB |
5-10 GB | 8 CPUs | 16 GB | 32 GB |
10-20 GB | 16 CPUs | 32 GB | 64 GB |
Note: Scan time is relative to the repository size so the specs that fit your needs may vary based on the size of your
...
repository.
Step 1: Generate a SAST Security Results API Key
...
Code Block |
---|
name: Data Theorem SAST # Controls when the workflow will run, adapt to your own needs on: # Triggers the workflow on push or pull request events but only for the "main" branch # Adapt triggers to your own needs push: branches: [ "main" ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: jobs: scan: continue-on-error: true timeout-minutes: 30 runs-on: ubuntu-latest container: image: us-central1-docker.pkg.dev/prod-scandal-us/datatheorem-sast/datatheorem-sast:latest env: DT_SAST_API_KEY: ${{ secrets.DT_SAST_API_KEY }} DT_SAST_REPOSITORY_NAME: ${{ github.event.repository.full_name }} DT_SAST_REPOSITORY_PLATFORM: GITHUB DT_SAST_REPOSITORY_ID: ${{ github.event.repository.id }} DT_SAST_REPOSITORY_HTML_URL: ${{ github.event.repository.html_url }} DT_SAST_REPOSITORY_DEFAULT_BRANCH_NAME: ${{ github.event.repository.default_branch }} DT_SAST_OUTPUT_DIR: ./ steps: - uses: actions/checkout@v4 - name: Start Data Theorem SAST Scan run: data_theorem_sast_analyzer scan ./ - uses: actions/upload-artifact@v4 with: name: dt-sast-scan-result path: ./scan-results-sarif.json |
...
Code Block |
---|
name: Data Theorem SAST # Controls when the workflow will run, adapt to your own needs on: # Triggers the workflow on push or pull request events but only for the "main" branch # Adapt triggers to your own needs pull_request jobs: scan: continue-on-error: true timeout-minutes: 30 runs-on: ubuntu-latest container: image: us-central1-docker.pkg.dev/prod-scandal-us/datatheorem-sast/datatheorem-sast:latest env: DT_SAST_API_KEY: ${{ secrets.DT_SAST_API_KEY }} DT_SAST_REPOSITORY_NAME: ${{ github.event.repository.full_name }} DT_SAST_REPOSITORY_PLATFORM: GITHUB DT_SAST_REPOSITORY_ID: ${{ github.event.repository.id }} DT_SAST_REPOSITORY_HTML_URL: ${{ github.event.repository.html_url }} DT_SAST_REPOSITORY_DEFAULT_BRANCH_NAME: ${{ github.event.repository.default_branch }} DT_SAST_SCAN_HEAD_REF: "refs/remotes/origin/${{ github.head_ref }}" DT_SAST_SCAN_TARGET_REF: "refs/remotes/origin/${{ github.base_ref }}" DT_SAST_FAIL_MODE: true steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # IMPORTANT: Needed because by default, actions/checkout@v4 doesn't load the full git history/refs - name: Start Data Theorem SAST Scan run: data_theorem_sast_analyzer scan ./ |
...
Code Block |
---|
stages: - security-scan datatheorem-sast-scan-branch-job: only: - main # Trigger on default branch push, replace 'main' with the name of your default branch tags: - gitlab-runner-docker # Needs to be an executor compatible with the`image` feature stage: security-scan image: us-central1-docker.pkg.dev/prod-scandal-us/datatheorem-sast/datatheorem-sast:latest script: - export DT_SAST_API_KEY=$DT_SAST_API_KEY - export DT_SAST_REPOSITORY_NAME=$CI_PROJECT_PATH - export DT_SAST_REPOSITORY_PLATFORM="GITLAB_ON_PREM" - export DT_SAST_REPOSITORY_ID=$CI_PROJECT_ID - export DT_SAST_REPOSITORY_HTML_URL=$CI_PROJECT_URL - export DT_SAST_REPOSITORY_DEFAULT_BRANCH_NAME=$CI_DEFAULT_BRANCH - export DT_SAST_SCAN_HEAD_REF=$CI_COMMIT_REF_NAME - data_theorem_sast_analyzer scan ./ datatheorem-sast-scan-merge-request-job: only: - merge_requests tags: - gitlab-runner-docker # Needs to be an executor compatible with the`image` feature stage: security-scan image: us-central1-docker.pkg.dev/prod-scandal-us/datatheorem-sast/datatheorem-sast:latest script: - export DT_SAST_API_KEY=$DT_SAST_API_KEY - export DT_SAST_REPOSITORY_NAME=$CI_PROJECT_PATH - export DT_SAST_REPOSITORY_PLATFORM="GITLAB_ON_PREM" - export DT_SAST_REPOSITORY_ID=$CI_PROJECT_ID - export DT_SAST_REPOSITORY_HTML_URL=$CI_PROJECT_URL - export DT_SAST_REPOSITORY_DEFAULT_BRANCH_NAME=$CI_DEFAULT_BRANCH - export DT_SAST_SCAN_TARGET_REF=$CI_MERGE_REQUEST_TARGET_BRANCH_NAME - data_theorem_sast_analyzer scan ./ |
Troubleshooting
SSL Errors
If the scanner if failing because of SSL errors, it may be because you are running the scanner behind a proxy that is making SSL verification fail.
If this is the case, we recommend to do the following:
Ensure the machine is able to connect with
api.securetheorem.com
For troubleshooting runcurl -v https://api.securetheorem.com/apis/devops/v1/sast_checks_download_link
The output should look like this if you have valid SSL certificatesCode Block * Trying 34.149.167.254:443... * TCP_NODELAY set * Connected to api.securetheorem.com (34.149.167.254) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=api.securetheorem.com * start date: Jun 19 00:50:43 2024 GMT * expire date: Sep 17 01:41:53 2024 GMT * subjectAltName: host "api.securetheorem.com" matched cert's "api.securetheorem.com" * issuer: C=US; O=Google Trust Services; CN=WR3 * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x56435e7a8340) > GET /apis/devops/v1/sast_checks_download_link HTTP/2 > Host: api.securetheorem.com > user-agent: curl/7.68.0 > accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * Connection state changed (MAX_CONCURRENT_STREAMS == 100)! < HTTP/2 401 HTTP/2 401 < content-type: application/json content-type: application/json < vary: Accept vary: Accept < cache-control: no-store cache-control: no-store < x-cloud-trace-context: cd829e04213d00117752acf8010832f9;o=1 x-cloud-trace-context: cd829e04213d00117752acf8010832f9;o=1 < date: Wed, 10 Jul 2024 10:14:41 GMT date: Wed, 10 Jul 2024 10:14:41 GMT < server: Google Frontend server: Google Frontend < content-length: 29 content-length: 29 < alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 < alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 < via: 1.1 google via: 1.1 google < x-xss-protection: 1; mode=block x-xss-protection: 1; mode=block < content-security-policy: default-src 'none'; object-src 'none'; frame-ancestors 'none'; report-uri https://o1421491.ingest.sentry.io/api/6767243/security/?sentry_key=e958eee4d16443b4a6674cda8c008ca7 content-security-policy: default-src 'none'; object-src 'none'; frame-ancestors 'none'; report-uri https://o1421491.ingest.sentry.io/api/6767243/security/?sentry_key=e958eee4d16443b4a6674cda8c008ca7 < expires: 0 expires: 0 < x-frame-options: DENY x-frame-options: DENY < referrer-policy: origin referrer-policy: origin < pragma: no-cache pragma: no-cache < x-content-type-options: nosniff x-content-type-options: nosniff < strict-transport-security: max-age=31536000; includeSubDomains; preload strict-transport-security: max-age=31536000; includeSubDomains; preload < * Connection #0 to host api.securetheorem.com left intact {"title": "401 Unauthorized"}(.venv) victor@vw-datatheorem:~/Workspace/scandal-server/on_prem_scanner$ curl -v https://api.securetheorem.com/apis/devops/v1/sast_checks_download_link * Trying 34.149.167.254:443... * TCP_NODELAY set * Connected to api.securetheorem.com (34.149.167.254) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/certs/ca-certificates.crt CApath: /etc/ssl/certs * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): * TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8): * TLSv1.3 (IN), TLS handshake, Certificate (11): * TLSv1.3 (IN), TLS handshake, CERT verify (15): * TLSv1.3 (IN), TLS handshake, Finished (20): * TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.3 (OUT), TLS handshake, Finished (20): * SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 * ALPN, server accepted to use h2 * Server certificate: * subject: CN=api.securetheorem.com * start date: Jun 19 00:50:43 2024 GMT * expire date: Sep 17 01:41:53 2024 GMT * subjectAltName: host "api.securetheorem.com" matched cert's "api.securetheorem.com" * issuer: C=US; O=Google Trust Services; CN=WR3 * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x55e36eefc340) > GET /apis/devops/v1/sast_checks_download_link HTTP/2 > Host: api.securetheorem.com > user-agent: curl/7.68.0 > accept: */* > * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * TLSv1.3 (IN), TLS handshake, Newsession Ticket (4): * old SSL session ID is stale, removing * Connection state changed (MAX_CONCURRENT_STREAMS == 100)! < HTTP/2 401 < content-type: application/json < vary: Accept < cache-control: no-store < x-cloud-trace-context: d93feb47ce573d06071f2b54ce0b87f2;o=1 < date: Wed, 10 Jul 2024 10:16:24 GMT < server: Google Frontend < content-length: 29 < alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 < alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000 < via: 1.1 google < x-xss-protection: 1; mode=block < content-security-policy: default-src 'none'; object-src 'none'; frame-ancestors 'none'; report-uri https://o1421491.ingest.sentry.io/api/6767243/security/?sentry_key=e958eee4d16443b4a6674cda8c008ca7 < expires: 0 < x-frame-options: DENY < referrer-policy: origin < pragma: no-cache < x-content-type-options: nosniff < strict-transport-security: max-age=31536000; includeSubDomains; preload < * Connection #0 to host api.securetheorem.com left intact {"title": "401 Unauthorized"}
In this example, we can see that the certificates at /etc/ssl/certs/ca-certificates.crt
(location may vary on your machine)
Note: the unauthorized response is expected, we are just checking the SSL verification here
Since the Data Theorem SAST scanner is running inside a Docker container, which may you have the certificates that can make valid calls for your proxy, we can mount the host machine’s SSL certificates directory in the Docker container and add a parameter to let the scanner know where to look for SSL certificates.
This can be done like this:
...
Azure DevOps Pipeline Example
Create a new Azure DevOps Pipeline
Add a variable named DT_SAST_API_KEY
with the value retrieved in step 1 and make sure the Keep this value secret
option is checked. (See https://learn.microsoft.com/en-us/azure/devops/pipelines/process/set-secret-variables?view=azure-devops&tabs=yaml%2Cbash )
The Azure Pipeline definition should look like this:
Code Block |
---|
trigger:
- main
pool:
vmImage: ubuntu-latest
steps:
- script: |
docker run \
-e DT_SAST_API_KEY='$(DT_SAST_API_KEY)' \
-e DT_SAST_REPOSITORY_NAME=$(Build.Repository.Name) \
-e DT_SAST_REPOSITORY_PLATFORM=AZURE_DEVOPS \
-e DT_SAST_REPOSITORY_ID=$(Build.Repository.ID) \
-e DT_SAST_REPOSITORY_HTML_URL=$(Build.Repository.Uri) \
-e DT_SAST_REPOSITORY_DEFAULT_BRANCH_NAME="main" \
-e DT_SAST_SCANNED_BRANCH=$(Build.SourceBranchName) \
-e DT_SAST_SCAN_HEAD_REF="HEAD" \
--mount type=bind,source="$(pwd)"/,target=/target \
us-central1-docker.pkg.dev/prod-scandal-us/datatheorem-sast/datatheorem-sast:latest \
data_theorem_sast_analyzer scan /target
displayName: 'Data Theorem On-Prem SAST'
|
Troubleshooting
SSL Errors
If the scanner if failing because of SSL errors, it may be because you are running the scanner behind a proxy that is making SSL verification fail.
If this is the case, we recommend to do the following:
You can build a custom Docker images that embeds your own valid SSL certificates
Make sure you have valid certificates that are able to call api.securetheorem.com
from the machine that is running the Data Theorem On-Prem Scanner
The Dockerfile would look like this
Code Block |
---|
FROM us-central1-docker.pkg.dev/prod-scandal-us/datatheorem-sast/datatheorem-sast:latest
# Copy SSL certificates to add
COPY --from=<YOUR_SOURCE> <PATH_TO_YOUR_SSL_CERTS> /usr/share/ca-certificates/custom
# Add certificates to /etc/ca-certificates.conf
RUN for crt in /usr/share/ca-certificates/custom/*.crt; do \
echo "Adding $crt" && echo "custom/$(basename "$crt")" >> /etc/ca-certificates.conf; \
done
# Update bundled CA certificates at /etc/ssl/certs/ca-certificates.crt
RUN update-ca-certificates
ENV DT_SAST_PATH_TO_SSL_CERTS_FILE=/etc/ssl/certs/ca-certificates.crt |
If this is not working, please contact
support@datatheorem.com
for help