Skip to content

Commit e562dc8

Browse files
St0rmz1laverya
andauthored
add jobs to scan released images (#2020)
* add jobs to scan released images * change comment to be accurate that we are scanning the registry image * Update .github/workflows/daily-container-scans.yml Co-authored-by: Andrew Lavery <[email protected]> --------- Co-authored-by: Andrew Lavery <[email protected]>
1 parent e755626 commit e562dc8

File tree

2 files changed

+191
-0
lines changed

2 files changed

+191
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Container Security Scans
2+
# This workflow orchestrates security scanning of container images using Anchore scanner.
3+
# It runs nightly and can be triggered manually to scan various container images for vulnerabilities.
4+
name: Container Security Scans
5+
6+
# Trigger configuration
7+
on:
8+
schedule:
9+
- cron: '0 0 * * *' # Runs nightly at midnight (UTC)
10+
workflow_dispatch: # Allows manual triggering through GitHub UI
11+
12+
# Security hardening: Start with no permissions and grant only what's needed
13+
permissions: {} # Remove all permissions by default
14+
15+
# Prevent multiple workflow runs from interfering with each other
16+
# This ensures only one scan runs at a time and new triggers cancel old runs
17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.ref }}
19+
cancel-in-progress: true
20+
21+
jobs:
22+
# Get the latest release tag first
23+
get-latest-tag:
24+
name: Get Latest Release Tag
25+
runs-on: ubuntu-latest
26+
permissions:
27+
contents: read # Needed to read releases
28+
outputs:
29+
tag_name: ${{ steps.get_release.outputs.tag_name }}
30+
steps:
31+
- name: Get latest release
32+
id: get_release
33+
uses: actions/github-script@v6
34+
with:
35+
script: |
36+
const release = await github.rest.repos.getLatestRelease({
37+
owner: context.repo.owner,
38+
repo: context.repo.repo
39+
});
40+
core.setOutput('tag_name', release.data.tag_name);
41+
42+
# Scan operator image using latest release tag
43+
scan-operator:
44+
name: Scan Operator Image
45+
needs: get-latest-tag # Wait for tag to be fetched
46+
uses: ./.github/workflows/scan-container-image.yml
47+
# Grant required permissions to the reusable workflow
48+
permissions:
49+
contents: read # Needed to read workflow files
50+
security-events: write # Needed to upload SARIF results
51+
with:
52+
# Use the latest release tag from the previous job
53+
image: replicated/embedded-cluster-operator-image:${{ needs.get-latest-tag.outputs.tag_name }}
54+
# Report findings of medium severity or higher
55+
severity-cutoff: medium
56+
# Continue even if vulnerabilities are found
57+
fail-build: false
58+
# Specify platform to scan
59+
platform: linux/amd64
60+
61+
# Scan local artifact mirror image using latest release tag
62+
scan-registry:
63+
name: Scan Local Artifact Mirror Image
64+
needs: get-latest-tag # Wait for tag to be fetched
65+
uses: ./.github/workflows/scan-container-image.yml
66+
# Grant required permissions to the reusable workflow
67+
permissions:
68+
contents: read # Needed to read workflow files
69+
security-events: write # Needed to upload SARIF results
70+
with:
71+
# Use the latest release tag from the previous job
72+
image: replicated/embedded-cluster-local-artifact-mirror:${{ needs.get-latest-tag.outputs.tag_name }}
73+
# Report findings of medium severity or higher
74+
severity-cutoff: medium
75+
# Continue even if vulnerabilities are found
76+
fail-build: false
77+
# Specify platform to scan
78+
platform: linux/amd64
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
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

Comments
 (0)