The workflow of GitHub Actions has four main steps:
- Prerequisites
 - Configure GitHub Environment Parameters
 - Configure GitHub Action
 - Download Scan Results
 
This README document explains how to use the Qualys WAS GitHub Action and gives some samples for your reference.
- Visit GitHub configuration a workflow to enable GitHub Action in your repository. configuring-a-workflow
 - Subscribe to Qualys WAS module and obtain Qualys credentials.
 - Create GitHub Secrets and variables. Refer to GitHub Action Parameter section below to learn about the parameters. Refer to Encrypted secrets for more details on how to set up secrets.
 - Configure your workflow. In the actions steps of run.yaml file use 
Qualys/github_action_qwas@main - You can use the Input Parameters to customize GitHub Action as per your requirements.
 
Note: The actions/checkout step is required to run before the scan action, otherwise the action does not have access to the Web apps to be scanned.
Qualys WAS GitHub Actions can be used to trigger repository scan in different events. Following are some sample scan events for your reference:
Refer to the below sample to scan web applications in your repository on push event.
name: Qualys WAS Scan 
on:
  push:
    branches:
      - main
jobs:
    Qualys_was_scan:
        runs-on: ubuntu-latest
        name: Qualys WAS Scan
        steps:
          - name: Checkout
            uses: actions/checkout@v3 
            with:
                fetch-depth: 0
    
          - name: Qualys WAS scan action step
            uses: Qualys/github_action_qwas@main
            id: was
            with:
              API_SERVER: ${{ vars.API_SERVER }}
              QUALYS_USERNAME: ${{ vars.QUALYS_USERNAME }}
              QUALYS_PASSWORD: ${{ secrets.QUALYS_PASSWORD }}
              WEBAPP_ID: ${{ vars.WEBAPP_ID }}
              SCAN_NAME: ${{ vars.SCAN_NAME }}
              SCAN_TYPE: ${{ vars.SCAN_TYPE }}
              AUTH_RECORD: ${{ vars.AUTH_RECORD }}
              AUTH_RECORD_ID: ${{ vars.AUTH_RECORD_ID }}
              OPTION_PROFILE: ${{ vars.OPTION_PROFILE }}
              OPTION_PROFILE_ID: ${{ vars.OPTION_PROFILE_ID }}
              CANCEL_OPTION: ${{ vars.CANCEL_OPTION }}
              CANCEL_HOURS: ${{ vars.CANCEL_HOURS }}
              SEVERITY_CHECK: ${{ vars.SEVERITY_CHECK }}
              SEVERITY_LEVEL: ${{ vars.SEVERITY_LEVEL }}
              EXCLUDE: ${{ vars.EXCLUDE }}
              FAIL_ON_SCAN_ERROR: ${{ vars.FAIL_ON_SCAN_ERROR }}
              WAIT_FOR_RESULT: ${{ vars.WAIT_FOR_RESULT }}
              INTERVAL: ${{ vars.INTERVAL }}
              TIMEOUT: ${{ vars.TIMEOUT }}
              FILE_TYPE: ${{ vars.FILE_TYPE }}To download the scan result in your repository, checkout the repository using below code. If the repository is private, then add PAT (personal access token) token in the checkout step.
          - name: checkout code
            uses: actions/checkout@v3
            with:
             repository: GITHUB_USERNAME/REPOSITORY_NAME
             ref: BRANCH_NAME
             path: ./
             PAT: ${{ secrets.ACCESS_TOKEN }}
          - name: Download Result
            uses: actions/download-artifact@v4
            with:
             name: Qualys_WAS_Scan_Result
             path: PATH_TO_TARGET_DIRECTORY Refer to the below sample to scan web applications in your repository on pull event.
name: Qualys WAS Scan 
on:
  pull_request:
    branches:
      - main 
jobs:
  Qualys_was_scan:
    runs-on: ubuntu-latest
    name: Qualys WAS Scan
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      
      - name: Qualys WAS scan action step
        uses: Qualys/github_action_qwas@main
        id: was
        with:
          API_SERVER: ${{ vars.API_SERVER }}
          QUALYS_USERNAME: ${{ vars.QUALYS_USERNAME }}
          QUALYS_PASSWORD: ${{ secrets.QUALYS_PASSWORD }}
          WEBAPP_ID: ${{ vars.WEBAPP_ID }}
          SCAN_NAME: ${{ vars.SCAN_NAME }}
          SCAN_TYPE: ${{ vars.SCAN_TYPE }}
          AUTH_RECORD: ${{ vars.AUTH_RECORD }}
          AUTH_RECORD_ID: ${{ vars.AUTH_RECORD_ID }}
          OPTION_PROFILE: ${{ vars.OPTION_PROFILE }}
          OPTION_PROFILE_ID: ${{ vars.OPTION_PROFILE_ID }}
          CANCEL_OPTION: ${{ vars.CANCEL_OPTION }}
          CANCEL_HOURS: ${{ vars.CANCEL_HOURS }}
          SEVERITY_CHECK: ${{ vars.SEVERITY_CHECK }}
          SEVERITY_LEVEL: ${{ vars.SEVERITY_LEVEL }}
          EXCLUDE: ${{ vars.EXCLUDE }}
          FAIL_ON_SCAN_ERROR: ${{ vars.FAIL_ON_SCAN_ERROR }}
          WAIT_FOR_RESULT: ${{ vars.WAIT_FOR_RESULT }}
          INTERVAL: ${{ vars.INTERVAL }}
          TIMEOUT: ${{ vars.TIMEOUT }}
          FILE_TYPE: ${{ vars.FILE_TYPE }}To download the scan result in your repository, checkout the repository using the following code. If repository is private, then add PAT (personal access token) token in the checkout step.
      - name: checkout code
        uses: actions/checkout@v3
        with:
           repository: GITHUB_USERNAME/REPOSITORY_NAME
           ref: BRANCH_NAME
           path: ./
           PAT: ${{ secrets.ACCESS_TOKEN }}
      - name: Download Result
        uses: actions/download-artifact@v4
        with:
           name: Qualys_WAS_Scan_Result
           path: PATH_TO_TARGET_DIRECTORYRefer to the below sample to scan web applications in your repository on manual trigger event.
name: Qualys IAC Scan 
on: workflow_dispatch
jobs:
  Qualys_was_scan:
    runs-on: ubuntu-latest
    name: Qualys WAS Scan
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      
      - name: Qualys WAS scan action step
        uses: Qualys/github_action_qwas@main
        id: was
        with:
          API_SERVER: ${{ vars.API_SERVER }}
          QUALYS_USERNAME: ${{ vars.QUALYS_USERNAME }}
          QUALYS_PASSWORD: ${{ secrets.QUALYS_PASSWORD }}
          WEBAPP_ID: ${{ vars.WEBAPP_ID }}
          SCAN_NAME: ${{ vars.SCAN_NAME }}
          SCAN_TYPE: ${{ vars.SCAN_TYPE }}
          AUTH_RECORD: ${{ vars.AUTH_RECORD }}
          AUTH_RECORD_ID: ${{ vars.AUTH_RECORD_ID }}
          OPTION_PROFILE: ${{ vars.OPTION_PROFILE }}
          OPTION_PROFILE_ID: ${{ vars.OPTION_PROFILE_ID }}
          CANCEL_OPTION: ${{ vars.CANCEL_OPTION }}
          CANCEL_HOURS: ${{ vars.CANCEL_HOURS }}
          SEVERITY_CHECK: ${{ vars.SEVERITY_CHECK }}
          SEVERITY_LEVEL: ${{ vars.SEVERITY_LEVEL }}
          EXCLUDE: ${{ vars.EXCLUDE }}
          FAIL_ON_SCAN_ERROR: ${{ vars.FAIL_ON_SCAN_ERROR }}
          WAIT_FOR_RESULT: ${{ vars.WAIT_FOR_RESULT }}
          INTERVAL: ${{ vars.INTERVAL }}
          TIMEOUT: ${{ vars.TIMEOUT }}
          FILE_TYPE: ${{ vars.FILE_TYPE }}To download the scan result in your repository, checkout the repository using the following code. If repository is private, then add PAT (personal access token) token in the checkout step.
      - name: checkout code
        uses: actions/checkout@v3
        with:
           repository: GITHUB_USERNAME/REPOSITORY_NAME
           ref: BRANCH_NAME
           path: ./
           PAT: ${{ secrets.ACCESS_TOKEN }}
      - name: Download Result
        uses: actions/download-artifact@v4
        with:
           name: Qualys_WAS_Scan_Result
           path: PATH_TO_TARGET_DIRECTORYRefer to the below sample to scan web applications in your repository on scheduled trigger events.
name: Qualys IAC Scan 
on: 
    schedule:
        - cron: '30 5 * * 1,3'
jobs:
  Qualys_was_scan:
    runs-on: ubuntu-latest
    name: Qualys WAS Scan
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        with:
          fetch-depth: 0
      
      - name: Qualys WAS scan action step
        uses: Qualys/github_action_qwas@main
        id: was
        with:
          API_SERVER: ${{ vars.API_SERVER }}
          QUALYS_USERNAME: ${{ vars.QUALYS_USERNAME }}
          QUALYS_PASSWORD: ${{ secrets.QUALYS_PASSWORD }}
          WEBAPP_ID: ${{ vars.WEBAPP_ID }}
          SCAN_NAME: ${{ vars.SCAN_NAME }}
          SCAN_TYPE: ${{ vars.SCAN_TYPE }}
          AUTH_RECORD: ${{ vars.AUTH_RECORD }}
          AUTH_RECORD_ID: ${{ vars.AUTH_RECORD_ID }}
          OPTION_PROFILE: ${{ vars.OPTION_PROFILE }}
          OPTION_PROFILE_ID: ${{ vars.OPTION_PROFILE_ID }}
          CANCEL_OPTION: ${{ vars.CANCEL_OPTION }}
          CANCEL_HOURS: ${{ vars.CANCEL_HOURS }}
          SEVERITY_CHECK: ${{ vars.SEVERITY_CHECK }}
          SEVERITY_LEVEL: ${{ vars.SEVERITY_LEVEL }}
          EXCLUDE: ${{ vars.EXCLUDE }}
          FAIL_ON_SCAN_ERROR: ${{ vars.FAIL_ON_SCAN_ERROR }}
          WAIT_FOR_RESULT: ${{ vars.WAIT_FOR_RESULT }}
          INTERVAL: ${{ vars.INTERVAL }}
          TIMEOUT: ${{ vars.TIMEOUT }}
          FILE_TYPE: ${{ vars.FILE_TYPE }}To download the scan result in your repository, checkout the repository using the following code. If repository is private, then add PAT (personal access token) token in the checkout step.
      - name: checkout code
        uses: actions/checkout@v3
        with:
           repository: GITHUB_USERNAME/REPOSITORY_NAME
           ref: BRANCH_NAME
           path: ./
           PAT: ${{ secrets.ACCESS_TOKEN }}
      - name: Download Result
        uses: actions/download-artifact@v4
        with:
           name: Qualys_WAS_Scan_Result
           path: PATH_TO_TARGET_DIRECTORY- Valid Qualys Credentials and subscription to Qualys WAS and Qualys API.
 - Use the 
actions/checkout@v3step withfetch-depth: 0before calling Qualys WAS GitHub action. - While working on the self-hosted runners, ensure that your machine has stable internet connection.
 - Add 
QUALYS_PASSWORDinsecretsand remaining parameters to therepository variablesof Qualys WAS GitHub action. 
| Parameter | Description | Mandatory/ Optional | Default Value | Parameter Type | 
|---|---|---|---|---|
| QUALYS_PASSWORD | Use the Qualys Password | Mandatory | "" | Secret | 
| QUALYS_USERNAME | Use the Qualys Username | Mandatory | "" | Variable | 
| API_SERVER | Use the API URL. Click here to get your API URL. (Make sure that you provide API server URL only. Platform URL or API Gateway URL is not valid) | Mandatory | "" | Variable | 
| WEBAPP_ID | Use the Web App ID that you want to scan. | Mandatory | "" | Variable | 
| SCAN_NAME | Use any name for the scan. The timestamp gets appended automatically. | Mandatory | "" | Variable | 
| SCAN_TYPE | This parameter specifies the scan type. Use VULNERABILITY or DISCOVERY as a parameter value. | Mandatory | "" | Variable | 
| AUTH_RECORD | Use any of the following values: useDefault: The default authentication record for the web app in WAS (if any) is used. other: Use this value to use a specific value for AUTH_RECORD_ID. none: Runs the scan without authentication. It is the default value. Note: If you use none as a parameter value, the scanner will not be able to log into the secured web application tabs and to test the authenticated area of the application. | Optional | none | Variable | 
| AUTH_RECORD_ID | Use the specific AUTH_RECORD_ID. Note: You must set the value for the AUTH_RECORD parameter as other. | Optional | "" | Variable | 
| OPTION_PROFILE | The option profile contains the various scan settings such as the vulnerability types that should be tested (detection scope), scan intensity, error thresholds, etc. Use any of the following values: useDefault: It uses the default option profile in WAS. It is the default value. other: You can use a specific value for the OPTION_PROFILE_ID parameter. | Optional | useDefault | Variable | 
| OPTION_PROFILE_ID | Use the option profile ID of your choice. Note: You must set the OPTION_PROFILE parameter value as other to use this parameter. | Optional | "" | Variable | 
| CANCEL_OPTION | Use any of the following: true: Set this value to true to specify the scan end time. false: The scan will run until it is completed. This is the default value. | Optional | false | Variable | 
| CANCEL_HOURS | Use the numeric value to specify scan duration in hours. The scan is terminated after a specified time. You must set the CANCEL_OPTION parameter value as true to use this parameter. | Optional | "" | Variables | 
| SEVERITY_CHECK | Use any of the following values: true: This will set the SEVERITY_LEVEL as a failure condition for the scan. false: The SEVERITY_LEVEL is not considered in scan failure. | Optional | false | Variables | 
| SEVERITY_LEVEL | Specify the severity level of the vulnerability. You can use any values between 1-5. In Qualys, a severity level of 1 is as considered the least harmful, and a severity level of 5 is considered as most harmful. Note: You can enter only one value as a scan parameter during a scan. The scan will fail the build if it detects the vulnerability of a specified value or greater than that. For example, if you set the severity level to 3, the build will fail if the vulnerability of severity level 3 or more is found during the scan. | Optional | 0 | Variable | 
| FAIL_ON_SCAN_ERROR | Use true or false as the parameter value. true: When the GitHub plugin initiates the scan and the value for this parameter is set to true, but the WAS module cannot complete the scan due to some issues then the build fails. false: If you set the parameter value as false then the build does not fail due to incomplete scan. The default value for this parameter is false. | Optional | false | Variable | 
| WAIT_FOR_RESULT | Use any of the following values: true: The plugin waits for the scan results. The default value for this parameter is true. false: The plugin will not wait for the scan results. | Optional | true | Variable | 
| INTERVAL | Use the numeric value to set the polling interval in minutes to collect the scan data. Ex: 5. By default, it will be 5 Minutes. | Optional | 5 | Variable | 
| TIMEOUT | Use the numeric value to set the timeout duration in minutes to check the scan results. For example, 60. The default value of TIMEOUT is 350 min. Note: The timeout limit for GitHub-hosted runners is 360 minutes. On GitHub-hosted runners, you cannot run the job for more than 360 minutes. However, in self-hosted runners, there is no limit on timeout, and you can set a timeout for more than 360 minutes. | Optional | 350 | Variable | 
| EXCLUDE | Use the QIDs separated by commas to exclude them from the scan. For example, 1234, 1345. This will exclude these two QIDs for vulnerability severity level failure conditions. | Optional | "" | Variable | 
| FILE_TYPE | This parameter specifies the file format in which user wants the scan report | Optional | "PDF" | Variable | 
| Note: The Parameter values given in the above table are case-sensitive. |