@@ -172,7 +172,7 @@ jobs:
172
172
173
173
- name : Get golangci-lint cache dir
174
174
run : |
175
- linter_ver=$(egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/contents /Dockerfile | cut -d '=' -f 2)
175
+ linter_ver=$(egrep -o 'GOLANGCI_LINT_VERSION=\S+' dogfood/coder /Dockerfile | cut -d '=' -f 2)
176
176
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v$linter_ver
177
177
dir=$(golangci-lint cache status | awk '/Dir/ { print $2 }')
178
178
echo "LINT_CACHE_DIR=$dir" >> $GITHUB_ENV
@@ -1024,7 +1024,11 @@ jobs:
1024
1024
# Necessary to push docker images to ghcr.io.
1025
1025
packages : write
1026
1026
# Necessary for GCP authentication (https://github.com/google-github-actions/setup-gcloud#usage)
1027
+ # Also necessary for keyless cosign (https://docs.sigstore.dev/cosign/signing/overview/)
1028
+ # And for GitHub Actions attestation
1027
1029
id-token : write
1030
+ # Required for GitHub Actions attestation
1031
+ attestations : write
1028
1032
env :
1029
1033
DOCKER_CLI_EXPERIMENTAL : " enabled"
1030
1034
outputs :
@@ -1041,7 +1045,7 @@ jobs:
1041
1045
fetch-depth : 0
1042
1046
1043
1047
- name : GHCR Login
1044
- uses : docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3 .0
1048
+ uses : docker/login-action@74a5d142397b4f367a81961eba4e8cd7edddf772 # v3.4 .0
1045
1049
with :
1046
1050
registry : ghcr.io
1047
1051
username : ${{ github.actor }}
@@ -1069,6 +1073,16 @@ jobs:
1069
1073
- name : Install zstd
1070
1074
run : sudo apt-get install -y zstd
1071
1075
1076
+ - name : Install cosign
1077
+ uses : sigstore/cosign-installer@d7d6bc7722e3daa8354c50bcb52f4837da5e9b6a # v3.8.1
1078
+ with :
1079
+ cosign-release : " v2.4.3"
1080
+
1081
+ - name : Install syft
1082
+ uses : anchore/sbom-action/download-syft@f325610c9f50a54015d37c8d16cb3b0e2c8f4de0 # v0.18.0
1083
+ with :
1084
+ syft-version : " v1.20.0"
1085
+
1072
1086
- name : Setup Windows EV Signing Certificate
1073
1087
run : |
1074
1088
set -euo pipefail
@@ -1170,6 +1184,138 @@ jobs:
1170
1184
done
1171
1185
fi
1172
1186
1187
+ # GitHub attestation provides SLSA provenance for the Docker images, establishing a verifiable
1188
+ # record that these images were built in GitHub Actions with specific inputs and environment.
1189
+ # This complements our existing cosign attestations which focus on SBOMs.
1190
+ #
1191
+ # We attest each tag separately to ensure all tags have proper provenance records.
1192
+ # TODO: Consider refactoring these steps to use a matrix strategy or composite action to reduce duplication
1193
+ # while maintaining the required functionality for each tag.
1194
+ - name : GitHub Attestation for Docker image
1195
+ id : attest_main
1196
+ if : github.ref == 'refs/heads/main'
1197
+ continue-on-error : true
1198
+ uses : actions/attest@a63cfcc7d1aab266ee064c58250cfc2c7d07bc31 # v2.2.1
1199
+ with :
1200
+ subject-name : " ghcr.io/coder/coder-preview:main"
1201
+ predicate-type : " https://slsa.dev/provenance/v1"
1202
+ predicate : |
1203
+ {
1204
+ "buildType": "https://github.com/actions/runner-images/",
1205
+ "builder": {
1206
+ "id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
1207
+ },
1208
+ "invocation": {
1209
+ "configSource": {
1210
+ "uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
1211
+ "digest": {
1212
+ "sha1": "${{ github.sha }}"
1213
+ },
1214
+ "entryPoint": ".github/workflows/ci.yaml"
1215
+ },
1216
+ "environment": {
1217
+ "github_workflow": "${{ github.workflow }}",
1218
+ "github_run_id": "${{ github.run_id }}"
1219
+ }
1220
+ },
1221
+ "metadata": {
1222
+ "buildInvocationID": "${{ github.run_id }}",
1223
+ "completeness": {
1224
+ "environment": true,
1225
+ "materials": true
1226
+ }
1227
+ }
1228
+ }
1229
+ push-to-registry : true
1230
+
1231
+ - name : GitHub Attestation for Docker image (latest tag)
1232
+ id : attest_latest
1233
+ if : github.ref == 'refs/heads/main'
1234
+ continue-on-error : true
1235
+ uses : actions/attest@a63cfcc7d1aab266ee064c58250cfc2c7d07bc31 # v2.2.1
1236
+ with :
1237
+ subject-name : " ghcr.io/coder/coder-preview:latest"
1238
+ predicate-type : " https://slsa.dev/provenance/v1"
1239
+ predicate : |
1240
+ {
1241
+ "buildType": "https://github.com/actions/runner-images/",
1242
+ "builder": {
1243
+ "id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
1244
+ },
1245
+ "invocation": {
1246
+ "configSource": {
1247
+ "uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
1248
+ "digest": {
1249
+ "sha1": "${{ github.sha }}"
1250
+ },
1251
+ "entryPoint": ".github/workflows/ci.yaml"
1252
+ },
1253
+ "environment": {
1254
+ "github_workflow": "${{ github.workflow }}",
1255
+ "github_run_id": "${{ github.run_id }}"
1256
+ }
1257
+ },
1258
+ "metadata": {
1259
+ "buildInvocationID": "${{ github.run_id }}",
1260
+ "completeness": {
1261
+ "environment": true,
1262
+ "materials": true
1263
+ }
1264
+ }
1265
+ }
1266
+ push-to-registry : true
1267
+
1268
+ - name : GitHub Attestation for version-specific Docker image
1269
+ id : attest_version
1270
+ if : github.ref == 'refs/heads/main'
1271
+ continue-on-error : true
1272
+ uses : actions/attest@a63cfcc7d1aab266ee064c58250cfc2c7d07bc31 # v2.2.1
1273
+ with :
1274
+ subject-name : " ghcr.io/coder/coder-preview:${{ steps.build-docker.outputs.tag }}"
1275
+ predicate-type : " https://slsa.dev/provenance/v1"
1276
+ predicate : |
1277
+ {
1278
+ "buildType": "https://github.com/actions/runner-images/",
1279
+ "builder": {
1280
+ "id": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
1281
+ },
1282
+ "invocation": {
1283
+ "configSource": {
1284
+ "uri": "git+https://github.com/${{ github.repository }}@${{ github.ref }}",
1285
+ "digest": {
1286
+ "sha1": "${{ github.sha }}"
1287
+ },
1288
+ "entryPoint": ".github/workflows/ci.yaml"
1289
+ },
1290
+ "environment": {
1291
+ "github_workflow": "${{ github.workflow }}",
1292
+ "github_run_id": "${{ github.run_id }}"
1293
+ }
1294
+ },
1295
+ "metadata": {
1296
+ "buildInvocationID": "${{ github.run_id }}",
1297
+ "completeness": {
1298
+ "environment": true,
1299
+ "materials": true
1300
+ }
1301
+ }
1302
+ }
1303
+ push-to-registry : true
1304
+
1305
+ # Report attestation failures but don't fail the workflow
1306
+ - name : Check attestation status
1307
+ if : github.ref == 'refs/heads/main'
1308
+ run : |
1309
+ if [[ "${{ steps.attest_main.outcome }}" == "failure" ]]; then
1310
+ echo "::warning::GitHub attestation for main tag failed"
1311
+ fi
1312
+ if [[ "${{ steps.attest_latest.outcome }}" == "failure" ]]; then
1313
+ echo "::warning::GitHub attestation for latest tag failed"
1314
+ fi
1315
+ if [[ "${{ steps.attest_version.outcome }}" == "failure" ]]; then
1316
+ echo "::warning::GitHub attestation for version-specific tag failed"
1317
+ fi
1318
+
1173
1319
- name : Prune old images
1174
1320
if : github.ref == 'refs/heads/main'
1175
1321
uses : vlaurin/action-ghcr-prune@0cf7d39f88546edd31965acba78cdcb0be14d641 # v0.6.0
0 commit comments