1
+ # This is a reusable workflow for scanning container images using Anchore's vulnerability scanner.
2
+ # It can be called from other workflows to scan any container image and report findings to GitHub Security tab.
3
+ name : Scan Container Image
4
+
5
+ # Define this as a reusable workflow that other workflows can call
6
+ on :
7
+ workflow_call :
8
+ # Define the inputs that callers must/can provide
9
+ inputs :
10
+ image :
11
+ required : true
12
+ type : string
13
+ description : ' Container image to scan (format: image:tag)'
14
+ severity-cutoff :
15
+ required : false
16
+ type : string
17
+ default : ' medium'
18
+ description : ' Minimum severity to report (critical, high, medium, low, negligible)'
19
+ fail-build :
20
+ required : false
21
+ type : boolean
22
+ default : false
23
+ description : ' Fail the workflow if vulnerabilities are found'
24
+ platform :
25
+ required : false
26
+ type : string
27
+ default : ' linux/amd64'
28
+ description : ' Platform to scan (e.g., linux/amd64, linux/arm64)'
29
+
30
+ permissions : {} # Remove all permissions by default
31
+
32
+ jobs :
33
+ scan :
34
+ name : Scan Image
35
+ runs-on : ubuntu-latest
36
+ timeout-minutes : 30 # Default timeout for the job
37
+ # Permissions required for security scanning and reporting
38
+ permissions :
39
+ security-events : write # Needed to upload SARIF results
40
+ contents : read # Needed to read workflow files
41
+
42
+ steps :
43
+ # Extract and normalize image details for use in later steps
44
+ # Handles cases where tag might be missing (defaults to 'latest')
45
+ # Creates a safe name for use in filenames and categories
46
+ - name : Extract image details
47
+ id : image_details
48
+ run : |
49
+ IMAGE_NAME=$(echo "${{ inputs.image }}" | cut -d':' -f1)
50
+ IMAGE_TAG=$(echo "${{ inputs.image }}" | cut -d':' -f2)
51
+ [[ "$IMAGE_TAG" == "$IMAGE_NAME" ]] && IMAGE_TAG="latest"
52
+ SAFE_NAME=$(echo "${IMAGE_NAME}-${IMAGE_TAG}" | sed 's/[\/:]/-/g')
53
+ echo "image_name=${IMAGE_NAME}" >> $GITHUB_OUTPUT
54
+ echo "image_tag=${IMAGE_TAG}" >> $GITHUB_OUTPUT
55
+ echo "safe_name=${SAFE_NAME}" >> $GITHUB_OUTPUT
56
+
57
+ # Run Anchore vulnerability scanner on the specified image
58
+ # Outputs findings in SARIF format for GitHub security dashboard
59
+ - name : Scan image with Anchore
60
+ uses : anchore/scan-action@v3
61
+ id : scan
62
+ with :
63
+ image : " ${{ inputs.image }}"
64
+ fail-build : ${{ inputs.fail-build }}
65
+ severity-cutoff : ${{ inputs.severity-cutoff }}
66
+ output-format : sarif
67
+ platform : ${{ inputs.platform }}
68
+
69
+ # Enrich the SARIF output with additional metadata about the scanned image
70
+ # This helps with tracking and identifying scan results in GitHub Security tab
71
+ - name : Enrich SARIF with image metadata
72
+ run : |
73
+ # Install jq for JSON processing
74
+ sudo apt-get update && sudo apt-get install -y jq
75
+
76
+ # Add metadata to SARIF using jq
77
+ # This includes image details, scan time, and repository information
78
+ jq --arg imageRef "${{ inputs.image }}" \
79
+ --arg repo "${{ steps.image_details.outputs.image_name }}" \
80
+ --arg name "${{ steps.image_details.outputs.image_name }}" \
81
+ --arg tag "${{ steps.image_details.outputs.image_tag }}" \
82
+ --arg scanTime "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
83
+ --arg platform "${{ inputs.platform }}" \
84
+ '.runs[0].properties = {
85
+ "imageRef": $imageRef,
86
+ "repository": $repo,
87
+ "scanTime": $scanTime,
88
+ "platform": $platform,
89
+ "imageMetadata": {
90
+ "name": $name,
91
+ "tag": $tag
92
+ }
93
+ }' results.sarif > enriched-results.sarif
94
+
95
+ mv enriched-results.sarif results.sarif
96
+
97
+ # Upload the SARIF results to GitHub Security tab
98
+ # Note: This uploads to the repository where the workflow runs, not the image source
99
+ - name : Upload SARIF file
100
+ uses : github/codeql-action/upload-sarif@v3
101
+ with :
102
+ sarif_file : results.sarif
103
+ # Create a unique category for each image to separate findings
104
+ category : " container-scan-${{ steps.image_details.outputs.safe_name }}"
105
+
106
+ # Archive the SARIF results as an artifact for later reference
107
+ # Useful for debugging or historical analysis
108
+ - name : Archive scan results
109
+ uses : actions/upload-artifact@v4
110
+ with :
111
+ name : " sarif-${{ steps.image_details.outputs.safe_name }}"
112
+ path : results.sarif
113
+ retention-days : 365
0 commit comments