Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci(.github)[SEC-1084]: SLSA supply chain security controls #7479

Merged
merged 2 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 43 additions & 8 deletions .github/workflows/release-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,31 @@ concurrency:
cancel-in-progress: true

jobs:
check:
runs-on: ubuntu-latest
permissions:
packages: write
contents: write # publish sbom to GH releases/tag assets
steps:
- name: Checkout repository
uses: actions/checkout@v3

# Perform SCA / SBOM analysis for the entiire monorepo code repository
# Produces SBOM and CVE report
# Helps understand vulnerabilities / license compliance across third party dependencies
# Automatically uploads to workflow assets
# (TODO): Prouce workspace/package specific SBOM. Current limitation: https://github.com/anchore/syft/issues/2574
- id: sca-project
uses: Kong/public-shared-actions/security-actions/sca@62643b74f79f6a697b9add1a2f9c069bf9ca1250 # v2.3.0
with:
dir: .
upload-sbom-release-assets: false
build-and-upload-release-artifacts:
timeout-minutes: 30
runs-on: ${{ matrix.os }}
env:
INSO_PACKAGE_NAME: insomnia-inso
INSO_DOCKER_TAR: inso-docker-image.tar
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -62,7 +84,7 @@ jobs:

- name: Setup Inso CLI version env var
run:
echo "INSO_VERSION=$(jq .version packages/insomnia-inso/package.json -rj)" >> $GITHUB_ENV
echo "INSO_VERSION=$(jq .version ./packages/${{ env.INSO_PACKAGE_NAME }}/package.json -rj)" >> $GITHUB_ENV

- name: Package inso
run: |
Expand All @@ -76,7 +98,7 @@ jobs:
if: matrix.os == 'macos-13'
run: ./src/scripts/macos-pkg.sh
shell: bash
working-directory: packages/insomnia-inso
working-directory: ./packages/${{ env.INSO_PACKAGE_NAME }}
continue-on-error: false
env:
MACOS_CERTIFICATE: ${{ secrets.DESIGNER_MAC_CSC_LINK }}
Expand All @@ -89,7 +111,7 @@ jobs:
if: matrix.os == 'macos-13'
uses: lando/notarize-action@v2
with:
product-path: packages/insomnia-inso/artifacts/inso-${{ matrix.os }}-${{ env.INSO_VERSION }}.pkg
product-path: ./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/inso-${{ matrix.os }}-${{ env.INSO_VERSION }}.pkg
primary-bundle-id: com.insomnia.inso
appstore-connect-username: ${{ secrets.DESIGNER_APPLE_ID }}
appstore-connect-password: ${{ secrets.DESIGNER_APPLE_ID_PASSWORD }}
Expand All @@ -99,13 +121,13 @@ jobs:
if: matrix.os == 'macos-13'
uses: BoundfoxStudios/action-xcode-staple@v1
with:
product-path: packages/insomnia-inso/artifacts/inso-${{ matrix.os }}-${{ env.INSO_VERSION }}.pkg
product-path: ./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/inso-${{ matrix.os }}-${{ env.INSO_VERSION }}.pkg

- name: Notarize Inso CLI binary (macOS only)
if: matrix.os == 'macos-13'
uses: lando/notarize-action@v2
with:
product-path: packages/insomnia-inso/binaries/inso
product-path: ./packages/${{ env.INSO_PACKAGE_NAME }}/binaries/inso
primary-bundle-id: com.insomnia.inso-binary
appstore-connect-username: ${{ secrets.DESIGNER_APPLE_ID }}
appstore-connect-password: ${{ secrets.DESIGNER_APPLE_ID_PASSWORD }}
Expand All @@ -114,11 +136,24 @@ jobs:
- name: Create inso artifacts
run: npm run inso-package:artifacts

- name: Create Docker Image artifacts
- name: Create inso Docker Image artifacts
if: matrix.os == 'ubuntu-latest'
run: |
DOCKER_BUILDKIT=1 docker build --tag insomnia-inso:temp ./packages/insomnia-inso/
docker save insomnia-inso:temp -o ./packages/insomnia-inso/artifacts/inso-docker-image.tar
DOCKER_BUILDKIT=1 docker build --tag ${{ env.INSO_PACKAGE_NAME }}:temp ./packages/${{ env.INSO_PACKAGE_NAME }}
docker save ${{ env.INSO_PACKAGE_NAME }}:temp -o ./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/${{ env.INSO_DOCKER_TAR }}

# Produce Docker SBOM for Inso Image
# Automatically uploads to workflow assets
- name: Scan inso docker artifacts
id: sbom_action
if: matrix.os == 'ubuntu-latest'
uses: Kong/public-shared-actions/security-actions/scan-docker-image@62643b74f79f6a697b9add1a2f9c069bf9ca1250 # v2.3.0
with:
asset_prefix: image-inso-${{ runner.os }}
image: ./packages/${{ env.INSO_PACKAGE_NAME }}/artifacts/${{ env.INSO_DOCKER_TAR }}
upload-sbom-release-assets: false # No release is publushed yet. Uploads as workflow assets
env:
SYFT_SOURCE_NAME: ${{ env.INSO_DOCKER_TAR }}

- name: Upload artifacts
uses: actions/upload-artifact@v4
Expand Down
181 changes: 137 additions & 44 deletions .github/workflows/release-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,26 @@ env:
RELEASE_CORE_TAG: core@${{ github.event.inputs.version }}
RELEASE_BRANCH: release/${{ github.event.inputs.version }}
IS_PRERELEASE: ${{ contains(github.event.inputs.version, 'alpha') || contains(github.event.inputs.version, 'beta') }}
ARTIFACTS_DOWNLOAD_PATH: ${{ github.workspace }}/artifacts
INSO_DOCKER_IMAGE: kong/inso # By default, registry is docker.io
NOTARY_REPOSITORY: ${{ (contains(github.event.inputs.version, 'alpha') || contains(github.event.inputs.version, 'beta')) && 'kong/notary-internal' || 'kong/notary' }}

jobs:
publish:
timeout-minutes: 15
runs-on: ubuntu-latest
outputs:
NOTARY_REPOSITORY: ${{ env.NOTARY_REPOSITORY }}
INSO_BINARY_ARTIFACTS_DIGEST_BASE64: ${{ steps.metadata.outputs.inso_binary_artifact_digest_base64 }}
INSO_DOCKER_IMAGE: ${{ env.INSO_DOCKER_IMAGE }}
INSO_DOCKER_IMAGE_DIGEST: ${{ steps.image_manifest_metadata.outputs.inso_image_sha }}
INSOMNIA_RELEASE_TAG: ${{ env.RELEASE_CORE_TAG }}
INSOMNIA_BINARY_ARTIFACTS_DIGEST_BASE64: ${{ steps.metadata.outputs.insomnia_binary_artifact_digest_base64 }}
permissions:
id-token: write # needed for signing the images
actions: read # For getting workflow run info for keyless signing of docker image
contents: write # Required to upload assets. Issue: https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/container#known-issues
packages: write
steps:
- name: Checkout branch # Check out the release branch
uses: actions/checkout@v4
Expand All @@ -42,9 +57,30 @@ jobs:
workflow: release-build.yml
workflow_conclusion: success
branch: ${{ env.RELEASE_BRANCH }} # Branch workflow ran on != branch the workflow created
path: ./artifacts/
path: ${{ env.ARTIFACTS_DOWNLOAD_PATH }} # Base path to download all release workflow assets

- name: Set publish metadata # Checksum for provenance must be calculated before moving artifacts temporarily
id: metadata
run: |

INSO_VERSION=$(jq .version packages/insomnia-inso/package.json -rj)
echo "INSO_VERSION=${INSO_VERSION}" >> $GITHUB_ENV

- name: Temporarily move Windows artifacts
inso_binary_artifact_digest_base64=$(find "${{env.ARTIFACTS_DOWNLOAD_PATH}}" -type f \
\( -name "inso-*.zip" -o -name "inso-*.pkg" -o -name "inso-*.tar.xz" \) \
-exec sha256sum {} \; | sed "s/\(.* \)\(.*\(inso\)\)/\1\\3/" | sort | base64 -w0)
echo "Inso CLI Artifact digest:"
echo "${inso_binary_artifact_digest_base64}"
echo "inso_binary_artifact_digest_base64=${inso_binary_artifact_digest_base64}" >> $GITHUB_OUTPUT

insomnia_binary_artifact_digest_base64=$(find "${{env.ARTIFACTS_DOWNLOAD_PATH}}" -type f \ [18:35:48]
\( -name "Insomnia.Core-*" \) \
-exec sha256sum {} \; | sed "s/\(.* \)\(.*\(Insomnia.Core\)\)/\1\\3/" | sort | base64 -w0)
echo "Insomnia Binary Artifact digest:"
echo "${insomnia_binary_artifact_digest_base64}"
echo "insomnia_binary_artifact_digest_base64=${insomnia_binary_artifact_digest_base64}" >> $GITHUB_OUTPUT

- name: Temporarily move artifacts
shell: bash
run: |
mv ./artifacts/windows-latest-artifacts/insomnia/dist/squirrel-windows/Insomnia.Core-${{ env.RELEASE_VERSION }}.exe ./artifacts/
Expand All @@ -71,40 +107,12 @@ jobs:
# file_path: ${GITHUB_WORKSPACE}/artifacts/Insomnia.Core-${{ env.RELEASE_VERSION }}-portable.exe
# output_path: ${GITHUB_WORKSPACE}/artifacts/windows-latest-artifacts/insomnia/dist

- name: Set Inso CLI version on Github Env
run:
echo "INSO_VERSION=$(jq .version packages/insomnia-inso/package.json -rj)" >> $GITHUB_ENV

- name: Create Release for Inso CLI
uses: ncipollo/release-action@v1
id: release_inso_cli
with:
tag: lib@${{ env.INSO_VERSION }}
name: "Inso CLI ${{ env.INSO_VERSION }} 📦"
generateReleaseNotes: false
commit: ${{ env.RELEASE_BRANCH }}
prerelease: ${{ env.IS_PRERELEASE }}
draft: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Upload Inso CLI artifacts to release
uses: xresloader/upload-to-github-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
release_id: ${{ steps.release_inso_cli.outputs.id }}
tag_name: lib@${{ env.INSO_VERSION }}
file: "./artifacts/*-latest-artifacts/insomnia-inso/artifacts/**"
prerelease: ${{ env.IS_PRERELEASE }}
draft: false

- name: Create Tag and Release
uses: ncipollo/release-action@v1
id: core_tag_and_release
with:
tag: ${{ env.RELEASE_CORE_TAG }}
name: "Insomnia ${{ env.RELEASE_VERSION }} 📦"
name: "${{ env.RELEASE_VERSION }} 📦"
generateReleaseNotes: true
commit: ${{ env.RELEASE_BRANCH }}
prerelease: ${{ env.IS_PRERELEASE }}
Expand All @@ -119,7 +127,7 @@ jobs:
with:
release_id: ${{ steps.core_tag_and_release.outputs.id }}
tag_name: ${{ env.RELEASE_CORE_TAG }}
file: "./artifacts/*-latest-artifacts/insomnia/**"
file: "./artifacts/*-latest-artifacts/insomnia/**;./artifacts/inso-*;./artifacts/*sbom.{spdx,cyclonedx}.json"
prerelease: ${{ env.IS_PRERELEASE }}
draft: false

Expand Down Expand Up @@ -187,23 +195,67 @@ jobs:
--dist-version focal
--package-type insomnia
${{ env.IS_PRERELEASE == 'true' && '--internal' || '--publish' }}

- name: Push Inso CLI docker image tags to Docker Hub
- name: Load the Inso CLI Docker Archive
run: |
echo -n $DOCKER_REGISTRY_TOKEN | docker login -u "$DOCKER_REGISTRY_USER" --password-stdin $DOCKER_REGISTRY
docker load -i ./artifacts/ubuntu-latest-artifacts/insomnia-inso/artifacts/inso-docker-image.tar
docker tag insomnia-inso:temp ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${{ env.INSO_VERSION }}
docker tag insomnia-inso:temp ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${DOCKER_LATEST_TAG}
docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${{ env.INSO_VERSION }}
docker push ${DOCKER_REGISTRY}/${DOCKER_IMAGE}:${DOCKER_LATEST_TAG}
docker image ls

- name: Login to Docker Hub
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.1.0
with:
username: ${{ secrets.DOCKER_REGISTRY_USER }}
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}

- name: Docker meta for Inso CLI Docker Image
id: inso_docker_meta
uses: docker/metadata-action@v5
with:
images: ${{ env.INSO_DOCKER_IMAGE }}
tags: |
type=raw,value=${{ env.INSO_VERSION }},prirority=1000
type=raw,value=latest,enable=${{ env.IS_PRERELEASE == 'false' }}
type=raw,value=alpha,enable=${{ env.IS_PRERELEASE == 'true' && contains(github.event.inputs.version, 'alpha') }}
type=raw,value=beta,enable=${{ env.IS_PRERELEASE == 'true' && contains(github.event.inputs.version, 'beta') }}
sep-tags: ","

- name: Push Inso CLI docker image tags to Docker Hub
id: publish_isno_docker_image
run: |
for tag in ${IMAGE_TAGS//,/ }; do \
docker tag insomnia-inso:temp $tag
docker push $tag; \
done
env:
DOCKER_REGISTRY_TOKEN: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
DOCKER_REGISTRY_USER: ${{ secrets.DOCKER_REGISTRY_USER }}
DOCKER_REGISTRY: docker.io
DOCKER_IMAGE: kong/inso
DOCKER_LATEST_TAG: ${{ env.IS_PRERELEASE == 'false' && 'latest' || contains(github.event.inputs.version, 'alpha') && 'alpha' || 'beta' }}
IMAGE_TAGS: ${{ steps.inso_docker_meta.outputs.tags }}

# Setup regctl to parse platform specific image digest from image manifest
- name: Install regctl
uses: regclient/actions/regctl-installer@main

# The image manifest digest/sha is generated only after the image is published to registry
- name: Parse architecture specific digest from image manifest
id: image_manifest_metadata
run: |
INSO_IMAGE=${{ env.INSO_DOCKER_IMAGE }}:${{ steps.inso_docker_meta.outputs.version }}
inso_image_sha="$(regctl image digest "${INSO_IMAGE}")"
echo "inso_image_sha=${inso_image_sha}" >> $GITHUB_OUTPUT

# Signing images requires image manifest digest
- name: Sign images
id: sign_images
if: ${{ steps.image_manifest_metadata.outputs.inso_image_sha != '' }}
uses: Kong/public-shared-actions/security-actions/sign-docker-image@2f02738ecb1670f01391162e43fe3f5d4e7942a1 # v2.2.2
with:
image_digest: ${{ steps.image_manifest_metadata.outputs.inso_image_sha }}
tags: ${{ steps.inso_docker_meta.outputs.tags }}
registry_username: ${{ secrets.DOCKER_REGISTRY_USER }}
registry_password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
# Optional: Central notary repository for image signatures
signature_registry_username: ${{ secrets.DOCKER_REGISTRY_USER }}
signature_registry_password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
signature_registry: ${{ env.NOTARY_REPOSITORY }}

- name: Upload sourcemaps to Sentry
env:
SENTRY_AUTH_TOKEN: '${{ secrets.SENTRY_AUTH_TOKEN }}'
Expand Down Expand Up @@ -231,3 +283,44 @@ jobs:
git push "${remote_repo}"
env:
RELEASE_GH_TOKEN: ${{ secrets.RELEASE_GH_TOKEN }}

artifact-provenance:
needs: [publish]
permissions:
id-token: write # needed for signing the images
actions: read # For getting workflow run info to build provenance
packages: write # Required for publishing provenance. Issue: https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/container#known-issues
strategy:
fail-fast: true
matrix:
include:
- product: insomnia
binary_artifacts_digest_base64: ${{ needs.publish.outputs.INSOMNIA_BINARY_ARTIFACTS_DIGEST_BASE64 }}
- product: inso
binary_artifacts_digest_base64: ${{ needs.publish.outputs.INSO_BINARY_ARTIFACTS_DIGEST_BASE64 }}
# need to use non hash version because of: https://github.com/slsa-framework/slsa-github-generator/issues/3498
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: ${{matrix.binary_artifacts_digest_base64 }}
upload-assets: true
upload-tag-name: ${{ needs.publish.outputs.INSOMNIA_RELEASE_TAG }}
provenance-name: ${{ matrix.product }}-provenance.intoto.jsonl
draft-release: false

inso-image-provenance:
needs: [publish]
permissions:
id-token: write # needed for signing the images
actions: read # For getting workflow run info to build provenance
packages: write # Required for publishing provenance. Issue: https://github.com/slsa-framework/slsa-github-generator/tree/main/internal/builders/container#known-issues
# need to use non hash version because of: https://github.com/slsa-framework/slsa-github-generator/issues/3498
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v2.0.0
with:
image: ${{ needs.publish.outputs.INSO_DOCKER_IMAGE }}
digest: ${{ needs.publish.outputs.INSO_DOCKER_IMAGE_DIGEST }}
provenance-repository: "${{ needs.publish.outputs.NOTARY_REPOSITORY }}"
secrets:
registry-username: ${{ secrets.DOCKER_REGISTRY_USER }}
registry-password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
provenance-registry-username: ${{ secrets.DOCKER_REGISTRY_USER }}
provenance-registry-password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
Loading