Skip to content

Add the universal WASIp2 Resource executor - #410

Merged
schickling-assistant merged 2 commits into
schickling-assistant/2026-09-01-wasip2-resource-foundation-2from
schickling-assistant/2026-09-01-wasip2-resource-executor
Sep 1, 2026
Merged

Add the universal WASIp2 Resource executor#410
schickling-assistant merged 2 commits into
schickling-assistant/2026-09-01-wasip2-resource-foundation-2from
schickling-assistant/2026-09-01-wasip2-resource-executor

Conversation

@schickling-assistant

@schickling-assistant schickling-assistant commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Problem

Resource providers need one sandboxed execution path. A provider-specific native runtime would duplicate lifecycle, limits, cancellation, and artifact trust rules.

Goal

Execute any admitted Resource observer component through one WASIp2 Component Model runtime with fresh per-observation state and reusable immutable artifacts.

Decisions

  • Use Wasmtime 48.0.1 and the WASIp2 Component Model; WASIp3 is not a production target.
  • Create a fresh Store and instance for every observation while reusing Engine, Linker, and compiled Component.
  • Admit only explicit domain capability modules. The executor has no generic command, filesystem, socket, or HTTP host surface.
  • Key the AOT cache by the complete runtime and component identity, then verify bytes and manifests before unsafe deserialization.

Verification

  • CI=1 nix develop -c cargo test -p st2-resource-wasip2 --features runtime
  • nix build .#checks.x86_64-linux.wasip2-resource-executor --no-link --print-build-logs

Both passed locally: 5 library tests and 13 executor integration tests. Coverage includes import admission, fresh Store state, fuel/epoch cancellation, resource limits, traps, corrupt cache rejection, concurrent writers, and AOT reuse.

Complexity

Wasmtime and the verified AOT cache are substantial, but they replace per-provider execution frameworks with one bounded runtime and one artifact trust boundary.

Concerns

The provider-enabled binary has a larger closure. The default st2 package does not enable the provider runtime feature.

Friction & bottlenecks

Nix auto-GC removed an input during one validation attempt. The exact check passed on retry. Component compilation is the dominant local build cost.

Follow-ups

The next PR in stack #412 supplies GitHub Issue and PTY stats capability modules and production components.

References

Posted on behalf of @schickling
field value
agent_identity dev3.direct.omp.2cshu64q
session dev3.2cshu64q
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.0.9
agent_runtime OMP 18.0.9
tooling_profile dotfiles@b607597

@schickling-assistant schickling-assistant changed the title feat(resource): add universal WASIp2 executor Add the universal WASIp2 Resource executor Sep 1, 2026
@schickling-assistant
schickling-assistant marked this pull request as ready for review September 1, 2026 15:45
@schickling-assistant

Copy link
Copy Markdown
Contributor Author

@codex please review this PR.

Posted on behalf of @schickling
field value
agent_identity dev3.direct.omp.2cshu64q
session dev3.2cshu64q
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.0.9
agent_runtime OMP 18.0.9
tooling_profile dotfiles@b607597

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-01T20:29:08.517633Z ce39603 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48c9fe4e41

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/st2-resource-wasip2/wit/observation.wit Outdated
Comment thread crates/st2-resource-wasip2/src/lib.rs Outdated
Comment thread crates/st2-resource-wasip2/src/cache.rs
agent-identity: dev3.direct.omp.2cshu64q
agent-persona: generalist
agent-supervisor: unavailable
agent-tool: OMP
agent-tool-version: 18.0.9
agent-runtime: OMP 18.0.9
tooling-profile: dotfiles@b607597
agent-identity: dev3.direct.omp.2cshu64q
agent-persona: generalist
agent-supervisor: unavailable
agent-tool: OMP
agent-tool-version: 18.0.9
agent-runtime: OMP 18.0.9
tooling-profile: dotfiles@b607597
@schickling-assistant
schickling-assistant force-pushed the schickling-assistant/2026-09-01-wasip2-resource-executor branch from 48c9fe4 to ce39603 Compare September 1, 2026 20:17
@schickling-assistant

Copy link
Copy Markdown
Contributor Author

@codex review

Posted on behalf of @schickling
field value
agent_identity dev3.direct.omp.2cshu64q
session dev3.2cshu64q
agent_persona generalist
agent_supervisor unavailable
agent_tool OMP
agent_tool_version 18.0.9
agent_runtime OMP 18.0.9
tooling_profile dotfiles@b607597

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce39603dec

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +379 to +381
for path in [&manifest_path, &artifact_path] {
if let Err(error) =
validate_owned_cache_entry_with(cache.root(), path, effective_uid(), &oracle)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Validate the exact cache descriptors before deserialization

When the cache root is beneath a directory another UID can rename entries in, these pathname checks do not authenticate the bytes being deserialized: both read_regular_bounded calls have already closed their file descriptors, so an attacker can substitute a malicious cache tree for the reads and restore the trusted tree before this loop runs. The malicious manifest supplies its own matching artifact digest, allowing attacker-chosen AOT bytes to reach Component::deserialize; validate ownership and mode on the exact opened descriptors and traverse from a retained root descriptor. Fresh evidence after the ownership fix is that both cache reads still complete before this pathname-based validation.

Useful? React with 👍 / 👎.

Comment on lines +994 to +997
let selector_schema = serde_json::from_str(&descriptor.selector_schema_json)
.map_err(DescriptorValidationError::SelectorSchemaJson)?;
let default_selector = serde_json::from_str(&descriptor.default_selector_json)
.map_err(DescriptorValidationError::DefaultSelectorJson)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Validate the selector schema and its default value

A provider can return a syntactically valid schema such as {"type":"integer"} with the default selector "not-an-integer", and describe accepts both because this only parses JSON. A binding that omits its selector can therefore activate with a default that violates the provider's own schema; compile/validate the supported schema definition and validate the default against it before returning the descriptor.

Useful? React with 👍 / 👎.

Comment on lines +391 to +392
let component = Arc::new(component);
components.insert(digest, Arc::clone(&component));

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Bound the compiled-component memory cache

In a long-running executor that observes component upgrades or many distinct catalog components, every successful load permanently retains another compiled Component in this HashMap; there is no eviction or removal path. Compiled Wasmtime artifacts can be substantially larger than their admitted input, so repeated reloads can grow process memory without bound despite the per-invocation resource limits; use a bounded cache or release entries no longer referenced by callers.

Useful? React with 👍 / 👎.

@schickling-assistant
schickling-assistant merged commit c21a390 into main Sep 1, 2026
2 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.

1 participant