-
Notifications
You must be signed in to change notification settings - Fork 9
(v1.4.1 hotfix) Fix multi-arch container image scanning #136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 14 commits
38bef58
8af1823
912bfff
d0d77dc
736a9f4
136e9a8
84a8ccc
0f8fa68
afbd08d
bff0cb4
7c6cf78
915bac2
0c2ec1c
873ffae
4ef1602
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
name: Test Multi-arch images | ||
|
||
on: | ||
schedule: | ||
- cron: '0 */6 * * *' # runs every 6 hours | ||
push: | ||
branches: # | ||
- '*' | ||
|
||
permissions: | ||
contents: read | ||
id-token: write | ||
|
||
jobs: | ||
test_multi_arch: | ||
runs-on: ubuntu-latest | ||
environment: | ||
name: plugin-development | ||
strategy: | ||
matrix: | ||
platform: | ||
- "linux/386" | ||
- "linux/amd64" | ||
- "linux/arm/v5" | ||
- "linux/arm/v7" | ||
- "linux/arm64/v8" | ||
- "linux/ppc64le" | ||
- "linux/riscv64" | ||
- "linux/s390x" | ||
|
||
steps: | ||
|
||
- name: Checkout this repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Configure AWS credentials | ||
uses: aws-actions/configure-aws-credentials@v4 | ||
with: | ||
aws-region: ${{ secrets.AWS_REGION }} | ||
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | ||
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | ||
role-to-assume: ${{ secrets.AWS_IAM_ROLE }} | ||
|
||
- name: Test multi-arch image - ${{ matrix.platform }} | ||
id: inspector | ||
uses: aws-actions/vulnerability-scan-github-action-for-amazon-inspector@investigate_multi_arch | ||
bluesentinelsec marked this conversation as resolved.
Show resolved
Hide resolved
|
||
with: | ||
artifact_type: 'container' | ||
artifact_path: 'debian:trixie' | ||
platform: ${{ matrix.platform }} | ||
display_vulnerability_findings: "enabled" | ||
sbomgen_version: "latest" | ||
|
||
- name: Demonstrate SBOM Output (JSON) | ||
run: cat ${{ steps.inspector.outputs.artifact_sbom }} | ||
|
||
- name: Display scan results | ||
run: cat ${{ steps.inspector.outputs.inspector_scan_results }} | ||
|
||
- name: Validate multi-arch - ${{ matrix.platform }} | ||
run: python3 validator/validate_multi_platform_image_support.py --platform "${{ matrix.platform }}" --sbom "${{ steps.inspector.outputs.artifact_sbom }}" | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,6 +162,7 @@ runs: | |
- --thresholds | ||
- ${{ inputs.threshold_fixable_only == 'true' && '--threshold-fixable-only' || '--no-op' }} | ||
- ${{ inputs.show_only_fixable_vulns == 'true' && '--show-only-fixable-vulns'|| '--no-op' }} | ||
- --platform=${{ inputs.platform || '' }} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you tell me how this works when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When the user does not specify a platform, the action passes the argument: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Non-blocking] I checked inspector-sbomgen's source code, and confirmed empty string is treated as platform is not set. However, since this depends on inspector-sbomgen's internal implementation, would it be possible to avoid passing the --platform option to inspector-sbomgen's container or inspector-sbomgen? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notionally speaking, if the user did not specify platform, we could avoid sending the platform flag to the Python layer by sending a no-op, similar to this line:
This pattern works well for bool CLI variables, but its less effective for string variables, as in this case, because then you have to write extra code to handle no-op strings. Since |
||
- --critical=${{ inputs.critical_threshold }} | ||
- --high=${{ inputs.high_threshold }} | ||
- --medium=${{ inputs.medium_threshold }} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import argparse | ||
import json | ||
import sys | ||
|
||
|
||
def get_expected_arch(platform): | ||
"""Map platform string to expected architecture value in SBOM""" | ||
platform_to_arch = { | ||
"linux/386": "386", | ||
"linux/amd64": "amd64", | ||
"linux/arm/v5": "arm", | ||
"linux/arm/v7": "arm", | ||
"linux/arm64/v8": "arm64", | ||
"linux/ppc64le": "ppc64le", | ||
"linux/riscv64": "riscv64", | ||
"linux/s390x": "s390x" | ||
} | ||
|
||
if platform not in platform_to_arch: | ||
raise ValueError(f"Unknown platform: {platform}") | ||
|
||
return platform_to_arch[platform] | ||
|
||
|
||
def extract_arch_from_sbom(sbom_file): | ||
"""Extract architecture from SBOM metadata""" | ||
try: | ||
with open(sbom_file, 'r') as f: | ||
sbom = json.load(f) | ||
|
||
properties = sbom.get('metadata', {}).get('component', {}).get('properties', []) | ||
|
||
for prop in properties: | ||
if prop.get('name') == 'amazon:inspector:sbom_generator:image_arch': | ||
return prop.get('value') | ||
|
||
raise ValueError("Architecture property not found in SBOM") | ||
|
||
except Exception as e: | ||
raise ValueError(f"Failed to parse SBOM: {e}") | ||
|
||
|
||
def main(): | ||
parser = argparse.ArgumentParser(description='Validate SBOM architecture matches expected platform') | ||
parser.add_argument('--platform', required=True, help='Expected platform (e.g., linux/amd64)') | ||
parser.add_argument('--sbom', required=True, help='Path to SBOM file') | ||
|
||
args = parser.parse_args() | ||
|
||
try: | ||
expected_arch = get_expected_arch(args.platform) | ||
actual_arch = extract_arch_from_sbom(args.sbom) | ||
|
||
print(f"Platform: {args.platform}") | ||
print(f"Expected arch: {expected_arch}") | ||
print(f"Actual arch: {actual_arch}") | ||
|
||
if actual_arch != expected_arch: | ||
print(f"β Architecture mismatch for platform {args.platform}") | ||
print(f" Expected: {expected_arch}") | ||
print(f" Found: {actual_arch}") | ||
sys.exit(1) | ||
|
||
print(f"β Architecture validation passed: {actual_arch} matches expected {expected_arch}") | ||
|
||
except Exception as e: | ||
print(f"β Validation failed: {e}") | ||
bluesentinelsec marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
sys.exit(1) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Uh oh!
There was an error while loading. Please reload this page.