diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml
index bc471c973e6d1ff301b4f23551500b67dc730c79..2e7f4d22578ad6dd02ce3cf1a936b57aa25b2d3f 100644
--- a/.github/workflows/e2e_test.yml
+++ b/.github/workflows/e2e_test.yml
@@ -34,7 +34,6 @@ jobs:
             .github/workflows/codecov_unittest.yaml
             .github/workflows/integration_test.yml
             .github/workflows/license_checker.yml
-            .github/workflows/manually-sign-container-images.yaml
             .github/workflows/must_update_changelog.yml
             .github/workflows/release_helm_chart.yml
             .github/workflows/stale.yml
diff --git a/.github/workflows/e2e_test_upload_cache.yml b/.github/workflows/e2e_test_upload_cache.yml
index 04d1978dd71ecaf0d709cbf8001f9d148eb8f6a6..aa882a6e9f870973f14f631bda5aee0a502e7553 100644
--- a/.github/workflows/e2e_test_upload_cache.yml
+++ b/.github/workflows/e2e_test_upload_cache.yml
@@ -17,7 +17,6 @@ on:
       - .github/workflows/codecov_unittest.yaml
       - .github/workflows/integration_test.yml
       - .github/workflows/license_checker.yml
-      - .github/workflows/manually-sign-container-images.yaml
       - .github/workflows/must_update_changelog.yml
       - .github/workflows/release_helm_chart.yml
       - .github/workflows/stale.yml
diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml
index 33bf561a137cad188d59c02a2a363b86c6b1e650..a1b8e5d18dd120d4df5d470965938b548fe37cd9 100644
--- a/.github/workflows/integration_test.yml
+++ b/.github/workflows/integration_test.yml
@@ -15,7 +15,6 @@ on:
       - .github/workflows/e2e_test.yml
       - .github/workflows/e2e_test_upload_cache.yml
       - .github/workflows/license_checker.yml
-      - .github/workflows/manually-sign-container-images.yaml
       - .github/workflows/must_update_changelog.yml
       - .github/workflows/release_helm_chart.yml
       - .github/workflows/stale.yml
diff --git a/.github/workflows/manually-sign-container-images.yaml b/.github/workflows/manually-sign-container-images.yaml
deleted file mode 100644
index b9d638fb6a62210b5d33711c477c9cb4f42b9c75..0000000000000000000000000000000000000000
--- a/.github/workflows/manually-sign-container-images.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-name: Manually Sign Container Images
-permissions: read-all
-on:
-  workflow_dispatch:
-    inputs:
-      imageTag:
-        description: The container image tag to be signed.
-        required: true
-        default: latest
-jobs:
-  sign:
-    runs-on: ubuntu-latest
-    permissions:
-      contents: read
-      packages: write
-    steps:
-      - name: Install cosign
-        uses: sigstore/cosign-installer@main
-        with:
-          cosign-release: "v1.13.1"
-      - name: Log in to GitHub Docker Registry
-        uses: docker/login-action@v1
-        with:
-          registry: ghcr.io
-          username: ${{ github.actor }}
-          password: ${{ secrets.GITHUB_TOKEN }}
-      - name: Sign Chaos Mesh Container Images
-        env:
-          COSIGN_PRIVATE_KEY: ${{secrets.COSIGN_PRIVATE_KEY}}
-          COSIGN_PASSWORD: ${{secrets.COSIGN_PASSWORD}}
-        run: |
-          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-mesh:${{ github.event.inputs.imageTag }}
-          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-daemon:${{ github.event.inputs.imageTag }}
-          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-dashboard:${{ github.event.inputs.imageTag }}
-          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-kernel:${{ github.event.inputs.imageTag }}
-          cosign public-key --key env://COSIGN_PRIVATE_KEY
diff --git a/.github/workflows/upload_image.yml b/.github/workflows/upload_image.yml
index 87195b8a1db6c4683d298d25d865bc6631854a6c..8be94ac13a7bd213fd7c0a8e7e040f04b35ddca1 100644
--- a/.github/workflows/upload_image.yml
+++ b/.github/workflows/upload_image.yml
@@ -29,6 +29,7 @@ jobs:
           fetch-depth: 0
 
       - name: Extract Image Tag
+        id: image_tag
         shell: bash
         run: |
           IMAGE_TAG=${GITHUB_REF##*/}
@@ -37,9 +38,8 @@ jobs:
           fi
 
           echo "::set-output name=image_tag::$(echo $IMAGE_TAG)"
-        id: image_tag
 
-      - name: Log in to GitHub Docker Registry
+      - name: Login to GitHub Container registry
         uses: docker/login-action@v1
         with:
           registry: ghcr.io
@@ -82,21 +82,22 @@ jobs:
           docker push ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/$IMAGE:$IMAGE_TAG-$ARCH
 
   upload-manifest:
+    needs: build-specific-architecture
+    runs-on: ubuntu-latest
     permissions:
       # https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#authenticating-to-package-registries-on-github
       packages: write
-    runs-on: ubuntu-latest
     strategy:
       matrix:
         image:
           [chaos-daemon, chaos-mesh, chaos-dashboard, chaos-kernel, chaos-dlv]
-    needs: build-specific-architecture
+    env:
+      IMAGE_TAG: ${{ needs.build-specific-architecture.outputs.image_tag }}
+      GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
     steps:
-      - name: Build Chaos Mesh manifest
+      - name: Create the manifest list
         env:
           IMAGE: ${{ matrix.image }}
-          IMAGE_TAG: ${{ needs.build-specific-architecture.outputs.image_tag }}
-          GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
         run: |
           # ${VAR,,} convert VAR to lower case
           docker manifest create ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/$IMAGE:$IMAGE_TAG \
@@ -110,18 +111,86 @@ jobs:
             ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/$IMAGE:$IMAGE_TAG-arm64 \
             --os linux --arch arm64
 
-      - name: Log in to GitHub Docker Registry
+      - name: Login to GitHub Container registry
         uses: docker/login-action@v1
         with:
           registry: ghcr.io
           username: ${{ github.actor }}
           password: ${{ secrets.GITHUB_TOKEN }}
 
-      - name: Upload Chaos Mesh
+      - name: Push the manifest list
         env:
           IMAGE: ${{ matrix.image }}
-          IMAGE_TAG: ${{ needs.build-specific-architecture.outputs.image_tag }}
-          GITHUB_REPOSITORY_OWNER: ${{ github.repository_owner }}
         run: |
           # ${VAR,,} convert VAR to lower case
           docker manifest push ghcr.io/${GITHUB_REPOSITORY_OWNER,,}/$IMAGE:$IMAGE_TAG
+
+  sign:
+    needs:
+      - build-specific-architecture
+      - upload-manifest
+    if: needs.build-specific-architecture.outputs.image_tag != 'latest'
+    runs-on: ubuntu-latest
+    permissions:
+      contents: write # Need to upload files to the related release.
+      # https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#authenticating-to-package-registries-on-github
+      packages: write
+    env:
+      IMAGE_TAG: ${{ needs.build-specific-architecture.outputs.image_tag }}
+    steps:
+      - name: Install cosign
+        uses: sigstore/cosign-installer@main
+        with:
+          cosign-release: "v1.13.1"
+      - name: Login to GitHub Container registry
+        uses: docker/login-action@v1
+        with:
+          registry: ghcr.io
+          username: ${{ github.actor }}
+          password: ${{ secrets.GITHUB_TOKEN }}
+      - name: Sign Chaos Mesh Container images
+        env:
+          COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_PRIVATE_KEY }}
+          COSIGN_PASSWORD: ${{ secrets.COSIGN_PASSWORD }}
+        run: |
+          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-mesh:$IMAGE_TAG --output-signature ghcr.io-chaos-mesh-chaos-mesh-$IMAGE_TAG.sig
+          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-daemon:$IMAGE_TAG --output-signature ghcr.io-chaos-mesh-chaos-daemon-$IMAGE_TAG.sig
+          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-dashboard:$IMAGE_TAG --output-signature ghcr.io-chaos-mesh-chaos-dashboard-$IMAGE_TAG.sig
+          cosign sign --key env://COSIGN_PRIVATE_KEY ghcr.io/chaos-mesh/chaos-kernel:$IMAGE_TAG --output-signature ghcr.io-chaos-mesh-chaos-kernel-$IMAGE_TAG.sig
+          cosign public-key --key env://COSIGN_PRIVATE_KEY > cosign.pub
+      - name: Upload cosign.pub and sigs
+        uses: softprops/action-gh-release@v1
+        with:
+          files: |
+            cosign.pub
+            ghcr.io-chaos-mesh-chaos-mesh-$IMAGE_TAG.sig
+            ghcr.io-chaos-mesh-chaos-daemon-$IMAGE_TAG.sig
+            ghcr.io-chaos-mesh-chaos-dashboard-$IMAGE_TAG.sig
+            ghcr.io-chaos-mesh-chaos-kernel-$IMAGE_TAG.sig
+
+  sbom:
+    needs: build-specific-architecture
+    if: needs.build-specific-architecture.outputs.image_tag != 'latest'
+    runs-on: ubuntu-latest
+    permissions:
+      contents: write # Need to upload files to the related release.
+    env:
+      IMAGE_TAG: ${{ needs.build-specific-architecture.outputs.image_tag }}
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Set up Go
+        uses: actions/setup-go@v3
+        with:
+          go-version: "1.18"
+
+      - name: Install bom
+        run: go install sigs.k8s.io/bom/cmd/bom
+
+      - name: Generate SBOM
+        run: bom generate -n https://chaos-mesh.org/chaos-mesh.spdx -o chaos-mesh-$IMAGE_TAG-sbom.spdx .
+
+      - name: Upload SBOM
+        uses: softprops/action-gh-release@v1
+        with:
+          files: chaos-mesh-$IMAGE_TAG-sbom.spdx
diff --git a/.gitignore b/.gitignore
index 6571250b78c5166ba7707c12044bf72d18eb3eff..9bbc4793562d873b54843a3a05158b70d7e8979d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,7 +22,7 @@ core.sqlite
 # But it is just tools that can be installed with make setup
 /_tools/
 
-/node_modules
+node_modules
 # FIXME: comment this line temporarily to get e2e_test.yml working.
 # /yarn.lock
 
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aa0f01b64617b3dd947576b70087545a53b5b0ec..7d6c8c78bd2c4083a69de344b51f8fec5025ae29 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -38,7 +38,7 @@ For more information and how-to, see [RFC: Keep A Changelog](https://github.com/
 
 ### Security
 
-- Nothing
+- Sign images and generate sbom when uploading images in CI [#3766](https://github.com/chaos-mesh/chaos-mesh/pull/3766)
 
 ## [2.4.0] - 2022-09-23