Skip to content

Add cryptographic signing for WASM OCI artifacts with digest-based security#154

Merged
Mossaka merged 6 commits into
mainfrom
copilot/fix-153
Aug 21, 2025
Merged

Add cryptographic signing for WASM OCI artifacts with digest-based security#154
Mossaka merged 6 commits into
mainfrom
copilot/fix-153

Conversation

Copilot AI commented Aug 14, 2025

Copy link
Copy Markdown
Contributor

This PR adds cryptographic signing capabilities to the wassette project's examples workflow, enhancing supply chain security for all published container images.

Key Security Features

Container Image Signing: All published images are cryptographically signed using Cosign with keyless signing via GitHub's OIDC tokens, providing verifiable authenticity and integrity.

Digest-Based Security: All signing operations use immutable digest references (@sha256:...) instead of mutable tags to prevent tag mutation attacks and ensure we're signing the exact artifact that was published.

Implementation

The workflow automatically signs all six example components (gomodule-go, eval-py, time-server-js, get-weather-js, filesystem-rs, fetch-rs) for both commit SHA-tagged and latest/custom-tagged images. The signing process uses GitHub's OIDC identity tokens for keyless signing, eliminating the need to manage signing keys while providing strong cryptographic verification.

The solution maintains backward compatibility with existing build processes while adding this critical security layer for artifact verification.

Fixes #153.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Co-authored-by: Mossaka <5447827+Mossaka@users.noreply.github.com>
Copilot AI changed the title [WIP] Add artifacts signing and sbom generation for all of the publish images in examples.yml Add artifacts signing and SBOM generation for all published images in examples.yml Aug 14, 2025
Copilot AI requested a review from Mossaka August 14, 2025 20:28
@Mossaka Mossaka marked this pull request as ready for review August 16, 2025 01:10
@Mossaka

Mossaka commented Aug 16, 2025

Copy link
Copy Markdown
Contributor

@duffney we should probably dry-run the examples.yml for each PR so that we know when the pipeline is working vs. not working

@Mossaka Mossaka requested a review from duffney August 16, 2025 01:11
@duffney

duffney commented Aug 18, 2025

Copy link
Copy Markdown
Collaborator

@duffney we should probably dry-run the examples.yml for each PR so that we know when the pipeline is working vs. not working

By dry-run do you mean run the workflow and just not publish the artifacts?

@Mossaka

Mossaka commented Aug 18, 2025

Copy link
Copy Markdown
Contributor

@duffney we should probably dry-run the examples.yml for each PR so that we know when the pipeline is working vs. not working

By dry-run do you mean run the workflow and just not publish the artifacts?

yeah exactly

@duffney

duffney commented Aug 18, 2025

Copy link
Copy Markdown
Collaborator

@duffney we should probably dry-run the examples.yml for each PR so that we know when the pipeline is working vs. not working

By dry-run do you mean run the workflow and just not publish the artifacts?

yeah exactly

If the artifact isn't pushed, you'll also have to skip the signing steps. Cosign expects the image its signing to be hosted on a registry. imo, having it run when a new release is cut should be frequent enough.

@Mossaka

Mossaka commented Aug 18, 2025

Copy link
Copy Markdown
Contributor

okay, could you please review this PR and let me know if it's good to merge? @duffney

@duffney

duffney commented Aug 19, 2025

Copy link
Copy Markdown
Collaborator

@copilot when you sign the oci artifact you need to use the digest instead of the tag, which in this case is latest. You should also get the digest from the output of the wkg action that pushed the artifact to the registry.

Here is an example:

run: cosign sign --yes ghcr.io/${{ env.IMAGE_NAME }}/${{ env.COMPONENT_NAME }}@${{ steps.publish_versioned.outputs.digest }}

Co-authored-by: duffney <8146181+duffney@users.noreply.github.com>

Copilot AI commented Aug 19, 2025

Copy link
Copy Markdown
Contributor Author

@copilot when you sign the oci artifact you need to use the digest instead of the tag, which in this case is latest. You should also get the digest from the output of the wkg action that pushed the ...

Updated the signing commands to use digest instead of tag as recommended. Added IDs to the publish steps (publish_versioned and publish_latest) and changed all cosign and syft commands to use @${{ steps.publish_*.outputs.digest }} instead of :tag. This follows security best practices by ensuring we're signing the immutable digest rather than mutable tags. Fixed in 2950ce2.

Copilot AI changed the title Add artifacts signing and SBOM generation for all published images in examples.yml Add artifacts signing and SBOM generation with digest-based security for all published images in examples.yml Aug 19, 2025
@duffney

duffney commented Aug 19, 2025

Copy link
Copy Markdown
Collaborator

@copilot the sbom generated by Syft only includes the oci artifact for the wasm file. It doesn't include any details about the dependencies that the wasm component uses. To get that detail you'll have to build the components with auditable configured. You can also just use cosign to generate an attestation that has an sbom.

Here's an example workflow.

The important steps are:

      - name: Install cargo-binstall
        uses: cargo-bins/cargo-binstall@v1.10.15
        
        name: Install build dependencies
        continue-on-error: false
        run: |
          cargo binstall cargo-component --force --version ${{ env.CARGO_COMPONENT_VERSION }}
          cargo binstall wkg --force 
          cargo binstall cargo-auditable cargo-audit
          cargo binstall auditable2cdx

      - name: Build the component
        run: cargo auditable component build --release
      - name: Extract the SBOM from the component
        run: auditable2cdx target/wasm32-wasip1/release/${{ env.COMPONENT_NAME_UNDERSCORED }} >> ${{ env.COMPONENT_NAME }}.spdx.json

      - name: Sign the SBOM for the latest Wasm component
        if: github.event_name != 'workflow_dispatch'
        run: cosign attest --yes --type spdxjson --predicate ${{ env.COMPONENT_NAME }}.spdx.json ghcr.io/${{ env.IMAGE_NAME }}/${{ env.COMPONENT_NAME }}@${{ steps.publish_latest.outputs.digest }}

Co-authored-by: duffney <8146181+duffney@users.noreply.github.com>

Copilot AI commented Aug 19, 2025

Copy link
Copy Markdown
Contributor Author

@copilot the sbom generated by Syft only includes the oci artifact for the wasm file. It doesn't include any details about the dependencies that the wasm component uses. To get that detail you'll have...

Updated the SBOM generation to use cargo auditable for building Rust components and auditable2cdx to extract detailed dependency information from the WASM binaries. The workflow now:

  • Installs cargo-auditable and auditable2cdx during the build phase
  • Uses cargo auditable build for Rust components (filesystem-rs and fetch-rs)
  • Extracts comprehensive SBOM data including all dependencies using auditable2cdx
  • Maintains Syft-based SBOM generation for non-Rust components (Go, Python, JavaScript)
  • Includes fallback logic to use Syft if auditable SBOMs aren't available

The Rust SBOMs now contain complete dependency information instead of just the OCI artifact metadata. Fixed in ff703c2.

Copilot AI changed the title Add artifacts signing and SBOM generation with digest-based security for all published images in examples.yml Add artifacts signing and SBOM generation with enhanced dependency tracking for Rust components Aug 19, 2025
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Security Audit Warnings

The cargo audit security scan found 1 warning(s) in dependencies:

Click to view cargo audit output
�[0m�[0m�[1m�[32m    Fetching�[0m advisory database from `https://github.com/RustSec/advisory-db.git`
�[0m�[0m�[1m�[32m      Loaded�[0m 796 security advisories (from /home/runner/.cargo/advisory-db)
�[0m�[0m�[1m�[32m    Updating�[0m crates.io index
�[0m�[0m�[1m�[32m    Scanning�[0m Cargo.lock for vulnerabilities (529 crate dependencies)
�[0m�[0m�[1m�[33mCrate:    �[0m paste
�[0m�[0m�[1m�[33mVersion:  �[0m 1.0.15
�[0m�[0m�[1m�[33mWarning:  �[0m unmaintained
�[0m�[0m�[1m�[33mTitle:    �[0m paste - no longer maintained
�[0m�[0m�[1m�[33mDate:     �[0m 2024-10-07
�[0m�[0m�[1m�[33mID:       �[0m RUSTSEC-2024-0436
�[0m�[0m�[1m�[33mURL:      �[0m https://rustsec.org/advisories/RUSTSEC-2024-0436
�[0m�[0m�[1m�[33mDependency tree:
�[0mpaste 1.0.15
└── rmcp 0.2.1
    ├── wassette-mcp-server 0.2.0
    └── mcp-server 0.1.0
        └── wassette-mcp-server 0.2.0

�[0m�[0m�[1m�[33mwarning:�[0m 1 allowed warning found

These are warnings (not vulnerabilities) but should be reviewed for:

  • Unmaintained crates - consider finding maintained alternatives
  • Known issues - check if they affect your use case
  • Supply chain risks - evaluate dependency hygiene

The security job will continue to pass as these are warnings, not blocking security issues.

@duffney

This comment was marked as duplicate.

@duffney

duffney commented Aug 20, 2025

Copy link
Copy Markdown
Collaborator

@copilot I just remembered that the SBOM generation is only supported by cargo. The other build tools do not support it yet. My recommendation is to remove the sbom steps from the workflow but keep the signing of the wasm oci artifact like you did in commit 2950ce2

Co-authored-by: duffney <8146181+duffney@users.noreply.github.com>

Copilot AI commented Aug 20, 2025

Copy link
Copy Markdown
Contributor Author

@copilot I just remembered that the SBOM generation is only supported by cargo. The other build tools do not support it yet. My recommendation is to remove the sbom steps from the workflow but keep th...

Removed all SBOM generation steps from the workflow as requested, keeping only the cryptographic signing of WASM OCI artifacts. The workflow now focuses solely on signing with Cosign using digest-based references. Fixed in a6219b4.

@copilot I just remembered that the SBOM generation is only supported by cargo. The other build tools do not support it yet. My recommendation is to remove the sbom steps from the workflow but keep th...

Removed all SBOM generation steps from the workflow as requested, keeping only the cryptographic signing of WASM OCI artifacts. The workflow now focuses solely on signing with Cosign using digest-based references. Fixed in a6219b4.

Copilot AI changed the title Add artifacts signing and SBOM generation with enhanced dependency tracking for Rust components Add cryptographic signing for WASM OCI artifacts with digest-based security Aug 20, 2025
@duffney

duffney commented Aug 20, 2025

Copy link
Copy Markdown
Collaborator

@copilot you forgot to update the Justfile at the root of the repo. (just build-auditable mode) (cd examples/filesystem-rs && just build-auditable mode) shoul call just build instead on lines 12 and 13.

…ust examples

Co-authored-by: duffney <8146181+duffney@users.noreply.github.com>

Copilot AI commented Aug 20, 2025

Copy link
Copy Markdown
Contributor Author

@copilot you forgot to update the Justfile at the root of the repo. (just build-auditable mode) (cd examples/filesystem-rs && just build-auditable mode) shoul call just build instead on l...

Updated the Justfile to use just build instead of just build-auditable for the Rust examples on lines 12 and 13, aligning with the removal of SBOM generation from the workflow. Fixed in e3a6901.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • just.systems
    • Triggering command: curl --proto =https --tlsv1.2 -sSf https://just.systems/install.sh (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@duffney

duffney commented Aug 20, 2025

Copy link
Copy Markdown
Collaborator

@Mossaka LGTM. I had copilot remove the sbom because it's empty without the ability to parse the dependencies of the component. But the signing is working! A later feature is we could setup wassette so it only run signed components.

@Mossaka Mossaka merged commit 85dc342 into main Aug 21, 2025
18 checks passed
@Mossaka Mossaka deleted the copilot/fix-153 branch August 21, 2025 05:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add artifacts signing and sbom generation for all of the publish images in examples.yml

3 participants