Plugin Security
The plugin system provides several security features to harden plugins in production environments. All security settings are off by default for backward compatibility.
Fuel Limits
Fuel limits restrict how many WASM instructions a single plugin call can execute. This prevents infinite loops or excessive computation from blocking the server:
plugins: enabled: true fuel_limit: 1000000 # ~100ms of execution per call
When a plugin exceeds its fuel budget, the call returns an error and the plugin’s output is discarded. The server continues normally using the original content.
To calibrate the limit, run with debug logging enabled:
RUST_LOG=accent=debug accent serve
Each plugin call logs its fuel consumption:
DEBUG Plugin 'syntax-highlight' on_render consumed 42317 fuel units
Compilation Caching
Compilation caching stores compiled WASM modules on disk, reducing startup time on subsequent runs:
plugins: compilation_cache: .cache/plugins
The directory is created automatically. If creation fails, the server continues without caching.
Pre-compilation
AOT (ahead-of-time) pre-compilation compiles plugins to native code at startup rather than JIT-compiling on first use:
plugins: precompile: true
This trades slower startup for faster first-call latency. Best combined with compilation_cache so the compiled module is cached for subsequent startups.
API Version Compatibility
Each plugin declares the host api_version it targets in its plugin.toml. At load time the host checks that version against the supported range it advertises: a minimum supported version and the newest version it implements. Advertising a range, rather than a single pinned version, lets a plugin built against an older-but-still-supported API keep loading — the previous API generation keeps working until support for it is explicitly retired.
A plugin is accepted when its api_version falls within the supported range, using the semver 0.x convention (below 1.0 the minor is the breaking unit; at and above 1.0 the major is). A plugin outside the range is skipped with an actionable warning:
- Newer than the host implements — upgrade Accent to a build that provides the required API.
- Older than the supported floor — rebuild the plugin against a still-supported API.
- Not valid semver — fix the
api_versionstring (for example,"0.1.0").
Skipping incompatible plugins prevents a plugin built for a newer API from loading and producing incorrect results, while keeping older-but-supported plugins working.
Filesystem Access
By default, plugins run in a fully sandboxed WASI environment with no access to the host filesystem. Plugins that need to read files (e.g., EXIF metadata extraction, content indexing) can opt in to filesystem access.
This requires two things:
- The plugin declares
requires_fs = truein itsplugin.toml - The site operator configures which paths are available in
config.yaml
Plugin Side
Add requires_fs = true to the [plugin] section:
[plugin]
name = "exif-reader"
version = "0.1.0"
api_version = "0.1.0"
requires_fs = true
Plugins without this field (or with requires_fs = false) receive no filesystem paths, regardless of what the site operator configures.
Site Operator Side
Define allowed_paths in config.yaml to map virtual paths (as seen inside the WASM module) to host filesystem paths:
plugins: enabled: true allowed_paths: /content: "ro:./site/content" /media: "ro:./site/media" /data: ./site/data
- Keys are virtual paths visible inside the plugin (e.g.,
/content) - Values are host filesystem paths (e.g.,
./site/content) - Prefix a host path with
ro:to grant read-only access (recommended for content and media directories) - Paths without the
ro:prefix grant read-write access
If a plugin declares requires_fs but no allowed_paths are configured, a warning is logged and the plugin runs without filesystem access.
Behavior Summary
requires_fs | allowed_paths configured | Result |
|---|---|---|
false or omitted | any | No paths granted (fully sandboxed) |
true | non-empty | Paths granted to the plugin |
true | empty or missing | Warning logged, no paths granted |