From 987a0a0260aeeaaee6b91fa618c35846020d2be3 Mon Sep 17 00:00:00 2001 From: Will Date: Wed, 21 Aug 2024 16:32:34 -0400 Subject: [PATCH 01/14] starting with the current finished-state pipeline Signed-off-by: Will --- .github/workflows/pipeline.yml | 69 +++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 13 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 3bb6942..b2ab955 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,23 +1,66 @@ -name: Demo Gold Image Pipeline for NGINX +name: Demo Security Validation Gold Image Pipeline on: push: - branches: - - main + branches: [ main, pipeline ] # trigger this action on any push to main branch jobs: - gold-image: - name: Gold Image Pipeline + gold-image: + name: Gold Image NGINX runs-on: ubuntu-20.04 env: - CHEF_LICENSE: accept - PROFILE: my_nginx + CHEF_LICENSE: accept # so that we can use InSpec without manually accepting the license + PROFILE: my_nginx # path to our profile steps: - - name: Update ubuntu - run: sudo apt-get update -y - - - name: PREP - Install InSpec executable + - name: PREP - Update runner # updating all dependencies is always a good start + run: sudo apt-get update + - name: PREP - Install InSpec executable run: curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec -v 5 - - name: PREP - Install profile - uses: actions/checkout@v3 \ No newline at end of file + - name: PREP - Check out this repository # because that's where our profile is! + uses: actions/checkout@v3 + + - name: LINT - Run InSpec Check # double-check that we don't have any serious issues in our profile code + run: inspec check $PROFILE + + - name: DEPLOY - Run a Docker container from nginx + run: docker run -dit --name nginx nginx:latest + + - name: DEPLOY - Install Python for our nginx container + run: | + docker exec nginx apt-get update -y + docker exec nginx apt-get install -y python3 + + - name: HARDEN - Fetch Ansible role + run: | + git clone --branch docker https://github.com/mitre/ansible-nginx-stigready-hardening.git || true + chmod 755 ansible-nginx-stigready-hardening + + - name: HARDEN - Fetch Ansible requirements + run: ansible-galaxy install -r ansible-nginx-stigready-hardening/requirements.yml + + - name: HARDEN - Run Ansible hardening + run: ansible-playbook --inventory=nginx, --connection=docker ansible-nginx-stigready-hardening/hardening-playbook.yml + + - name: VALIDATE - Run InSpec + continue-on-error: true # we dont want to stop if our InSpec run finds failures, we want to continue and record the result + run: | + inspec exec $PROFILE \ + --input-file=$PROFILE/inputs.yml \ + --target docker://nginx \ + --reporter cli json:results/pipeline_run.json + + - name: VALIDATE - Save Test Result JSON # save our results to the pipeline artifacts, even if the InSpec run found failing tests + uses: actions/upload-artifact@v3 + with: + path: results/pipeline_run.json + + - name: VERIFY - Display our results summary + uses: mitre/saf_action@v1 + with: + command_string: "view summary -i results/pipeline_run.json" + + - name: VERIFY - Ensure the scan meets our results threshold + uses: mitre/saf_action@v1 # check if the pipeline passes our defined threshold + with: + command_string: "validate threshold -i results/pipeline_run.json -F threshold.yml" \ No newline at end of file From e7835ec3e3984ec43f51f9bef9a396176b3576a9 Mon Sep 17 00:00:00 2001 From: Will Date: Wed, 21 Aug 2024 16:33:54 -0400 Subject: [PATCH 02/14] adding pull request trigger Signed-off-by: Will --- .github/workflows/pipeline.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index b2ab955..630fee3 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,6 +1,8 @@ name: Demo Security Validation Gold Image Pipeline on: + pull_request: # trigger this action on any pull request + branches: [ main ] # against main branch push: branches: [ main, pipeline ] # trigger this action on any push to main branch From 3f36e86b192ac1b6e1578291e0ac8af26f4e05da Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 00:56:19 -0400 Subject: [PATCH 03/14] adding push-to-heimdall step Signed-off-by: Will --- .github/workflows/pipeline.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 630fee3..b0c1004 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -57,6 +57,11 @@ jobs: with: path: results/pipeline_run.json + - name: VALIDATE - Upload to Heimdall + continue-on-error: true + run: | + curl -# -s -F data=@results/pipeline_run.json -F "filename=${{ github.actor }}-pipeline-demo-${{ github.sha }}.json" -F "public=false" -F "${{ github.repository }},${{ github.workflow }}" -H "Authorization: Api-Key ${{ secrets.HEIMDALL_API_KEY }}" "https://heimdall-demo.mitre.org/evaluations" + - name: VERIFY - Display our results summary uses: mitre/saf_action@v1 with: From 14e240f411930e4513e3106296fcf6226e0d51d1 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 00:58:02 -0400 Subject: [PATCH 04/14] adding correct input file Signed-off-by: Will --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index b0c1004..a10a8af 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -48,7 +48,7 @@ jobs: continue-on-error: true # we dont want to stop if our InSpec run finds failures, we want to continue and record the result run: | inspec exec $PROFILE \ - --input-file=$PROFILE/inputs.yml \ + --input-file=$PROFILE/inputs-linux.yml \ --target docker://nginx \ --reporter cli json:results/pipeline_run.json From e30fcbf3333701751511461d2de517f32f3a0572 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 01:04:33 -0400 Subject: [PATCH 05/14] replacing accidentally removed evaluationTags Signed-off-by: Will --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index a10a8af..2c8c52d 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -60,7 +60,7 @@ jobs: - name: VALIDATE - Upload to Heimdall continue-on-error: true run: | - curl -# -s -F data=@results/pipeline_run.json -F "filename=${{ github.actor }}-pipeline-demo-${{ github.sha }}.json" -F "public=false" -F "${{ github.repository }},${{ github.workflow }}" -H "Authorization: Api-Key ${{ secrets.HEIMDALL_API_KEY }}" "https://heimdall-demo.mitre.org/evaluations" + curl -# -s -F data=@results/pipeline_run.json -F "filename=${{ github.actor }}-pipeline-demo-${{ github.sha }}.json" -F "public=false" -F "evaluationTags=${{ github.repository }},${{ github.workflow }}" -H "Authorization: Api-Key ${{ secrets.HEIMDALL_API_KEY }}" "https://heimdall-demo.mitre.org/evaluations" - name: VERIFY - Display our results summary uses: mitre/saf_action@v1 From 325150346ab4ce72fa97bd656725178aebd94460 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 01:08:39 -0400 Subject: [PATCH 06/14] adding new test control requiring manual attestation Signed-off-by: Will --- my_nginx/controls/example.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/my_nginx/controls/example.rb b/my_nginx/controls/example.rb index d88b6e5..a476013 100644 --- a/my_nginx/controls/example.rb +++ b/my_nginx/controls/example.rb @@ -53,3 +53,13 @@ end end end + +control 'nginx-interview' do + impact 1.0 + title 'NGINX interview' + desc 'NGINX admins should have documentation on security procedures.' + + describe "Manual Review" do + skip "This control must be manually reviewed." + end +end \ No newline at end of file From e47aa2055d8f265cd59a416967939b56bd73f816 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 01:10:31 -0400 Subject: [PATCH 07/14] removing unecessary pipeline pr trigger Signed-off-by: Will --- .github/workflows/pipeline.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 2c8c52d..0f47a5a 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,8 +1,6 @@ name: Demo Security Validation Gold Image Pipeline -on: - pull_request: # trigger this action on any pull request - branches: [ main ] # against main branch +on: # against main branch push: branches: [ main, pipeline ] # trigger this action on any push to main branch From 6dddd54ca3a7b26d573fabd0e2dbe3f6246b0fc3 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 01:19:16 -0400 Subject: [PATCH 08/14] adding threshold file, adding attested control, adding attestation code to pipeline Signed-off-by: Will --- .github/workflows/pipeline.yml | 13 +++++++++---- attestation.json | 10 ++++++++++ threshold.yml | 5 +++++ 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 attestation.json create mode 100644 threshold.yml diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 0f47a5a..68a281b 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -50,22 +50,27 @@ jobs: --target docker://nginx \ --reporter cli json:results/pipeline_run.json + - name: VALIDATE - Apply an Attestation + uses: mitre/saf_action@v1 + with: + command_string: "attest -i results/pipeline_run.json -F attestation.json -o results/pipeline_run_attested.json" + - name: VALIDATE - Save Test Result JSON # save our results to the pipeline artifacts, even if the InSpec run found failing tests uses: actions/upload-artifact@v3 with: - path: results/pipeline_run.json + path: results/pipeline_run_attested.json - name: VALIDATE - Upload to Heimdall continue-on-error: true run: | - curl -# -s -F data=@results/pipeline_run.json -F "filename=${{ github.actor }}-pipeline-demo-${{ github.sha }}.json" -F "public=false" -F "evaluationTags=${{ github.repository }},${{ github.workflow }}" -H "Authorization: Api-Key ${{ secrets.HEIMDALL_API_KEY }}" "https://heimdall-demo.mitre.org/evaluations" + curl -# -s -F data=@results/pipeline_run_attested.json -F "filename=${{ github.actor }}-pipeline-demo-${{ github.sha }}.json" -F "public=false" -F "evaluationTags=${{ github.repository }},${{ github.workflow }}" -H "Authorization: Api-Key ${{ secrets.HEIMDALL_API_KEY }}" "https://heimdall-demo.mitre.org/evaluations" - name: VERIFY - Display our results summary uses: mitre/saf_action@v1 with: - command_string: "view summary -i results/pipeline_run.json" + command_string: "view summary -i results/pipeline_run_attested.json" - name: VERIFY - Ensure the scan meets our results threshold uses: mitre/saf_action@v1 # check if the pipeline passes our defined threshold with: - command_string: "validate threshold -i results/pipeline_run.json -F threshold.yml" \ No newline at end of file + command_string: "validate threshold -i results/pipeline_run_attested.json -F threshold.yml" \ No newline at end of file diff --git a/attestation.json b/attestation.json new file mode 100644 index 0000000..a419e78 --- /dev/null +++ b/attestation.json @@ -0,0 +1,10 @@ +[ + { + "control_id": "nginx-interview", + "explanation": "Interview determined that security policy is being followed.", + "frequency": "1d", + "status": "passed", + "updated": "3000-01-01", + "updated_by": "John Doe" + } +] \ No newline at end of file diff --git a/threshold.yml b/threshold.yml new file mode 100644 index 0000000..f883b89 --- /dev/null +++ b/threshold.yml @@ -0,0 +1,5 @@ +compliance: + min: 100 +error: + total: + max: 0 \ No newline at end of file From abb3b3bd65b82d2dc649d053f627255bf86bcfcd Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 01:26:49 -0400 Subject: [PATCH 09/14] fixing typo in attestation Signed-off-by: Will --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 68a281b..e85a674 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -53,7 +53,7 @@ jobs: - name: VALIDATE - Apply an Attestation uses: mitre/saf_action@v1 with: - command_string: "attest -i results/pipeline_run.json -F attestation.json -o results/pipeline_run_attested.json" + command_string: "attest apply -i results/pipeline_run.json attestation.json -o results/pipeline_run_attested.json" - name: VALIDATE - Save Test Result JSON # save our results to the pipeline artifacts, even if the InSpec run found failing tests uses: actions/upload-artifact@v3 From 67cfa6a065d0f677a7996aaaa9c08ada945ce708 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 01:35:35 -0400 Subject: [PATCH 10/14] bumping action version Signed-off-by: Will --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index e85a674..60da3ec 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -51,7 +51,7 @@ jobs: --reporter cli json:results/pipeline_run.json - name: VALIDATE - Apply an Attestation - uses: mitre/saf_action@v1 + uses: mitre/saf_action@v1.7.5 with: command_string: "attest apply -i results/pipeline_run.json attestation.json -o results/pipeline_run_attested.json" From dcf3bc21a36fa5f5e4fbd2a77708ad5d837fe9db Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 01:52:05 -0400 Subject: [PATCH 11/14] refactoring saf cli install Signed-off-by: Will --- .github/workflows/pipeline.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 60da3ec..a3de0f2 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -14,9 +14,13 @@ jobs: steps: - name: PREP - Update runner # updating all dependencies is always a good start run: sudo apt-get update + - name: PREP - Install InSpec executable run: curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec -v 5 + - name: PREP - Install SAF CLI + run: npm install -g npm && npm install -g @mitre/saf + - name: PREP - Check out this repository # because that's where our profile is! uses: actions/checkout@v3 @@ -51,9 +55,8 @@ jobs: --reporter cli json:results/pipeline_run.json - name: VALIDATE - Apply an Attestation - uses: mitre/saf_action@v1.7.5 - with: - command_string: "attest apply -i results/pipeline_run.json attestation.json -o results/pipeline_run_attested.json" + run: | + saf attest apply -i results/pipeline_run.json attestation.json -o results/pipeline_run_attested.json - name: VALIDATE - Save Test Result JSON # save our results to the pipeline artifacts, even if the InSpec run found failing tests uses: actions/upload-artifact@v3 From e159ccae2779aa859211bc5dcd42417ec576b15e Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 10:26:37 -0400 Subject: [PATCH 12/14] adding correct install step Signed-off-by: Will --- .github/workflows/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index a3de0f2..da29e6b 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -19,7 +19,7 @@ jobs: run: curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec -v 5 - name: PREP - Install SAF CLI - run: npm install -g npm && npm install -g @mitre/saf + run: npm install -g @mitre/saf - name: PREP - Check out this repository # because that's where our profile is! uses: actions/checkout@v3 From 288d5b0ddc1cd05b836515822209390e27ba9665 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 10:42:23 -0400 Subject: [PATCH 13/14] cleanup -- using saf action via direct installation instead of the GH action since the action is currently bugged, moving comments for readability Signed-off-by: Will --- .github/workflows/pipeline.yml | 50 ++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index da29e6b..54e9056 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,18 +1,23 @@ name: Demo Security Validation Gold Image Pipeline -on: # against main branch +# define the triggers for this action +on: push: - branches: [ main, pipeline ] # trigger this action on any push to main branch + # trigger this action on any push to main branch + branches: [ main, pipeline ] jobs: gold-image: name: Gold Image NGINX runs-on: ubuntu-20.04 env: - CHEF_LICENSE: accept # so that we can use InSpec without manually accepting the license - PROFILE: my_nginx # path to our profile + # so that we can use InSpec without manually accepting the license + CHEF_LICENSE: accept + # path to our profile + PROFILE: my_nginx steps: - - name: PREP - Update runner # updating all dependencies is always a good start + # updating all dependencies is always a good start + - name: PREP - Update runner run: sudo apt-get update - name: PREP - Install InSpec executable @@ -21,20 +26,25 @@ jobs: - name: PREP - Install SAF CLI run: npm install -g @mitre/saf - - name: PREP - Check out this repository # because that's where our profile is! + # checkout the profile, because that's where our profile is! + - name: PREP - Check out this repository uses: actions/checkout@v3 - - name: LINT - Run InSpec Check # double-check that we don't have any serious issues in our profile code + # double-check that we don't have any serious issues in our profile code + - name: LINT - Run InSpec Check run: inspec check $PROFILE + # launch a container as the test target - name: DEPLOY - Run a Docker container from nginx run: docker run -dit --name nginx nginx:latest + # install dependencies on the container so that hardening will work - name: DEPLOY - Install Python for our nginx container run: | docker exec nginx apt-get update -y docker exec nginx apt-get install -y python3 + # fetch the hardening role and requirements - name: HARDEN - Fetch Ansible role run: | git clone --branch docker https://github.com/mitre/ansible-nginx-stigready-hardening.git || true @@ -43,37 +53,41 @@ jobs: - name: HARDEN - Fetch Ansible requirements run: ansible-galaxy install -r ansible-nginx-stigready-hardening/requirements.yml + # harden! - name: HARDEN - Run Ansible hardening run: ansible-playbook --inventory=nginx, --connection=docker ansible-nginx-stigready-hardening/hardening-playbook.yml - name: VALIDATE - Run InSpec - continue-on-error: true # we dont want to stop if our InSpec run finds failures, we want to continue and record the result + # we dont want to stop if our InSpec run finds failures, we want to continue and record the result + continue-on-error: true run: | inspec exec $PROFILE \ --input-file=$PROFILE/inputs-linux.yml \ --target docker://nginx \ --reporter cli json:results/pipeline_run.json + # attest - name: VALIDATE - Apply an Attestation run: | saf attest apply -i results/pipeline_run.json attestation.json -o results/pipeline_run_attested.json - - name: VALIDATE - Save Test Result JSON # save our results to the pipeline artifacts, even if the InSpec run found failing tests + # save our results to the pipeline artifacts, even if the InSpec run found failing tests + - name: VALIDATE - Save Test Result JSON uses: actions/upload-artifact@v3 with: path: results/pipeline_run_attested.json + # drop off the data with our dashboard - name: VALIDATE - Upload to Heimdall continue-on-error: true run: | - curl -# -s -F data=@results/pipeline_run_attested.json -F "filename=${{ github.actor }}-pipeline-demo-${{ github.sha }}.json" -F "public=false" -F "evaluationTags=${{ github.repository }},${{ github.workflow }}" -H "Authorization: Api-Key ${{ secrets.HEIMDALL_API_KEY }}" "https://heimdall-demo.mitre.org/evaluations" + curl -# -s -F data=@results/pipeline_run_attested.json -F "filename=${{ github.actor }}-pipeline-demo-${{ github.sha }}.json" -F "public=true" -F "evaluationTags=${{ github.repository }},${{ github.workflow }}" -H "Authorization: Api-Key ${{ secrets.HEIMDALL_API_KEY }}" "https://heimdall-demo.mitre.org/evaluations" - name: VERIFY - Display our results summary - uses: mitre/saf_action@v1 - with: - command_string: "view summary -i results/pipeline_run_attested.json" - - - name: VERIFY - Ensure the scan meets our results threshold - uses: mitre/saf_action@v1 # check if the pipeline passes our defined threshold - with: - command_string: "validate threshold -i results/pipeline_run_attested.json -F threshold.yml" \ No newline at end of file + run: | + saf view summary -i results/pipeline_run_attested.json + + # check if the pipeline passes our defined threshold + - name: VERIFY - Ensure the scan meets our results threshold + run: | + saf validate threshold -i results/pipeline_run_attested.json -F threshold.yml \ No newline at end of file From 5191e0d4175c19ddd4737a63881355783267a673 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 22 Aug 2024 13:55:44 -0400 Subject: [PATCH 14/14] fixing threshold Signed-off-by: Will --- threshold.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/threshold.yml b/threshold.yml index f883b89..288f10c 100644 --- a/threshold.yml +++ b/threshold.yml @@ -1,5 +1,3 @@ -compliance: - min: 100 error: total: max: 0 \ No newline at end of file