diff --git a/.github/workflows/test-pr.yml b/.github/workflows/test-pr.yml index 97ca44717..10cb28338 100644 --- a/.github/workflows/test-pr.yml +++ b/.github/workflows/test-pr.yml @@ -53,6 +53,10 @@ jobs: - name: Checkout uses: actions/checkout@v4 + # TODO: move this into the ansible! + - name: Install cosign + uses: sigstore/cosign-installer@v3 + - name: Paths Filter # For safety using commit of dorny/paths-filter@v3 uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 diff --git a/roles/community_images/defaults/main.yml b/roles/community_images/defaults/main.yml index cbd5b750e..4f255abf6 100644 --- a/roles/community_images/defaults/main.yml +++ b/roles/community_images/defaults/main.yml @@ -64,6 +64,7 @@ community_images_azimuth_images: |- "{{ dest_key }}": { "name": "{{ image.name }}", "source_url": "{{ image.url }}", + "cosign_bundle_url": "{{ image.get("cosign-bundle-url", "todo-missing") }}", "checksum": "{{ image.checksum }}", "source_disk_format": "qcow2", "container_format": "bare", @@ -75,6 +76,9 @@ community_images_azimuth_images: |- {% endfor %} } +community_images_certificate_oidc_issuer: "https://token.actions.githubusercontent.com" +community_images_certificate_identity_regexp: "https://github.com/azimuth-cloud/azimuth-images/.github/.*" + # Slurm images are published by the ansible-slurm-appliance repo - https://github.com/stackhpc/ansible-slurm-appliance/ community_images_slurm_base_url: >- https://object.arcus.openstack.hpc.cam.ac.uk/swift/v1/AUTH_3a06571936a0424bb40bc5c672c4ccb1/openhpc-images @@ -85,6 +89,7 @@ community_images_slurm: source_url: "{{ community_images_slurm_base_url }}/openhpc-RL9-250506-1259-abb6394b" source_disk_format: qcow2 container_format: bare + cosign_bundle_url: "" # The default community images to upload community_images_default: >- diff --git a/roles/community_images/tasks/upload_image.yml b/roles/community_images/tasks/upload_image.yml index 0dcdb1040..754509bb5 100644 --- a/roles/community_images/tasks/upload_image.yml +++ b/roles/community_images/tasks/upload_image.yml @@ -48,12 +48,14 @@ community_images_image_current_visibility: "{{ community_images_image_info.stdout | from_json | json_query('visibility') }}" - name: Download, convert and upload images to Glance - when: "community_images_image_list | length == 0" + # todo when: "community_images_image_list | length == 0" block: - name: "Set image facts - {{ community_images_image_spec.name }}" ansible.builtin.set_fact: community_images_image_download_path: >- {{ (community_images_workdir, community_images_image_spec.name + '.download') | path_join }} + community_images_image_cosign_download_path: >- + {{ (community_images_workdir, community_images_image_spec.name + '.bundle') | path_join }} community_images_image_decompress_path: >- {{ (community_images_workdir, community_images_image_spec.name + '.decompress') | path_join }} community_images_image_convert_path: >- @@ -87,6 +89,25 @@ timeout: 600 mode: "0644" + - name: "Download cosign bundle - {{ community_images_image_spec.name }}" + ansible.builtin.get_url: + url: "{{ community_images_image_spec.cosign_bundle_url }}" + dest: "{{ community_images_image_cosign_download_path }}" + timeout: 120 + mode: "0644" + when: community_images_image_spec.cosign_bundle_url + + - name: "Validate downloaded image with sigstore - {{ community_images_image_spec.name }}" + ansible.builtin.shell: >- + cosign verify-blob "{{ community_images_image_download_path }}" \ + --bundle "{{ community_images_image_cosign_download_path }}" \ + --certificate-oidc-issuer="https://token.actions.githubusercontent.com" \ + --certificate-identity-regexp="https://github.com/azimuth-cloud/azimuth-images/.github/.*" + register: community_images_verify_blob_cmd + changed_when: false + failed_when: community_images_verify_blob_cmd.rc != 0 + when: community_images_image_spec.cosign_bundle_url + - name: "Uncompress image (bzip2) - {{ community_images_image_spec.name }}" ansible.builtin.shell: "bunzip2 -dc {{ community_images_image_download_path }} > {{ community_images_image_decompress_path }}" args: @@ -124,6 +145,7 @@ state: absent loop: - "{{ community_images_image_download_path }}" + - "{{ community_images_image_cosign_download_path }}" - "{{ community_images_image_decompress_path }}" - "{{ community_images_image_convert_path }}" loop_control: diff --git a/roles/infra/tasks/main.yml b/roles/infra/tasks/main.yml index a316f7fb8..25141122d 100644 --- a/roles/infra/tasks/main.yml +++ b/roles/infra/tasks/main.yml @@ -19,6 +19,7 @@ source_disk_format: "{{ infra_image_source_disk_format }}" container_format: "{{ infra_image_container_format }}" visibility: private + cosign_bundle_url: "" - name: Set infra image ID fact ansible.builtin.set_fact: