A collection of utility components that remix wasi:http types and interfaces.
client: a higher-level HTTP client that delegates towasi:http/clientstatus-codes: constants for HTTP status codes
Access control for wasi:http is split between gates and latches. A gate wraps wasi:http/client or wasi:http/handler and consults a latch before each request, a latch decides whether the request may proceed. Latches are small and single purpose, combine them to build a policy.
gate: gates bothwasi:http/clientandwasi:http/handlergate-client: gateswasi:http/client, requests sentgate-handler: gateswasi:http/handler, requests handled
A denied request fails with the latch's reason, and is logged as a warning. A latch error fails the request with internal-error, and is logged as an error.
Caution
Interfering with HTTP requests can have dramatic, unintended consequences. A denied request surfaces to the caller as a failed request, which can trigger retries, timeouts and fallbacks far from the request that was denied. Install new latches, and new configurations of existing latches, cautiously and monitor the result: roll out with latch-dry-run, watch decisions with latch-trace, and review the denials the gate logs.
Decide which requests are allowed. A latch defers or denies, a request proceeds unless a latch denies it. Deciding and acting on a decision are separate steps, a latch is told the final decision for each request with observe-decision.
latch-defer-all: defers every request, allowing all requestslatch-deny-all: denies every request
latch-method: decides by the request method, configured withwasi:config/storelatch-method-readonly: allows only GET, HEAD, QUERY and OPTIONS,latch-methodwithlatch-method-readonly-configlatch-scheme: decides by the request scheme, configured withwasi:config/storelatch-scheme-httpsonly: allows only HTTPS,latch-schemewithlatch-scheme-httpsonly-config
Deny requests on purpose, to prove a component is resilient to failures.
latch-deny-random: randomly denies a configurable fraction of requests, reproducible with a seed
Build a policy from several latches, apply a latch to only part of the requests, or try a policy before enforcing it.
latch-n2,latch-n3,latch-n4,latch-n5: aggregate two to five latches, any latch can deny a requestlatch-delegate-client/latch-delegate-handler: apply a wrapped latch to onlywasi:http/clientor onlywasi:http/handlerrequestslatch-dry-run: log what a wrapped latch would deny without enforcing it, to roll out a policylatch-trace: log the decisions of a wrapped latch
Log wasi:http calls, for debugging or auditing, without affecting them.
trace: traceswasi:http/types,wasi:http/clientandwasi:http/handlertrace-client: traceswasi:http/typesandwasi:http/clienttrace-handler: traceswasi:http/typesandwasi:http/handlertrace-types: traceswasi:http/typestrace-componentized-client: tracescomponentized:http/client
Due to resource types being unique to the instance that defines them in the Component Model, fine grain composition of the wasi:http interfaces can be persnickety. Pick the most specific component that covers the interfaces the target component imports. While the base component is more universal, a larger surface area asks the host for capabilities the target component doesn't use.
For example, with the trace-* components:
| The target component imports | Use |
|---|---|
wasi:http/types |
trace-types |
wasi:http/types and wasi:http/client |
trace-client |
wasi:http/types and wasi:http/handler |
trace-handler |
wasi:http/types, wasi:http/client and wasi:http/handler |
trace |
componentized:http/client |
trace-componentized-client |
trace-client, trace-handler and trace also trace wasi:http/types, don't combine them with trace-types.
The wasi:http/handler exported by trace-handler and trace takes requests created with their exported wasi:http/types. Use them in front of a component that forwards requests with wasi:http/handler, a host serving incoming requests can't call them directly.
Prereqs:
- a rust toolchain
cargo-binstall, optional, to download prebuilt tools instead of building them
make componentsThe build creates each component in components into target/components, e.g. the client at target/components/client/client.wasm, along with target/components/interface.wasm, the componentized:http WIT package. Each component is also built with debug info, e.g. target/components/client/client.debug.wasm.
The cli tools the build uses, static-config, wasm-tools, wac, wasmtime and wkg, are pinned in tools/Cargo.toml and installed into target/tools/<platform>, e.g. target/tools/aarch64-apple-darwin, as needed, or ahead of time with make tools. Dependabot bumps the pinned versions.
The Componentized project follow the Contributor Covenant Code of Conduct. In short, be kind and treat others with respect.
General discussion and questions about the project can occur in the project's GitHub discussions.
The Componentized project team welcomes contributions from the community. A contributor license agreement (CLA) is not required. You own full rights to your contribution and agree to license the work to the community under the Apache License v2.0, via a Developer Certificate of Origin (DCO). For more detailed information, refer to CONTRIBUTING.md.
This project was conceived in discussion between Mark Fisher and Scott Andrews.
Apache License v2.0: see LICENSE for details.