
Integrating Inspector with Gitlab CI/CD
How to integrate Inspector with GitLab, my experiences with it, and why do it.
- Create an IAM resource that can perform the
inspector-scan:ScanSbom
action. - Download the SBOM Generator.
- Generate an SBOM based on the container image.
- Call the
inspector-scan
API while referencing the SBOM.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
build_image:
stage: build
script:
- docker build --file Dockerfile --tag $CI_REGISTRY_IMAGE/$NAME:$CI_COMMIT_SHORT_SHA.
- docker push $CI_REGISTRY_IMAGE/$NAME:$CI_COMMIT_SHORT_SHA
inspector_container_scanning:
stage: test
script:
- echo "Installing Inspector SBOM"
- apk upgrade --no-cache && apk add python3 py3-pip tar unzip
- wget https://amazon-inspector-sbomgen.s3.amazonaws.com/latest/linux/amd64/inspector-sbomgen.zip
-O inspector-sbomgen.zip
- unzip inspector-sbomgen.zip
- mv inspector-sbomgen-1.0.0/linux/amd64/inspector-sbomgen ./inspector-sbomgen
- chmod +x ./inspector-sbomgen
- "./inspector-sbomgen --version"
- "./inspector-sbomgen container --image $CI_REGISTRY_IMAGE/$NAME:$CI_COMMIT_SHORT_SHA -o sbom.json"
- pip3 install awscli
- aws inspector-scan scan-sbom --sbom file://sbom.json --output-format "CYCLONE_DX_1_5" --endpoint "https://inspector-scan.us-west-2.amazonaws.com" --region us-west-2 > output.json
artifacts:
paths:
- output.json
parse_results:
stage: report
image: ruby:3.2
script:
- ruby scripts/parse.rb
$CI_REGISTRY_IMAGE
and $CI_COMMIT_SHORT_SHA
are both predefined GitLab CI/CD variables. $NAME
would be the name of your choosing.inspector_container_scanning
job handles most of the work: Getting the SBOMGen binary, ensuring it’s executable, generating the SBOM, and calling the inspector-scan
API. Just a handful of commands.scripts/parse.rb
is just a simple script that iterates over output.json
to find the counts of each vulnerability type:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# frozen_string_literal: true
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'json'
end
require 'json'
file = File.read('output.json')
data = JSON.parse(file)
vulnerabilities = data['sbom']['metadata']['properties']
exit_code = 0
summary = vulnerabilities.each_with_object(Hash.new(0)) do |vuln, counts|
severity = vuln['name'].split(':').last.split('_').first
count = vuln['value'].to_i
counts[severity] += count
end
puts 'Vulnerability Summary:'
puts '-' * 40
summary.each do |severity, count|
puts "#{severity.capitalize} Vulnerabilities: #{count}"
exit_code = 1 if %w[critical high].include?(severity)
end
puts ''
puts '-' * 40
puts ''
if exit_code == 1
puts 'Critical or High Vulns Found'
exit 1
endr
HIGH
or CRITICAL
vulns are found.inspector-scan
API call was a little easy to parse through, but with time, I think a solution would be easy enough to create.