Create Attestations Show View

Why are we doing this work

In order for SLSA attestations to be discoverable at a project level, a show view will need to be added to the UI. The scope of this issue is build out the implementation described below.

The view should be available at the path /:project_path/attestations/:iid and should reflect the UI described in this design.

The visibility should match that of the project, so if the project is public, the attestation should be publicly visible.

This change will also require that iid support is added to the attestations table in the database. This should already be available.

This should be developed behind the slsa_provenance_statement feature flag.

Refer to the following links for more information:

Implementation plan

Overview

Since the pages are static, we'll implement the UI using HAML views instead of Vue. The routes should already be implemented as part of the first MR for #566593.

The page should implement the following:

  • Render 404 if the user doesn't have read access to the project or if the feature flag is disabled
  • Render attestation details, including subjects and certificate details
  • Provide a download link
  • Make sure to show error messages and empty states when appropriate.

Details

We can supply the data via the controller.

class Projects::AttestationsController < Projects::ApplicationController
  def index
    @attestation = SupplyChain::Attestation
      .for_project(@project.id)
      .find_by!(iid: params[:id])
  end
end

Following the steps for creating an attestation file below, we can get the metadata through the following:

attestation = SupplyChain::Attestation.find(ID)
data = attestation.file.read
parsed = JSON.parse(data)
decoded = Base64.decode64(parsed["dsseEnvelope"]["payload"])
parsed_decoded = JSON.parse(decoded) # provenance document as a ruby hash

Verification steps

To create an attestation for your project with the associated build data:

  1. Make sure your project is public and that you have runner running on your gdk.
  2. Create a .gitlab-ci.yml in your project. In the UI, you can use the pipeline editor (Build > Pipeline editor):
    test-job:
      stage: build
      script:
        - echo "Building artifact"
        - echo "test content" > artifact.txt
        - tar -czf artifact.tar.gz artifact.txt
      artifacts:
        paths:
          - artifact.tar.gz
  3. Once saved, a pipeline should automatically run. Wait for it to complete.
  4. In the Rails console, manually create an attestation and associate it with build that was just generated:
    project = Project.find_by_full_path('namespace/project')
    build = project.builds.last
    
    data = URI("https://gitlab.com/gitlab-org/software-supply-chain-security/tools/sigstore-local/-/raw/main/sample.sigstore.json").read
    temp_file = Tempfile.new('sample.sigstore.json')
    temp_file.write(data)
    temp_file.rewind
    
    attestation = SupplyChain::Attestation.create!(
      project: build.project,
      build_id: build.id,
      status: "success",
      predicate_kind: "provenance",
      predicate_type: "https://slsa.dev/provenance/v1",
      subject_digest: "e6e5f634effc310a2a38bea8f71fec08eca20489763628a6e66951265df2177c",
      file: temp_file
    )

The view should be available at the path /:project_path/attestations/:iid.

Edited by Mireya Andres