Skip to content

Commit f061d8e

Browse files
authored
Merge pull request #170 from Kong/feat/slsa
ci(.github)[SEC-1084]: SLSA supply chain security controls
2 parents f86ca3d + 32f2264 commit f061d8e

File tree

3 files changed

+286
-54
lines changed

3 files changed

+286
-54
lines changed

.github/workflows/release.yaml

+178-45
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Docker
1+
name: Package & Release
22

33
# This workflow uses actions that are not certified by GitHub.
44
# They are provided by a third-party and are governed by
@@ -16,81 +16,214 @@ on:
1616
env:
1717
# Use docker.io for Docker Hub if empty
1818
REGISTRY: ghcr.io
19-
# github.repository as <account>/<repo>
20-
IMAGE_NAME: ${{ github.repository }}
21-
19+
# Format as <account>/<repo>
20+
# Must be lower case for container tools to parse correctly
21+
IMAGE_NAME: kong/insomnia-mockbin
22+
HAS_ACCESS_TO_GITHUB_TOKEN: ${{ github.repository_owner == 'Kong' }}
23+
# Local docker OCI archive name until the image is pushed to registry
24+
DOCKER_OCI_ARCHIVE: "docker-archive"
25+
# Always use Docker Hub for publishing image signatures
26+
## docker.io/kong/notary - Use Public Notary repository for release image signatures
27+
## docker.io/kong/notary-internal - Use Private Notary repository for internal image signatures
28+
NOTARY_REPOSITORY: ${{ github.ref_type == 'tag' || github.ref_name == 'master' && 'kong/notary' || 'kong/notary-internal' }}
2229

2330
jobs:
24-
build:
25-
31+
check:
2632
runs-on: ubuntu-latest
2733
permissions:
2834
contents: read
29-
packages: write
30-
# This is used to complete the identity challenge
31-
# with sigstore/fulcio when running outside of PRs.
32-
id-token: write
33-
35+
packages: write
3436
steps:
3537
- name: Checkout repository
3638
uses: actions/checkout@v3
3739

38-
# Install the cosign tool except on PR
39-
# https://github.com/sigstore/cosign-installer
40-
- name: Install cosign
41-
if: github.event_name != 'pull_request'
42-
uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1
40+
# Perform SCA analysis for the code repository
41+
# Produces SBOM and CVE report
42+
# Helps understand vulnerabilities / license compliance across third party dependencies
43+
- id: sca-project
44+
uses: Kong/public-shared-actions/security-actions/sca@2f02738ecb1670f01391162e43fe3f5d4e7942a1 # v2.2.2
4345
with:
44-
cosign-release: 'v2.1.1'
46+
dir: .
47+
upload-sbom-release-assets: true
48+
49+
# Build docker images
50+
build-images:
51+
runs-on: ubuntu-latest
52+
permissions:
53+
contents: read
54+
packages: write
55+
needs: [check]
56+
outputs:
57+
image_tags: ${{ steps.meta.outputs.tags }}
58+
image_tag_version: ${{ steps.meta.outputs.version }}
59+
steps:
60+
- name: Checkout repository
61+
uses: actions/checkout@v3
4562

4663
# Set up BuildKit Docker container builder to be able to build
4764
# multi-platform images and export cache
4865
# https://github.com/docker/setup-buildx-action
4966
- name: Set up Docker Buildx
5067
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
5168

52-
# Login against a Docker registry except on PR
53-
# https://github.com/docker/login-action
54-
- name: Log into registry ${{ env.REGISTRY }}
55-
if: github.event_name != 'pull_request'
56-
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
57-
with:
58-
registry: ${{ env.REGISTRY }}
59-
username: ${{ github.actor }}
60-
password: ${{ secrets.GITHUB_TOKEN }}
61-
62-
# Extract metadata (tags, labels) for Docker
69+
# Extract metadata (tags, labels) for Docker Image
6370
# https://github.com/docker/metadata-action
6471
- name: Extract Docker metadata
6572
id: meta
73+
env:
74+
DOCKER_METADATA_PR_HEAD_SHA: true
6675
uses: docker/metadata-action@96383f45573cb7f253c731d3b3ab81c87ef81934 # v5.0.0
6776
with:
6877
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
78+
sep-tags: ","
6979

70-
# Build and push Docker image with Buildx (don't push on PR)
80+
# Build Docker image with Buildx (don't push on PR)
7181
# https://github.com/docker/build-push-action
72-
- name: Build and push Docker image
82+
- name: Build Docker image
7383
id: build-and-push
7484
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
7585
with:
7686
context: .
77-
push: ${{ github.event_name != 'pull_request' }}
87+
push: false # only push after the image is scanned
7888
tags: ${{ steps.meta.outputs.tags }}
7989
labels: ${{ steps.meta.outputs.labels }}
8090
cache-from: type=gha
8191
cache-to: type=gha,mode=max
92+
# these 2 options are needed so that the MediaType of the manifest is
93+
# OCI-compliant for other downstream integrations
94+
# see also:
95+
# - https://github.com/docker/buildx/issues/1507
96+
# - https://github.com/docker/buildx/issues/1509#issuecomment-1378538197
97+
provenance: false
98+
outputs: type=docker,dest=${{ env.DOCKER_OCI_ARCHIVE }}.tar,oci-mediatypes=true
8299

83-
# Sign the resulting Docker image digest except on PRs.
84-
# This will only write to the public Rekor transparency log when the Docker
85-
# repository is public to avoid leaking data. If you would like to publish
86-
# transparency data even for private images, pass --force to cosign below.
87-
# https://github.com/sigstore/cosign
88-
- name: Sign the published Docker image
89-
if: ${{ github.event_name != 'pull_request' }}
90-
env:
91-
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
92-
TAGS: ${{ steps.meta.outputs.tags }}
93-
DIGEST: ${{ steps.build-and-push.outputs.digest }}
94-
# This step uses the identity token to provision an ephemeral certificate
95-
# against the sigstore community Fulcio instance.
96-
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
100+
- name: Upload Docker OCI layout TAR Artifact
101+
uses: actions/upload-artifact@v3
102+
with:
103+
name: ${{ env.DOCKER_OCI_ARCHIVE }}
104+
path: ${{ env.DOCKER_OCI_ARCHIVE }}.tar
105+
if-no-files-found: error
106+
retention-days: 1
107+
108+
scan-images:
109+
runs-on: ubuntu-latest
110+
permissions:
111+
contents: read
112+
packages: write
113+
needs: [check, build-images]
114+
if: >
115+
github.repository_owner == 'Kong'
116+
&& needs.build-images.result == 'success'
117+
steps:
118+
119+
- name: Download OCI docker TAR artifact
120+
uses: actions/download-artifact@v3
121+
with:
122+
name: ${{ env.DOCKER_OCI_ARCHIVE }}
123+
path: ${{ github.workspace }}
124+
- name: Load OCI docker TAR artifact
125+
run: |
126+
docker load -i ${{ github.workspace }}/${{ env.DOCKER_OCI_ARCHIVE }}.tar
127+
docker image ls
128+
129+
- name: Scan the docker OCI Tar ball
130+
id: sbom_action_amd64
131+
uses: Kong/public-shared-actions/security-actions/scan-docker-image@2f02738ecb1670f01391162e43fe3f5d4e7942a1 # v2.2.2
132+
with:
133+
asset_prefix: image-${{ env.IMAGE_NAME }}-amd64
134+
image: ${{ env.DOCKER_OCI_ARCHIVE }}.tar
135+
upload-sbom-release-assets: true
136+
137+
release-images:
138+
runs-on: ubuntu-latest
139+
permissions:
140+
contents: write
141+
packages: write # needed for publishing the images
142+
id-token: write # needed for keyless signing of the images
143+
needs: [check, build-images, scan-images]
144+
if: >
145+
github.repository_owner == 'Kong'
146+
&& needs.scan-images.result == 'success'
147+
&& github.event_name != 'pull_request'
148+
env:
149+
IMAGE_TAGS: ${{ needs.build-images.outputs.image_tags }}
150+
outputs:
151+
image_name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
152+
image_manifest_sha: ${{ steps.image_manifest_metadata.outputs.image_manifest_sha }}
153+
notary_repository: ${{ env.NOTARY_REPOSITORY }}
154+
steps:
155+
156+
- name: Download OCI docker TAR artifact
157+
uses: actions/download-artifact@v3
158+
with:
159+
name: ${{ env.DOCKER_OCI_ARCHIVE }}
160+
path: ${{ github.workspace }}
161+
162+
- name: Load OCI docker TAR artifact
163+
run: |
164+
docker load -i ${{ github.workspace }}/${{ env.DOCKER_OCI_ARCHIVE }}.tar
165+
docker image ls
166+
167+
# Login against a Docker registry except on PR
168+
# https://github.com/docker/login-action
169+
- name: Log into image registry ${{ env.REGISTRY }}
170+
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
171+
with:
172+
registry: ${{ env.REGISTRY }}
173+
username: ${{ github.actor }}
174+
password: ${{ secrets.GITHUB_TOKEN }}
175+
176+
- name: Push images to registry
177+
id: publish_images
178+
run: |
179+
for tag in ${IMAGE_TAGS//,/ }; do \
180+
docker push $tag; \
181+
done
182+
183+
# Setup regctl to parse platform specific image digest from image manifest
184+
- name: Install regctl
185+
uses: regclient/actions/regctl-installer@main
186+
187+
# The image manifest digest/sha is generated only after the image is published to registry
188+
- name: Parse architecture specific digest from image manifest
189+
id: image_manifest_metadata
190+
run: |
191+
IMAGE=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build-images.outputs.IMAGE_TAG_VERSION }}
192+
sha="$(regctl image digest "${IMAGE}")"
193+
echo "sha=${sha}" >> $GITHUB_OUTPUT
194+
195+
# Signing images requires image manifest digest
196+
- name: Sign images
197+
id: sign_images
198+
if: ${{ steps.image_manifest_metadata.outputs.sha != '' }}
199+
uses: Kong/public-shared-actions/security-actions/sign-docker-image@2f02738ecb1670f01391162e43fe3f5d4e7942a1 # v2.2.2
200+
with:
201+
image_digest: ${{ steps.image_manifest_metadata.outputs.sha }}
202+
tags: ${{ env.IMAGE_TAGS }}
203+
image_registry_domain: ghcr.io
204+
registry_username: ${{ github.actor }}
205+
registry_password: ${{ secrets.GITHUB_TOKEN }}
206+
# Optional: Central notary repository for image signatures
207+
# signature_registry_domain: docker.io
208+
# signature_registry_username: ${{ secrets.GHA_DOCKERHUB_PUSH_USER }}
209+
# signature_registry_password: ${{ secrets.GHA_DOCKERHUB_PUSH_TOKEN }}
210+
# signature_registry: ${{ env.NOTARY_REPOSITORY }}
211+
212+
release-images-provenance:
213+
needs: ["check", "build-images", "scan-images", "release-images"]
214+
if: ${{ github.ref_type == 'tag' || (github.event_name == 'push' && github.ref_name == 'master') }}
215+
uses: slsa-framework/slsa-github-generator/.github/workflows/[email protected]
216+
permissions:
217+
contents: write
218+
id-token: write # For using token to sign images
219+
actions: read # For getting workflow run info to build provenance
220+
packages: write # Required for publishing provenance. Issue: https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/container#known-issues
221+
with:
222+
image: ${{ needs.release-images.outputs.image_name }} # Image repository without tag. Eg: kong/insomnia-mockbins
223+
digest: ${{ needs.release-images.outputs.image_manifest_sha }} # Image manifest digest for the published docker image/TAR
224+
#provenance-repository: ${{ needs.release-images.outputs.notary_repository }}
225+
secrets:
226+
registry-username: ${{ github.actor }}
227+
registry-password: ${{ secrets.GITHUB_TOKEN }}
228+
# provenance-registry-username: ${{ secrets.GHA_DOCKERHUB_PUSH_USER }}
229+
# provenance-registry-password: ${{ secrets.GHA_KONG_ORG_DOCKERHUB_PUSH_TOKEN }}

.github/workflows/sast.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@ on:
1111
- 'v*.*.*'
1212
workflow_dispatch: {}
1313

14+
permissions:
15+
contents: read
1416

1517
jobs:
1618
semgrep:
19+
timeout-minutes: ${{ fromJSON(vars.GHA_DEFAULT_TIMEOUT) }}
1720
name: Semgrep SAST
1821
runs-on: ubuntu-latest
1922
permissions:
@@ -27,4 +30,4 @@ jobs:
2730

2831
steps:
2932
- uses: actions/checkout@v4
30-
- uses: Kong/public-shared-actions/security-actions/semgrep@bd3d75259607dd015bea3b3313123f53b80e9d7f
33+
- uses: Kong/public-shared-actions/security-actions/semgrep@2f02738ecb1670f01391162e43fe3f5d4e7942a1 # v2.2.2

0 commit comments

Comments
 (0)