Skip to content
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
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use flake
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ wasmsign2

# Rivet external project cache
.rivet/

# Nix / direnv
.direnv/
result
74 changes: 74 additions & 0 deletions artifacts/cybersecurity/goals-and-requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1244,3 +1244,77 @@ artifacts:
links:
- type: verifies
target: CR-1

- id: CR-17
type: cybersecurity-req
title: Transcoding attestation chain integrity
status: draft
description: >
When a WASM component is compiled to native code, the transcoding
process must produce an in-toto attestation cryptographically binding
the source WASM digest to the native output digest, recording compiler
identity and verification status.
fields:
cal-level: CAL-2
links:
- type: derives-from
target: CG-1
- type: derives-from
target: CG-3

- id: CD-17
type: cybersecurity-design
title: TranscodingPredicate with in-toto Statement envelope
status: draft
description: >
Implement wsc.dev/transcoding/v1 predicate type recording source
WASM digest, signature verification status, compiler identity and
version, target architecture, and compilation parameters. Wrapped
in DSSE envelope for tamper evidence.
links:
- type: refines
target: CR-17
- type: refines
target: CD-7

- id: CD-18
type: cybersecurity-design
title: Nix-pinned reproducible build environment
status: draft
description: >
Nix flake pinning Rust 1.90.0, Bazel 8.5.1, and all build tools
to exact versions via flake.lock. Deterministic development shell
ensures identical toolchains across contributors and CI runners.
links:
- type: refines
target: CR-4

- id: CV-25
type: cybersecurity-verification
title: Transcoding attestation roundtrip test
status: draft
description: >
Test that TranscodingPredicate serializes to valid in-toto Statement
JSON, deserializes back identically, and that the builder pattern
produces correct attestations for all field combinations.
fields:
method: test
tool: cargo-test
links:
- type: verifies
target: CD-17

- id: CV-26
type: cybersecurity-verification
title: Nix flake reproducibility verification
status: draft
description: >
Verify that nix develop produces identical toolchain versions across
runs and that cargo build produces deterministic output within the
Nix environment.
fields:
method: test
tool: nix
links:
- type: verifies
target: CD-18
58 changes: 58 additions & 0 deletions artifacts/dev/features.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -290,3 +290,61 @@ artifacts:
links:
- type: satisfies
target: REQ-9

- id: FEAT-6
type: feature
title: WASM-to-native transcoding attestation protocol
status: in-progress
description: >
Define and implement the attestation protocol for carrying cryptographic
provenance across the WASM-to-native compilation boundary. Enables synth
to produce signed native binaries with full chain-of-custody from source
WASM through AOT compilation to ELF/MCUboot output.
fields:
github-issue: 47
phase: phase-2
links:
- type: satisfies
target: REQ-4
- type: satisfies
target: REQ-8

- id: DD-5
type: design-decision
title: In-toto predicate format for transcoding attestation
status: approved
description: >
Use in-toto Statement v1 with a custom wsc.dev/transcoding/v1 predicate
type for recording WASM-to-native compilation provenance. The predicate
captures source WASM digest and signature status, compiler identity,
target architecture, and compilation parameters.
fields:
rationale: >
In-toto provides the standardized envelope and statement framework
already used by sigil for WASM attestations. Extending with a
transcoding-specific predicate maintains consistency with SLSA
provenance while adding compiler-specific fields for the
WASM-to-native boundary.
alternatives: >
Custom JSON format (not standardized), SLSA provenance only
(lacks compiler fields), embedded ELF notes only (not portable)
links:
- type: satisfies
target: REQ-4
- type: satisfies
target: REQ-8

- id: REQ-12
type: requirement
title: Nix flake for reproducible development and CI builds
status: approved
description: >
Project must provide a Nix flake that pins all build tool versions
(Rust 1.90.0, Bazel 8.5.1, wasm-tools) for reproducible development
environments and CI builds. Prerequisite for SLSA Level 3 compliance.
fields:
priority: must
category: non-functional
links:
- type: satisfies
target: FEAT-3
22 changes: 22 additions & 0 deletions artifacts/stpa/data-flows.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -466,3 +466,25 @@ artifacts:
target: CTRL-10
- type: flows-to
target: CTRL-4

- id: DF-16
type: data-flow
title: Transcoding attestation flow
description: >
Attestation data flow from source WASM signature verification
through AOT compilation to native binary attestation embedding.
Carries source digest, compiler identity, and verification status
across the compilation boundary.
status: implemented
tags: [attestation, transcoding, chain-of-custody]
fields:
source: CTRL-3
destination: CP-5
data-classification: integrity-critical
links:
- type: flows-from
target: DF-5
- type: carries
target: SP-2
- type: carries
target: SP-6
82 changes: 82 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 97 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
{
description = "wsc - WebAssembly Signature Component";

inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
rust-overlay = {
url = "github:oxalica/rust-overlay";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-utils.url = "github:numtide/flake-utils";
};

outputs = { self, nixpkgs, rust-overlay, flake-utils }:
flake-utils.lib.eachSystem [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
] (system:
let
overlays = [ (import rust-overlay) ];
pkgs = import nixpkgs { inherit system overlays; };

rustToolchain = pkgs.rust-bin.stable."1.90.0".default.override {
extensions = [ "rustfmt" "clippy" "rust-src" "rust-analyzer" ];
targets = [ "wasm32-wasip2" ];
};

# Common build inputs for all platforms
commonBuildInputs = with pkgs; [
openssl
];

# Common native build inputs for all platforms
commonNativeBuildInputs = with pkgs; [
rustToolchain
pkg-config
cargo-fuzz
cargo-audit
cargo-deny
];

# Platform-specific inputs
# On Darwin, Security and SystemConfiguration frameworks are provided
# by the default SDK in stdenv; only libiconv needs to be explicit.
darwinBuildInputs = with pkgs; [
libiconv
];

linuxBuildInputs = with pkgs; [
# libtss2-dev equivalent for optional TPM2 feature
];

platformBuildInputs =
if pkgs.stdenv.isDarwin then darwinBuildInputs
else linuxBuildInputs;

in {
devShells.default = pkgs.mkShell {
buildInputs = commonBuildInputs ++ platformBuildInputs;
nativeBuildInputs = commonNativeBuildInputs ++ [
pkgs.bazel_8
];

shellHook = ''
export RUST_SRC_PATH="${rustToolchain}/lib/rustlib/src/rust/library"
# Let Bazel accept the nixpkgs-provided version instead of .bazelversion pin
export USE_BAZEL_VERSION="${pkgs.bazel_8.version}"
'';
};

packages.default = pkgs.rustPlatform.buildRustPackage {
pname = "wsc";
version = "0.5.1";
src = ./.;

cargoLock.lockFile = ./Cargo.lock;

nativeBuildInputs = with pkgs; [
pkg-config
];

buildInputs = commonBuildInputs ++ platformBuildInputs;

# Build only the CLI binary
cargoBuildFlags = [ "--package" "wsc-cli" ];
cargoTestFlags = [ "--package" "wsc-cli" ];

meta = with pkgs.lib; {
description = "WebAssembly Signature Component - WASM signing and verification toolkit";
homepage = "https://github.com/pulseengine/wsc";
license = licenses.mit;
};
};
}
);
}
4 changes: 4 additions & 0 deletions rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
channel = "1.90.0"
components = ["rustfmt", "clippy", "rust-src", "rust-analyzer"]
targets = ["wasm32-wasip2"]
3 changes: 3 additions & 0 deletions src/lib/src/intoto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ pub mod predicate_types {

/// CycloneDX SBOM
pub const CYCLONEDX: &str = "https://cyclonedx.org/bom";

/// WSC Transcoding attestation (WASM→native)
pub const WSC_TRANSCODING_V1: &str = "https://wsc.dev/transcoding/v1";
}

#[cfg(test)]
Expand Down
8 changes: 8 additions & 0 deletions src/lib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,14 @@ pub mod intoto;
/// See: https://slsa.dev/spec/v1.0/provenance
pub mod slsa;

/// Transcoding attestation protocol for WASM-to-native compilation
///
/// Provides the attestation format for recording provenance when compiling
/// WASM modules to native code (ARM ELF, MCUboot). Uses in-toto Statement
/// with a custom predicate to capture source verification, compiler identity,
/// target platform, and compilation parameters.
pub mod transcoding;

/// HTTP client abstraction for sync/async support
///
/// Provides a unified HTTP client interface using `maybe_async` for compile-time
Expand Down
3 changes: 3 additions & 0 deletions src/lib/src/slsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,9 @@ pub mod build_types {

/// Generic transformation
pub const TRANSFORMATION: &str = "https://wsc.dev/Transformation/v1";

/// WASM-to-native transcoding
pub const WASM_NATIVE_TRANSCODE: &str = "https://wsc.dev/WasmNativeTranscode/v1";
}

#[cfg(test)]
Expand Down
Loading
Loading