44import os
55import subprocess
66import sys
7+ import json
8+ import base64
79
810excluded_products = [
911 "hello-world" ,
1214 "stackable-base" ,
1315 "trino-cli" ,
1416 "vector" ,
17+ "tools" ,
1518 "omid" ,
19+ "kcat" ,
20+ "kafka-testing-tools" ,
21+ "java-devel" ,
22+ "statsd_exporter"
1623]
1724
1825REGISTRY_URL = "docker.stackable.tech"
@@ -28,8 +35,10 @@ def main():
2835 )
2936 sys .exit (1 )
3037
31- os .makedirs ("/tmp/stackable" , exist_ok = True )
3238 os .system ("rm -rf /tmp/stackable/*" )
39+ os .makedirs ("/tmp/stackable/trivy_tmp" , exist_ok = True )
40+ os .makedirs ("/tmp/stackable/trivy_cache" , exist_ok = True )
41+ os .makedirs ("/tmp/stackable/grype_db_cache" , exist_ok = True )
3342
3443 with tempfile .TemporaryDirectory () as tempdir :
3544 # dump argv to console
@@ -69,49 +78,69 @@ def main():
6978 "zookeeper" ,
7079 ]
7180
72- for operator_name in operators :
73- product_name = f"{ operator_name } -operator"
74- scan_image (secobserve_api_token , f"{ REGISTRY_URL } /stackable/{ product_name } :{ release } " , product_name , release )
81+ for arch in ["amd64" , "arm64" ]:
82+ for operator_name in operators :
83+ product_name = f"{ operator_name } -operator"
84+ scan_image (secobserve_api_token , f"{ REGISTRY_URL } /stackable/{ product_name } :{ release } -{ arch } " , product_name , release )
7585
76- # Load product versions from that file using the image-tools functionality
77- sys .path .append ("docker-images" )
78- product_versions = load_configuration ("docker-images/conf.py" )
86+ # Load product versions from that file using the image-tools functionality
87+ sys .path .append ("docker-images" )
88+ product_versions = load_configuration ("docker-images/conf.py" )
7989
80- for product in product_versions .products :
81- product_name : str = product ["name" ]
90+ for product in product_versions .products :
91+ product_name : str = product ["name" ]
8292
83- if product_name in excluded_products :
84- continue
85- for version_dict in product .get ("versions" , []):
86- version : str = version_dict ["product" ]
87- product_version = f"{ version } -stackable{ release } "
88- scan_image (
89- secobserve_api_token ,
90- f"{ REGISTRY_URL } /stackable/{ product_name } :{ product_version } " ,
91- product_name ,
92- product_version ,
93- )
93+ if product_name in excluded_products :
94+ continue
95+ for version_dict in product .get ("versions" , []):
96+ version : str = version_dict ["product" ]
97+ product_version = f"{ version } -stackable{ release } "
98+ scan_image (
99+ secobserve_api_token ,
100+ f"{ REGISTRY_URL } /stackable/{ product_name } :{ product_version } - { arch } " ,
101+ product_name ,
102+ product_version ,
103+ )
94104
95105
96106def scan_image (secobserve_api_token : str , image : str , product_name : str , product_version : str ) -> None :
107+ extract_sbom_cmd = [
108+ "cosign" ,
109+ "verify-attestation" ,
110+ "--type" ,
111+ "cyclonedx" ,
112+ "--certificate-identity-regexp" ,
113+ "^https://github.com/stackabletech/.+/.github/workflows/.+@.+" ,
114+ "--certificate-oidc-issuer" ,
115+ "https://token.actions.githubusercontent.com" ,
116+ image .replace ("docker.stackable.tech/stackable/" , "oci.stackable.tech/sdp/" ),
117+ ];
118+ print (" " .join (extract_sbom_cmd ))
119+
120+ result = subprocess .run (extract_sbom_cmd , stdout = subprocess .PIPE , stderr = subprocess .PIPE )
121+ cosign_output = json .loads (result .stdout .decode ('utf-8' ))
122+ payload = base64 .b64decode (cosign_output ["payload" ]).decode ('utf-8' )
123+ sbom = json .loads (payload )["predicate" ]
124+ with open ("/tmp/stackable/bom.json" , "w" ) as f :
125+ json .dump (sbom , f )
126+
97127 # Run Trivy
98128 env = {}
99- env ["TARGET" ] = image
129+ env ["TARGET" ] = "/tmp/bom.json"
100130 env ["SO_UPLOAD" ] = "true"
101131 env ["SO_PRODUCT_NAME" ] = product_name
102132 env ["SO_API_BASE_URL" ] = "https://secobserve-backend.stackable.tech"
103133 env ["SO_API_TOKEN" ] = secobserve_api_token
104134 env ["SO_BRANCH_NAME" ] = product_version
105- env ["TMPDIR" ] = "/tmp"
135+ env ["TMPDIR" ] = "/tmp/trivy_tmp"
136+ env ["TRIVY_CACHE_DIR" ] = "/tmp/trivy_cache"
106137 env ["REPORT_NAME" ] = "trivy.json"
107138
108- print (f"Scanning { env ['TARGET' ]} with Trivy" )
109-
110139 cmd = [
111140 "docker" ,
112141 "run" ,
113142 "--entrypoint" ,
114- "/entrypoints/entrypoint_trivy_image .sh" ,
143+ "/entrypoints/entrypoint_trivy_sbom .sh" ,
115144 "-v" ,
116145 "/tmp/stackable:/tmp" ,
117146 "-v" ,
@@ -122,22 +151,21 @@ def scan_image(secobserve_api_token: str, image: str, product_name: str, product
122151 cmd .append ("-e" )
123152 cmd .append (f"{ key } ={ value } " )
124153
125- cmd .append ("maibornwolff /secobserve-scanners:latest" )
154+ cmd .append ("oci.stackable.tech/sandbox /secobserve-scanners:latest" )
126155
156+ print (" " .join (cmd ))
127157 subprocess .run (cmd )
128158
129159 # Run Grype
130- print (f"Scanning { env ['TARGET' ]} with Grype" )
131-
132160 env ["FURTHER_PARAMETERS" ] = "--by-cve"
133- env ["GRYPE_DB_CACHE_DIR" ] = "/tmp"
161+ env ["GRYPE_DB_CACHE_DIR" ] = "/tmp/grype_db_cache "
134162 env ["REPORT_NAME" ] = "grype.json"
135163
136164 cmd = [
137165 "docker" ,
138166 "run" ,
139167 "--entrypoint" ,
140- "/entrypoints/entrypoint_grype_image .sh" ,
168+ "/entrypoints/entrypoint_grype_sbom .sh" ,
141169 "-v" ,
142170 "/tmp/stackable:/tmp" ,
143171 "-v" ,
@@ -148,7 +176,7 @@ def scan_image(secobserve_api_token: str, image: str, product_name: str, product
148176 cmd .append ("-e" )
149177 cmd .append (f"{ key } ={ value } " )
150178
151- cmd .append ("maibornwolff /secobserve-scanners:latest" )
179+ cmd .append ("oci.stackable.tech/sandbox /secobserve-scanners:latest" )
152180
153181 subprocess .run (cmd )
154182
0 commit comments