feat(attestation): implement attestation verification in glab

Description

This MR does the following:

In order to achieve this, two changes to dependencies have been introduced. These are:

What are "Sigstore bundles"?

The grouppipeline security group is working towards providing users with SLSA Level 3 Provenance Attestations. Quoting from the SLSA documentation, it states that attestations are:

It’s the verifiable information about software artifacts describing where, when, and how something was produced. For higher SLSA levels and more resilient integrity guarantees, provenance requirements are stricter and need a deeper, more technical understanding of the predicate. Describe how an artifact or set of artifacts was produced so that:

  • Consumers of the provenance can verify that the artifact was built according to expectations.
  • Others can rebuild the artifact, if desired.

As a simplified TL;DR, in the context of GitLab, a provenance statement is a JSON document that correlates the SHA-256 sum of an artifact with the build information. A worker then performs a digital signature, called a provenance attestation, stored as a "Sigstore Bundle" blob. This is a highly sought-after feature, particularly for our GitLab Ultimate customers.

How has this been tested?

This can be tested against the production environment APIs with the following command. Note the commands below don't require authentication because they're against a public project.

~/code/cli % make && ./bin/glab attestation verify ~/ATTEST_ME.txt -p sroque-worcel/test-slsa-worker
go build -trimpath -ldflags "-X main.commit=f1fdfa89  -X main.version=v1.77.0 -X main.debugMode=false -w -s" -o ./bin/glab gitlab.com/gitlab-org/cli/cmd/glab
Artifact provenance successfully verified. Signatures confirm /Users/samroque-worcel/ATTEST_ME.txt was attested by sroque-worcel/test-slsa-worker%

~/code/cli % make && ./bin/glab attestation verify ~/json-pretty.txt -p sroque-worcel/test-slsa-worker
go build -trimpath -ldflags "-X main.commit=f1fdfa89  -X main.version=v1.77.0 -X main.debugMode=false -w -s" -o ./bin/glab gitlab.com/gitlab-org/cli/cmd/glab

   ERROR

  Unable to find a provenance statement for 1f9e5808a340916aa5618ee13a893dcf9d4f7e2d42a254be0f7eb06a094ab8ea.

More verbose output:

make && GLAB_DEBUG_HTTP=1 ./bin/glab attestation verify ~/ATTEST_ME.txt -p sroque-worcel/test-slsa-worker
go build -trimpath -ldflags "-X main.commit=f1fdfa89  -X main.version=v1.77.0 -X main.debugMode=false -w -s" -o ./bin/glab gitlab.com/gitlab-org/cli/cmd/glab
REQUEST:
GET /api/v4/projects/sroque-worcel%2Ftest-slsa-worker/attestations/76c34666f719ef14bd2b124a7db51e9c05e4db2e12a84800296d559064eebe2c HTTP/1.1
Host: gitlab.com
User-Agent: glab/v1.77.0 (darwin, arm64)
Accept: application/json
Authorization: [REDACTED]
Accept-Encoding: gzip



RESPONSE:
HTTP/2.0 200 OK
Cache-Control: max-age=0, private, must-revalidate
Cf-Cache-Status: MISS
Cf-Ray: 9a456b06cc54d9b2-AKL
Content-Security-Policy: default-src 'none'
Content-Type: application/json
Date: Wed, 26 Nov 2025 00:55:03 GMT
Etag: W/"78e2ae9db0dee4de9358bd533d77b4d8"
Gitlab-Lb: haproxy-main-56-lb-gprd
Gitlab-Sv: api-gke-us-east1-c
Link: <https://gitlab.com/api/v4/projects/sroque-worcel%2Ftest-slsa-worker/attestations/76c34666f719ef14bd2b124a7db51e9c05e4db2e12a84800296d559064eebe2c?id=sroque-worcel%2Ftest-slsa-worker&page=1&per_page=20&subject_digest=76c34666f719ef14bd2b124a7db51e9c05e4db2e12a84800296d559064eebe2c>; rel="first", <https://gitlab.com/api/v4/projects/sroque-worcel%2Ftest-slsa-worker/attestations/76c34666f719ef14bd2b124a7db51e9c05e4db2e12a84800296d559064eebe2c?id=sroque-worcel%2Ftest-slsa-worker&page=1&per_page=20&subject_digest=76c34666f719ef14bd2b124a7db51e9c05e4db2e12a84800296d559064eebe2c>; rel="last"
Nel: {"max_age": 0}
Ratelimit-Limit: 2000
Ratelimit-Name: throttle_authenticated_api
Ratelimit-Observed: 1
Ratelimit-Remaining: 1999
Ratelimit-Reset: 1764118560
Referrer-Policy: strict-origin-when-cross-origin
Server: cloudflare
Set-Cookie: __cf_bm=ZIvsIHpU.j1ZTTCmS85qRVQNTRU1GziCxZV5X5U_Wcs-1764118503-1.0.1.1-oWNgXahHszCpaDDyZtu7pmKyjkY5MEzLTPFLhKtz8wQHwAp.Wm2YFmQFA6diYa4vVAn30C9TAf6P6cwrZBPfKZtaOwtntSNhz_DgCr8B_fE; path=/; expires=Wed, 26-Nov-25 01:25:03 GMT; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
Set-Cookie: _cfuvid=ZaVDpXY6tG6EO6D56OBfcV5htF48MxCIvzTPQxogBWw-1764118503923-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
Strict-Transport-Security: max-age=31536000
Vary: Origin, Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Gitlab-Meta: {"correlation_id":"9a456b0721abd9b2-ATL","version":"1"}
X-Next-Page:
X-Page: 1
X-Per-Page: 20
X-Prev-Page:
X-Request-Id: 9a456b0721abd9b2-ATL
X-Runtime: 0.108493
X-Total: 1
X-Total-Pages: 1

[{"id":1,"iid":1,"created_at":"2025-10-07T20:59:27.085Z","updated_at":"2025-10-07T20:59:27.085Z","expire_at":"2027-10-07T20:59:26.967Z","project_id":72356192,"build_id":11637492236,"status":"success","predicate_kind":"provenance","predicate_type":"https://slsa.dev/provenance/v1","subject_digest":"76c34666f719ef14bd2b124a7db51e9c05e4db2e12a84800296d559064eebe2c","download_url":"https://gitlab.com/api/v4/projects/72356192/attestations/1/download"}]

REQUEST:
GET /api/v4/projects/sroque-worcel%2Ftest-slsa-worker/attestations/1/download HTTP/1.1
Host: gitlab.com
User-Agent: glab/v1.77.0 (darwin, arm64)
Accept: application/json
Authorization: [REDACTED]
Accept-Encoding: gzip



RESPONSE:
HTTP/2.0 200 OK
Content-Length: 21655
Accept-Ranges: bytes
Cache-Control: max-age=0, private, must-revalidate
Cf-Cache-Status: MISS
Cf-Ray: 9a456b099eb1d9b2-AKL
Content-Security-Policy: default-src 'none'
Content-Type: text/json
Date: Wed, 26 Nov 2025 00:55:04 GMT
Etag: W/"23548cc023df78433bc5fcceeccc2d79"
Gitlab-Lb: haproxy-main-02-lb-gprd
Gitlab-Sv: api-gke-us-east1-c
Nel: {"max_age": 0}
Ratelimit-Limit: 2000
Ratelimit-Name: throttle_authenticated_api
Ratelimit-Observed: 2
Ratelimit-Remaining: 1998
Ratelimit-Reset: 1764118560
Referrer-Policy: strict-origin-when-cross-origin
Server: cloudflare
Set-Cookie: __cf_bm=hhjbxYi69XbPh1wJwq1wS1GujJ8Yp.mg3wcqHGbkPDY-1764118504-1.0.1.1-OrGalC.IVcdFGbKzqQ5jH1DV3iHoUPkNFP5WeHp3cnhST6TZLQ3_ac79IuCFO_XR_rC.BjKRl1C9c0qT2ugd7cisbwjJAyqaaZGzPSo9_B4; path=/; expires=Wed, 26-Nov-25 01:25:04 GMT; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
Set-Cookie: _cfuvid=c2ZhuzvdxDEfnu6h0l2iABG45b8VKF3c9FkLWETSQGk-1764118504504-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
Strict-Transport-Security: max-age=31536000
Vary: Origin, Accept-Encoding
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Gitlab-Meta: {"correlation_id":"9a456b09b60cd9b2-ATL","version":"1"}
X-Request-Id: 9a456b09b60cd9b2-ATL
X-Runtime: 0.282901

{"mediaType":"application/vnd.dev.sigstore.bundle.v0.3+json", "verificationMaterial":{"certificate":{"rawBytes":"MIIF2zCCBWCgAwIBAgIUaQ+U+6Yen7x8ggsePuCDB6iRtgEwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjUxMDA3MjA1OTI2WhcNMjUxMDA3MjEwOTI2WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFgkUqRg2+hKTDgEu4mkQwyzegHzvnGTgvh2MGngNiudMipGLSufnW4U9P+cWIKdUqYVbSwiZOFKBhq9kexdJGqOCBH8wggR7MA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUOJj1iTs/i1/ALaREFVdIdHjIbSgwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wXwYDVR0RAQH/BFUwU4ZRaHR0cHM6Ly9naXRsYWIuY29tL3Nyb3F1ZS13b3JjZWwvdGVzdC1zbHNhLXdvcmtlci8vLmdpdGxhYi1jaS55bWxAcmVmcy9oZWFkcy9tYWluMCAGCisGAQQBg78wAQEEEmh0dHBzOi8vZ2l0bGFiLmNvbTAiBgorBgEEAYO/MAEIBBQMEmh0dHBzOi8vZ2l0bGFiLmNvbTBhBgorBgEEAYO/MAEJBFMMUWh0dHBzOi8vZ2l0bGFiLmNvbS9zcm9xdWUtd29yY2VsL3Rlc3Qtc2xzYS13b3JrZXIvLy5naXRsYWItY2kueW1sQHJlZnMvaGVhZHMvbWFpbjA4BgorBgEEAYO/MAEKBCoMKGVhZmEwYTY4MjBiN[...]

Artifact provenance successfully verified. Signatures confirm /Users/samroque-worcel/ATTEST_ME.txt was attested by sroque-worcel/test-slsa-worker%

Screenshots (if appropriate):

image

Edited by Sam Roque-Worcel

Merge request reports

Loading