Skip to content

feat(verifier,as): gate the verifier and rvps for wasm32 - #207

Open
imlk0 wants to merge 12 commits into
openanolis:mainfrom
imlk0:pure-lib-wasm-gating
Open

feat(verifier,as): gate the verifier and rvps for wasm32#207
imlk0 wants to merge 12 commits into
openanolis:mainfrom
imlk0:pure-lib-wasm-gating

Conversation

@imlk0

@imlk0 imlk0 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Make the verifier (notably TDX) and RVPS build and run under wasm32-unknown-unknown, so attestation-service can be embedded as a pure library/wasm module. The verifier's env/file reads, blocking per-GPU spawns, and Send-bound async traits all assume a native multi-threaded host; this PR makes each wasm-viable without forking the code path, using cfg_attr/cfg gates and injectable overrides so native behavior is unchanged.

Key changes worth reviewing

  • deps/verifier/src/tdx/mod.rs: new set_pccs_url(Option<String>) override (RwLock) takes precedence over the PCCS_URL env var / QCNL config-file resolution; those env + filesystem fallbacks are gated behind non-wasm targets, since wasm32 has no environment variable or filesystem access. Exported via verifier::tdx so an embedder can configure the PCCS endpoint directly.

  • deps/verifier/src/tdx/gpu/rim.rs: the forced wasm-skip of GPU RIM verification is replaced with injectable overrides — set_rim_service_url (wasm now fails closed instead of silently trying to fetch an unreachable default URL) and set_skip_gpu_verify (wasm now defaults to verify, not skip). The per-GPU tokio::spawn loop is swapped for futures::future::join_all, so a single code path works for both native (multi-threaded) and wasm (single-threaded) targets. This mirrors the TDX case: the NVIDIA RIM service URL is also normally resolved from an env var, which is unavailable on wasm, hence the same setter-based override pattern.

  • deps/verifier/src/tdx/verify/native.rs: reqwest request timeout is gated out for wasm (the wasm HTTP backend doesn't support this option).

  • deps/verifier + attestation-service traits: Verifier and RvpsApi (and their impls) use async_trait(?Send) on wasm32 via cfg_attr on the target triple, across the verifier/sample/sample_device/tdx and rvps modules.
    Why: on wasm32, reqwest's HTTP backend delegates to the browser's fetch API through wasm-bindgen FFI bindings, which operate on JS types (Promise/JsValue) tied to the single-threaded JS runtime. JsValue is not Send, so any future that awaits an HTTP call transitively becomes !Send. Since async-trait normally boxes futures as Box<dyn Future + Send>, we need ?Send on wasm to drop that bound — the trait's async-ness itself doesn't change, only the auto-trait requirement.

  • getrandom/uuid: add the getrandom js feature for wasm32 in attestation-service and deps/verifier (uuid v4 generation and getrandom both need a JS/wasm-bindgen-backed RNG source in the browser, since there's no OS entropy source to call into). Mirrors attestation-service's existing native/wasm uuid split in deps/verifier: native uses ["v4"], wasm adds js on top.

  • web-time: switch std::time to web_time under wasm32 in verifier's sgx/tdx/tpm and rvps reference_value, plus the corresponding workspace dependency wiring.
    Why: Rust's std SystemTime::now() / Instant::now() are unimplemented on wasm32-unknown-unknown and panic at runtime — there's no wall-clock/monotonic-clock syscall to bind to without going through JS. web-time is a drop-in replacement that reads time via the JS Date/Performance APIs instead.
    (The challenge/mod.rs web-time hunk is split out into a follow-up PR that lands after the challenge module exists in the challenger PR.)

Open question for discussion

Both the TDX (PCCS_URL) and NVIDIA GPU RIM service URL originally come from environment variables (TDX additionally falls back to a QCNL config file on disk). Since wasm32 has no env/fs access, this PR adds a setter per config item (set_pccs_url, set_rim_service_url, set_skip_gpu_verify) as the wasm-compatible substitute.

This works, but doesn't scale cleanly if more verifiers need the same treatment — each one growing its own ad-hoc setter + RwLock. An alternative worth discussing: thread this configuration down from attestation-service's config (file/struct) into the verifier in a unified way, rather than having each verifier module manage its own override state. Happy to discuss the tradeoffs before this pattern spreads further.

imlk0 added 6 commits July 30, 2026 10:29
Add a `set_pccs_url(Option<String>)` override (RwLock) that takes
precedence over `PCCS_URL` env / QCNL-config-file resolution, and gate
those env / filesystem fallbacks behind non-wasm targets since wasm has
no env or filesystem. Export `set_pccs_url` via `verifier::tdx` so an
embedder (binary or wasm host) can configure the PCCS endpoint directly.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
Replace the forced wasm skip of GPU RIM verification with injectable
overrides mirroring `set_pccs_url` -- `set_rim_service_url` (wasm fails
closed instead of fetching an unreachable default) and
`set_skip_gpu_verify` (wasm defaults to verify, not skip). Swap the
per-GPU `tokio::spawn` loop for `futures::future::join_all` so one code
path works on both native and single-threaded wasm.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
reqwest's `.timeout()` is unavailable on wasm32-unknown-unknown, so
split each reqwest client builder so the timeout call is applied only on
non-wasm targets, across the three client constructions in gpu/rim.rs
and the PCCS client in verify/native.rs.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
On wasm32-unknown-unknown futures default to !Send, so the `async_trait`
expansions of the Verifier and RvpsApi traits (and their impls) must use
`?Send`. Gate via `cfg_attr` on the wasm target triple across verifier,
sample, sample_device, tdx, and rvps modules.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
The uuid v4 RNG and getrandom need a wasm backend (js-sys/wasm-bindgen)
under wasm32-unknown-unknown. Add `getrandom` js in attestation-service
and deps/verifier, and mirror attestation-service's target-specific uuid
split in deps/verifier (native `["v4"]`, wasm adds `js`).

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
Part 1 of splitting 284a091: the non-challenge web-time changes — switch
std::time to web_time under wasm32 in verifier sgx/tdx/tpm and rvps
reference_value, and add the web-time workspace/dep wiring. The
challenge/mod.rs hunk is split into a follow-up commit so it can land
in the challenger PR after the challenge module exists.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

CI's `cargo fmt --check` wanted the long `#[cfg_attr(not(all(...)), async_trait)]`
one-liners broken across lines, and `cargo clippy` flagged `clone_on_copy`
on the `Option<bool>` skip-gpu-verify override read. Apply rustfmt to the
wasm cfg_attr lines and deref the RwLockReadGuard instead of cloning.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

Comment thread deps/verifier/src/tdx/mod.rs Outdated
std::result::Result::Ok(gpu_evidence_claims),
)) => {
gpu_claims.insert(format!("nvidia_gpu.{}", index), gpu_evidence_claims);
// Evaluate each GPU concurrently without `tokio::spawn`: the RIM

@jialez0 jialez0 Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这种方式,和原本的tokio::spawn有多少性能差距可以评估下吗?或者依然采用feature开关分流

@jialez0 jialez0 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

现在CI没有覆盖wsam模式下的编译和测试,最好添加一下

imlk0 added 2 commits July 30, 2026 15:33
Restore `tokio::spawn` for the per-GPU evidence evaluation loop on native
targets so the I/O-bound RIM fetches keep multi-core parallelism, and keep
`futures::future::join_all` only on the single-threaded wasm target where
`tokio::spawn` is unavailable. The per-GPU task body is unchanged; only the
dispatch is differentiated via `cfg` on the wasm32 target triple.

Addresses review feedback that switching to `join_all` uniformly lost
multi-core parallelism on native.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
Add a `cargo check -p verifier --target wasm32-unknown-unknown
--no-default-features` step to the CoCo-AS Check job. The verifier's `tdx`
module is unconditionally compiled, so this exercises the wasm cfg gating.
The attestation-service lib wasm check is intentionally excluded -- it does
not compile until later PRs in this series.

Addresses review feedback that CI did not cover wasm compilation.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

The inline `Wasm compile check (verifier)` step added to the `as-check`
job failed on CI's pinned rustc 1.76: the wasm build pulls
`js-sys`/`web-sys` 0.3.103 (already pinned in the lockfile on main),
which require rustc >= 1.77. The wasm port inherently needs these (the
getrandom `js` backend for RNG on wasm32). Move the check out of
`as-check` so the native fmt/clippy/test steps on 1.76 run unblocked,
into a dedicated `wasm-check` job that installs the `stable` toolchain
(satisfies the js-sys MSRV), adds the wasm32 target, installs protoc, and
runs `cargo check -p verifier --target wasm32-unknown-unknown --no-default-features`.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

@jialez0

jialez0 commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

几个小 comments:

  1. WASM CI 没有覆盖TDX/GPU相关的verifier代码
  2. 建议固定一个明确的WASM模式rust版本
  3. pccs_override_wins 当前没有#[test] 测试覆盖

imlk0 added 2 commits July 31, 2026 11:42
pccs_override_wins was a bare fn with no #[test] attribute, so it never
ran. Add #[test] and #[serial_test::serial] (serial_test is already a
workspace dev-dep) since it mutates the shared global PCCS override
RwLock; the serial attribute stops it racing other tests that touch the
same global. The trailing assert_ne confirms the override is cleared so
it cannot leak.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
Add a dedicated wasm-check job (runs on PR/push/create) that compiles the
wasm-viable crates for wasm32-unknown-unknown. The main CI is pinned to
1.76 and never built wasm before; the pure-lib port adds wasm targets, so
a dedicated job is needed.

Pin the toolchain to a reproducible nightly (nightly-2025-07-07) and invoke
each command with RUSTUP_TOOLCHAIN set to it. A separate job is required
because js-sys/web-sys 0.3.103 (pre-existing on main's Cargo.lock, pulled by
getrandom's js backend) need rustc >=1.77, while the native CI is 1.76.

The check covers:
- eventlog (default features)
- reference-value-provider-service (--no-default-features; no 'fs' feature
  in wasm)
- verifier (--no-default-features --features tdx-dcap-rust) so the full
  TDX + GPU verifier (PCCS override, collateral fetch, GPU RIM verify, the
  join_all per-GPU evaluation loop) compiles for wasm32; --no-default-features
  keeps the wasm-incompatible openssl/tss-esapi backends off.

The attestation-service wasm check is left commented out: the only OPA
policy engine still hard-depends on tokio::fs, which is unavailable on
wasm32. It will be re-enabled once that dependency is lifted.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,您的请求已接收,请耐心等待结果。

@ostest-bot

Copy link
Copy Markdown

@imlk0 ,您好,未检测到有镜像需要构建,如需重新检测请评论 /start

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.

3 participants