fix CORS headers and a wasm experiment
Some checks failed
Go / build (push) Has been cancelled
Go / release (push) Has been cancelled

This commit is contained in:
2025-11-14 19:15:50 +00:00
parent 9fb976703d
commit 24eef5b5a8
13 changed files with 691 additions and 35 deletions

View File

@@ -1 +1 @@
v0.28.1
v0.28.2

View File

@@ -0,0 +1,10 @@
{
"permissions": {
"allow": [
"Bash(go build:*)",
"Bash(CGO_ENABLED=0 go build:*)"
],
"deny": [],
"ask": []
}
}

View File

@@ -0,0 +1,125 @@
# Quick Start Guide
## TL;DR
```bash
# Build all examples
./build.sh
# Run hello example (stdout only)
./run.sh hello.wasm
# Run echo example (stdin/stdout)
echo "test" | ./run.sh echo.wasm
# Run all tests
./test.sh
```
## What's Included
### Scripts
- **`build.sh`** - Compile all `.wat` files to `.wasm` using `wat2wasm`
- **`run.sh`** - Execute WASM files with `wasmtime` WASI runtime
- **`test.sh`** - Run complete test suite
### Examples
- **`hello.wat/wasm`** - Simple "Hello World" to stdout
- **`echo.wat/wasm`** - Read from stdin, echo to stdout
### Documentation
- **`README.md`** - Complete documentation with examples
- **`QUICKSTART.md`** - This file
## Running WASM in Shell - The Basics
### Console Output (stdout)
```bash
./run.sh hello.wasm
# Output: Hello from WASM shell!
```
### Console Input (stdin)
```bash
# Piped input
echo "your text" | ./run.sh echo.wasm
# Interactive input
./run.sh echo.wasm
# (type your input and press Enter)
# From file
cat file.txt | ./run.sh echo.wasm
```
## Use Case: ORLY Policy Scripts
This WASM shell runner is perfect for ORLY's policy system:
```bash
# Event JSON comes via stdin
echo '{"kind":1,"content":"hello","pubkey":"..."}' | ./run.sh policy.wasm
# Policy script:
# - Reads JSON from stdin
# - Applies rules
# - Outputs decision to stdout: "accept" or "reject"
# ORLY reads the decision and acts accordingly
```
### Benefits
- **Sandboxed** - Cannot access system unless explicitly granted
- **Fast** - Near-native performance with wasmtime's JIT
- **Portable** - Same WASM binary runs everywhere
- **Multi-language** - Write policies in Go, Rust, C, JavaScript, etc.
- **Deterministic** - Same input = same output, always
## Next Steps
1. **Read the full README** - `cat README.md`
2. **Try the examples** - `./test.sh`
3. **Write your own** - Start with the template in README.md
4. **Compile from Go** - Use TinyGo to compile Go to WASM
5. **Integrate with ORLY** - Use as policy execution engine
## File Structure
```
pkg/wasm/shell/
├── build.sh # Build script (wat -> wasm)
├── run.sh # Run script (execute wasm)
├── test.sh # Test all examples
├── hello.wat # Source: Hello World
├── hello.wasm # Binary: Hello World
├── echo.wat # Source: Echo stdin/stdout
├── echo.wasm # Binary: Echo stdin/stdout
├── README.md # Full documentation
└── QUICKSTART.md # This file
```
## Troubleshooting
### "wasmtime not found"
```bash
curl https://wasmtime.dev/install.sh -sSf | bash
export PATH="$HOME/.wasmtime/bin:$PATH"
```
### "wat2wasm not found"
```bash
sudo apt install wabt
```
### WASM fails to run
```bash
# Rebuild from source
./build.sh
# Check the WASM module
wasm-objdump -x your.wasm
```
---
**Happy WASM hacking!** 🎉

353
pkg/wasm/shell/README.md Normal file
View File

@@ -0,0 +1,353 @@
# WASM Shell Runner
Run WebAssembly programs directly in your shell with stdin/stdout support using WASI (WebAssembly System Interface).
## Quick Start
```bash
# Build all WAT files to WASM
./build.sh
# Run the hello example
./run.sh hello.wasm
# Run the echo example (with stdin)
echo "Hello World" | ./run.sh echo.wasm
# Or interactive
./run.sh echo.wasm
```
## Prerequisites
### Install wabt (WebAssembly Binary Toolkit)
```bash
# Ubuntu/Debian
sudo apt install wabt
# Provides: wat2wasm, wasm2wat, wasm-objdump, etc.
```
### Install wasmtime (WASM Runtime)
```bash
# Install via official installer
curl https://wasmtime.dev/install.sh -sSf | bash
# Add to PATH (add to ~/.bashrc for persistence)
export PATH="$HOME/.wasmtime/bin:$PATH"
```
## Examples
### 1. Hello World (`hello.wat`)
Simple example that prints to stdout:
```bash
./build.sh
./run.sh hello.wasm
```
**Output:**
```
Hello from WASM shell!
```
### 2. Echo Program (`echo.wat`)
Reads from stdin and echoes back:
```bash
./build.sh
# Interactive mode
./run.sh echo.wasm
# Type something and press Enter
# Piped input
echo "Test message" | ./run.sh echo.wasm
# From file
cat somefile.txt | ./run.sh echo.wasm
```
**Output:**
```
Enter text: Test message
You entered: Test message
```
## How It Works
### WASI (WebAssembly System Interface)
WASI provides a standard interface for WASM programs to interact with the host system:
- **stdin** (fd 0) - Standard input
- **stdout** (fd 1) - Standard output
- **stderr** (fd 2) - Standard error
### Key WASI Functions Used
#### `fd_write` - Write to file descriptor
```wat
(import "wasi_snapshot_preview1" "fd_write"
(func $fd_write (param i32 i32 i32 i32) (result i32)))
;; Usage: fd_write(fd, iovs_ptr, iovs_len, nwritten_ptr) -> errno
;; fd: File descriptor (1 = stdout)
;; iovs_ptr: Pointer to iovec array
;; iovs_len: Number of iovecs
;; nwritten_ptr: Where to store bytes written
```
#### `fd_read` - Read from file descriptor
```wat
(import "wasi_snapshot_preview1" "fd_read"
(func $fd_read (param i32 i32 i32 i32) (result i32)))
;; Usage: fd_read(fd, iovs_ptr, iovs_len, nread_ptr) -> errno
;; fd: File descriptor (0 = stdin)
;; iovs_ptr: Pointer to iovec array
;; iovs_len: Number of iovecs
;; nread_ptr: Where to store bytes read
```
### iovec Structure
Both functions use an iovec (I/O vector) structure:
```
struct iovec {
u32 buf; // Pointer to buffer in WASM memory
u32 buf_len; // Length of buffer
}
```
## Writing Your Own WASM Programs
### Basic Template
```wat
(module
;; Import WASI functions you need
(import "wasi_snapshot_preview1" "fd_write"
(func $fd_write (param i32 i32 i32 i32) (result i32)))
;; Allocate memory
(memory 1)
(export "memory" (memory 0))
;; Store your strings in memory
(data (i32.const 0) "Your message here\n")
;; Main function (entry point)
(func $main (export "_start")
;; Setup iovec at some offset (e.g., 100)
(i32.store (i32.const 100) (i32.const 0)) ;; buf pointer
(i32.store (i32.const 104) (i32.const 18)) ;; buf length
;; Write to stdout
(call $fd_write
(i32.const 1) ;; stdout
(i32.const 100) ;; iovec pointer
(i32.const 1) ;; number of iovecs
(i32.const 200) ;; nwritten pointer
)
drop ;; drop return value
)
)
```
### Build and Run
```bash
# Compile WAT to WASM
wat2wasm yourprogram.wat -o yourprogram.wasm
# Run it
./run.sh yourprogram.wasm
# Or directly with wasmtime
wasmtime yourprogram.wasm
```
## Advanced Usage
### Pass Arguments
```bash
# WASM programs can receive command-line arguments
./run.sh program.wasm arg1 arg2 arg3
```
### Environment Variables
```bash
# Set environment variables (wasmtime flag)
wasmtime --env KEY=value program.wasm
```
### Mount Directories
```bash
# Give WASM access to directories (wasmtime flag)
wasmtime --dir=/tmp program.wasm
```
### Call Specific Functions
```bash
# Instead of _start, call a specific exported function
wasmtime --invoke my_function program.wasm
```
## Compiling from High-Level Languages
### From Go (using TinyGo)
```bash
# Install TinyGo
wget https://github.com/tinygo-org/tinygo/releases/download/v0.31.0/tinygo_0.31.0_amd64.deb
sudo dpkg -i tinygo_0.31.0_amd64.deb
# Write Go program
cat > main.go << 'EOF'
package main
import "fmt"
func main() {
fmt.Println("Hello from Go WASM!")
}
EOF
# Compile to WASM with WASI
tinygo build -o program.wasm -target=wasi main.go
# Run
./run.sh program.wasm
```
### From Rust
```bash
# Add WASI target
rustup target add wasm32-wasi
# Create project
cargo new --bin myprogram
cd myprogram
# Build for WASI
cargo build --target wasm32-wasi --release
# Run
wasmtime target/wasm32-wasi/release/myprogram.wasm
```
### From C/C++ (using wasi-sdk)
```bash
# Download wasi-sdk
wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sdk-21.0-linux.tar.gz
tar xf wasi-sdk-21.0-linux.tar.gz
# Compile C program
cat > hello.c << 'EOF'
#include <stdio.h>
int main() {
printf("Hello from C WASM!\n");
return 0;
}
EOF
# Compile to WASM
./wasi-sdk-21.0/bin/clang hello.c -o hello.wasm
# Run
wasmtime hello.wasm
```
## Debugging
### Inspect WASM Module
```bash
# Disassemble WASM to WAT
wasm2wat program.wasm -o program.wat
# Show module structure
wasm-objdump -x program.wasm
# Show imports
wasm-objdump -x program.wasm | grep -A 10 "Import"
# Show exports
wasm-objdump -x program.wasm | grep -A 10 "Export"
```
### Verbose Execution
```bash
# Run with logging
WASMTIME_LOG=wasmtime=trace wasmtime program.wasm
# Enable debug info
wasmtime -g program.wasm
```
## Use Cases for ORLY
WASM with WASI is perfect for ORLY's policy system:
### Sandboxed Policy Scripts
```bash
# Write policy in any language that compiles to WASM
# Run it safely in a sandbox with controlled stdin/stdout
./run.sh policy.wasm < event.json
```
**Benefits:**
- **Security**: Sandboxed execution, no system access unless granted
- **Portability**: Same WASM runs on any platform
- **Performance**: Near-native speed with wasmtime's JIT
- **Language Choice**: Write policies in Go, Rust, C, JavaScript, etc.
- **Deterministic**: Same input always produces same output
### Example Policy Flow
```bash
# Event comes in via stdin (JSON)
echo '{"kind":1,"content":"hello"}' | ./run.sh filter-policy.wasm
# Policy outputs "accept" or "reject" to stdout
# ORLY reads the decision and acts accordingly
```
## Scripts Reference
### `build.sh`
Compiles all `.wat` files to `.wasm` using `wat2wasm`
### `run.sh [wasm-file] [args...]`
Runs a WASM file with `wasmtime`, defaults to `hello.wasm`
## Files
- **hello.wat** - Simple stdout example
- **echo.wat** - stdin/stdout interactive example
- **build.sh** - Build all WAT files
- **run.sh** - Run WASM files with wasmtime
## Resources
- [WASI Specification](https://github.com/WebAssembly/WASI)
- [Wasmtime Documentation](https://docs.wasmtime.dev/)
- [WebAssembly Reference](https://webassembly.github.io/spec/)
- [WAT Language Guide](https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format)
- [TinyGo WASI Support](https://tinygo.org/docs/guides/webassembly/wasi/)

34
pkg/wasm/shell/build.sh Executable file
View File

@@ -0,0 +1,34 @@
#!/bin/bash
# Build script for WASM shell examples
# Compiles WAT (WebAssembly Text) to WASM binary
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "Building WASM modules from WAT files..."
# Check if wat2wasm is available
if ! command -v wat2wasm &> /dev/null; then
echo "Error: wat2wasm not found. Install wabt:"
echo " sudo apt install wabt"
exit 1
fi
# Build each .wat file to .wasm
for wat_file in *.wat; do
if [ -f "$wat_file" ]; then
wasm_file="${wat_file%.wat}.wasm"
echo " $wat_file -> $wasm_file"
wat2wasm "$wat_file" -o "$wasm_file"
fi
done
echo "Build complete!"
echo ""
echo "Run with:"
echo " ./run.sh hello.wasm"
echo " or"
echo " wasmtime hello.wasm"

52
pkg/wasm/shell/run.sh Executable file
View File

@@ -0,0 +1,52 @@
#!/bin/bash
# Run script for WASM shell examples
# Executes WASM files using wasmtime with WASI support
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Find wasmtime executable
WASMTIME=""
if command -v wasmtime &> /dev/null; then
WASMTIME="wasmtime"
elif [ -x "$HOME/.wasmtime/bin/wasmtime" ]; then
WASMTIME="$HOME/.wasmtime/bin/wasmtime"
else
echo "Error: wasmtime not found. Install it:"
echo " curl https://wasmtime.dev/install.sh -sSf | bash"
echo ""
echo "Or add to PATH:"
echo " export PATH=\"\$HOME/.wasmtime/bin:\$PATH\""
exit 1
fi
# Get the WASM file from argument, default to hello.wasm
WASM_FILE="${1:-hello.wasm}"
# If relative path, make it relative to script dir
if [[ "$WASM_FILE" != /* ]]; then
WASM_FILE="$SCRIPT_DIR/$WASM_FILE"
fi
if [ ! -f "$WASM_FILE" ]; then
echo "Error: WASM file not found: $WASM_FILE"
echo ""
echo "Usage: $0 [wasm-file]"
echo ""
echo "Available WASM files:"
cd "$SCRIPT_DIR"
ls -1 *.wasm 2>/dev/null || echo " (none - run ./build.sh first)"
exit 1
fi
echo "Running: $WASM_FILE"
echo "---"
# Run the WASM file with wasmtime
# Additional flags you might want:
# --dir=. : Mount current directory
# --env VAR=value : Set environment variable
# --invoke function : Call specific function instead of _start
"$WASMTIME" "$WASM_FILE" "$@"

45
pkg/wasm/shell/test.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/bin/bash
# Test script for WASM shell examples
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "========================================="
echo "WASM Shell Test Suite"
echo "========================================="
echo ""
# Build first
echo "[1/4] Building WASM modules..."
./build.sh
echo ""
# Test hello.wasm
echo "[2/4] Testing hello.wasm (stdout only)..."
echo "---"
./run.sh hello.wasm
echo ""
# Test echo.wasm with piped input
echo "[3/4] Testing echo.wasm (stdin/stdout with pipe)..."
echo "---"
echo "This is a test message" | ./run.sh echo.wasm
echo ""
# Test echo.wasm with heredoc
echo "[4/4] Testing echo.wasm (stdin/stdout with heredoc)..."
echo "---"
./run.sh echo.wasm <<< "Testing heredoc input"
echo ""
echo "========================================="
echo "All tests passed!"
echo "========================================="
echo ""
echo "Try these commands:"
echo " ./run.sh hello.wasm"
echo " echo 'your text' | ./run.sh echo.wasm"
echo " ./run.sh echo.wasm # interactive mode"