Lacework
Access helpful articles and other FAQs on Lacework
Kate_M
Community Manager
Community Manager
Article Id 334670
Description

In this post we will build a Workflow that will be triggered upon the creation of a PR, will scan the code, then publish a summary of the results as a comment inside the PR.

Scope Lacework / Github
Solution

Setting the Workflow

The first step is to decide what events will trigger this workflow. In this case, we want to trigger this workflow when a Pull Request is created. In addition we need to give this pipeline the proper permissions:

 

name: lacework-iac-scan-pr

on:

 pull_request:

 workflow_dispatch:

permissions:

     id-token: write

     contents: read

     pull-requests: write

     security-events: write

     actions: read


Job : Lacework Scanner

In this workflow, we will only have one Job that will do a few steps. The reason for that is that we want it to be as fast as possible. The first step is to set the environment variables with the secrets needed for accessing out Lacework Account:

 

jobs:

 Lacework-Scanner:

   runs-on: ubuntu-latest

   steps:

     - name: Checkout Code

       uses: actions/checkout@v3

     - name: Lacework IaC Scan

       id: laceworkscan

       env:

         LW_ACCOUNT: ${{ secrets.LW_ACCOUNT }}

         LW_API_KEY: ${{ secrets.API_KEY }}

         LW_API_SECRET: ${{ secrets.API_SECRET_TOKEN }}

 

The next step is the scanning step. This is very similar to the scanning step in a previous post here

 

run: |

            # Setup

            IAC_REPORTS_DIR="/tmp/iac_reports"

            env | grep "GITHUB_\|LW_\|CI_" > env.list    # Set Lacework and other secrets

            echo "SCAN_COMMAND=tf-scan" >> env.list      # Configure the scanner to run Terraform Scan

            echo "WORKSPACE=src" >> env.list            

            echo "EXIT_FLAG=critical" >> env.list      # Cause the pipline to fail if any Critical Vulnerabilities are discovered

            echo "JUNIT_OUTPUT_FILE=/tmp/lacework-report.junit.xml"  >> env.list

            echo "JSON_OUTPUT_FILE=/tmp/lacework-report.json"  >> env.list

           

            # Run the Scan

            docker run --env-file env.list -v "$(pwd):/app/src" lacework/codesec-iac:latest

           

            # Copy the report outside lacework/codesec-iac:latest container

            CONTAINER_ID=$(docker ps -a |grep lacework |head -n1 |cut -d ' ' -f1) # Extracts the latest container ID (Inside a pipeline there should be only one anyways)

            mkdir $IAC_REPORTS_DIR

            docker container cp "$CONTAINER_ID:/tmp/lacework-report.json" $IAC_REPORTS_DIR

            docker container cp "$CONTAINER_ID:/tmp/lacework-report.junit.xml" $IAC_REPORTS_DIR



            # Set GITHUB_ENV

            RESULTS_JSON="$IAC_REPORTS_DIR/lacework-report.json"

            echo "RESULTS_JSON=$RESULTS_JSON" >> "$GITHUB_ENV"

 

The scanner step will upload the results to our Lacework account. But since results’ files in JSON and JUnit, the next step is to upload and publish  those so that developers can access them without logging into the lacework console

 

Please refer to this post [LINK] for full explanation of the Upload and Publish steps. What we care about here is extracting TEST, TEST_PASSED, and TESTS_FAILED values. We need those values to create a summary and add it to the PR as a comment.   

 

  - name: Update Pull Request

       uses: actions/github-script@v6

       if: github.event_name == 'pull_request'

       with:

         script: |

           const { TESTS, TESTS_PASSED, TESTS_FAILED   } = process.env

           const message = "Verify the Lacework IaC scanning results before merging!"

           const test_results = `<table><tr><th><th>Tests</th><th>Passed ✅</th><th>Failed ❌</th></tr><tr><td>Lacework TF-SCAN JUnit Results</td><td>${TESTS} Ran</td><td>${TESTS_PASSED} Passed</td><td>${TESTS_FAILED} Failed</td></tr></table>`



           const output = message + test_results



           github.rest.issues.createComment({

           issue_number: context.issue.number,

           owner: context.repo.owner,

           repo: context.repo.repo,

           body: output

           }) 

 

The above step uses TEST, TEST_PASSED, and TESTS_FAILED values from the previous step to build a summary and add it to the PR.

 

Finally, putting the entire Workflow together:

 

name: lacework-iac-scan-pr

on:

 pull_request:

 workflow_dispatch:

permissions:

     id-token: write

     contents: read

     pull-requests: write

     security-events: write

     actions: read

jobs:

 Lacework-Scanner:

   runs-on: ubuntu-latest

   steps:

     - name: Checkout Code

       uses: actions/checkout@v3

     - name: Lacework IaC Scan

       id: laceworkscan

       env:

         LW_ACCOUNT: ${{ secrets.LW_ACCOUNT }}

         LW_API_KEY: ${{ secrets.API_KEY }}

         LW_API_SECRET: ${{ secrets.API_SECRET_TOKEN }}

       run: |

            # Setup

            IAC_REPORTS_DIR="/tmp/iac_reports"

            env | grep "GITHUB_\|LW_\|CI_" > env.list    # Set Lacework and other secrets

            echo "SCAN_COMMAND=tf-scan" >> env.list      # Configure the scanner to run Terraform Scan

            echo "WORKSPACE=src" >> env.list            

            echo "EXIT_FLAG=critical" >> env.list      # Cause the pipline to fail if any Critical Vulnerabilities are discovered

            echo "JUNIT_OUTPUT_FILE=/tmp/lacework-report.junit.xml"  >> env.list

            echo "JSON_OUTPUT_FILE=/tmp/lacework-report.json"  >> env.list

           

            # Run the Scan

            docker run --env-file env.list -v "$(pwd):/app/src" lacework/codesec-iac:latest

           

            # Copy the report outside lacework/codesec-iac:latest container

            CONTAINER_ID=$(docker ps -a |grep lacework |head -n1 |cut -d ' ' -f1) # Extracts the latest container ID (Inside a pipeline there should be only one anyways)

            mkdir $IAC_REPORTS_DIR

            docker container cp "$CONTAINER_ID:/tmp/lacework-report.json" $IAC_REPORTS_DIR

            docker container cp "$CONTAINER_ID:/tmp/lacework-report.junit.xml" $IAC_REPORTS_DIR



            # Set GITHUB_ENV

            RESULTS_JSON="$IAC_REPORTS_DIR/lacework-report.json"

            echo "RESULTS_JSON=$RESULTS_JSON" >> "$GITHUB_ENV"

      

     - name: 'Upload Artifacts'

       uses: actions/upload-artifact@v3

       with:

         name: Lacework Junit Report

         path: /tmp/iac_reports/*

     - name: Publish IaC Scan Results

       run: |

           # Create results summary

           TESTS=$(cat $RESULTS_JSON |jq -r '.[].findings | .[].pass'| wc -l)

           echo "TESTS: $TESTS"

           TESTS_PASSED=$(cat $RESULTS_JSON |jq -r '.[].findings | .[].pass' | grep true | wc -l)

           echo "TESTS_PASSED: $TESTS_PASSED"

           TESTS_FAILED=$(cat $RESULTS_JSON |jq -r '.[].findings | .[].pass' | grep false| wc -l)

           echo "TESTS_FAILED: $TESTS_FAILED"



           # Set GITHUB_ENV

           echo "TESTS=$TESTS" >> "$GITHUB_ENV"

           echo "TESTS_PASSED=$TESTS_PASSED" >> "$GITHUB_ENV"

           echo "TESTS_FAILED=$TESTS_FAILED" >> "$GITHUB_ENV"



           # Adding a Step Summary to the workflow using $GITHUB_STEP_SUMMARY

           echo "<table><tr><th><th>Tests</th><th>Passed ✅</th><th>Failed ❌</th></tr><tr><td>Lacework TF-SCAN JUnit Results</td><td>${TESTS} Ran</td><td>${TESTS_PASSED} Passed</td><td>${TESTS_FAILED} Failed</td></tr></table>" >> $GITHUB_STEP_SUMMARY



     - name: Update Pull Request

       uses: actions/github-script@v6

       if: github.event_name == 'pull_request'

       with:

         script: |

           const { TESTS, TESTS_PASSED, TESTS_FAILED   } = process.env

           const message = "Verify the Lacework IaC scanning results before merging!"

           const test_results = `<table><tr><th><th>Tests</th><th>Passed ✅</th><th>Failed ❌</th></tr><tr><td>Lacework TF-SCAN JUnit Results</td><td>${TESTS} Ran</td><td>${TESTS_PASSED} Passed</td><td>${TESTS_FAILED} Failed</td></tr></table>`



           const output = message + test_results



           github.rest.issues.createComment({

           issue_number: context.issue.number,

           owner: context.repo.owner,

           repo: context.repo.repo,

           body: output

           }) 

 

Once a PR is created, the Workflow will be trigger and The PR would look like this:

 

 
755dc436-28e7-49f6-8745-5a0cae8b15a1.png

Contributors