Skip to content

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

Merged
jialez0 merged 10 commits into
openanolis:mainfrom
imlk0:pure-lib-wasm-gating
Aug 4, 2026
Merged

feat(verifier,as): gate the verifier and rvps for wasm32#207
jialez0 merged 10 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.

@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

@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模式下的编译和测试,最好添加一下

@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

@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] 测试覆盖

@ostest-bot

Copy link
Copy Markdown

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

@ostest-bot

Copy link
Copy Markdown

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

imlk0 added 10 commits August 4, 2026 10:43
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>
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>
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>
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 `wasm-check` job (runs on PR/push/create) that compiles the
wasm-viable crates for the `wasm32-unknown-unknown` target. Main CI is
pinned to rustc 1.76 and never built wasm before; the pure-lib port
adds wasm targets, so a dedicated job is needed to cover this.

The job pins the toolchain to a reproducible nightly
(nightly-2025-07-07) and invokes each command with RUSTUP_TOOLCHAIN
set to it, rather than running inline in the `as-check` job: the wasm
build pulls in `js-sys`/`web-sys` 0.3.103 (already pinned in the
lockfile on main via getrandom's `js` backend, needed for RNG on
wasm32), which require rustc >= 1.77. Running it as a separate job
keeps the native fmt/clippy/test steps on 1.76 unblocked.

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.

Addresses review feedback that CI did not cover wasm compilation.

Signed-off-by: Kun Lai <laikun@linux.alibaba.com>
@imlk0
imlk0 force-pushed the pure-lib-wasm-gating branch from 1b21de8 to 87e641a Compare August 4, 2026 03:43
@ostest-bot

Copy link
Copy Markdown

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

@ostest-bot

Copy link
Copy Markdown

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

@jialez0
jialez0 merged commit 0540c0c into openanolis:main Aug 4, 2026
16 of 17 checks passed
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