feat(FN-3633): document plugin trust policy feature

Adds plugin trust policy documentation across the CLI reference, settings reference, and a new plugin authoring guide, along with a patch-level changeset for `@runfusion/fusion`.

Fusion-Task-Id: FN-3633
This commit is contained in:
Fusion
2026-05-10 12:14:39 -07:00
committed by gsxdsm
parent 48f0353b7f
commit 097653eceb
4 changed files with 55 additions and 1 deletions

View File

@@ -80,6 +80,37 @@ If your plugin is blocked:
- document external calls and sensitive operations in README
- ask operators to run `fn plugin rescan <id>` after publishing fixes
### Signature Verification and Publisher Trust
Fusion supports deterministic detached-signature verification for plugin provenance before plugin code is loaded.
Expected plugin files at the plugin root:
- `manifest.json`
- `plugin-publisher.json` (publisher identity + public key metadata)
- `plugin-signature.json` (detached signature over canonical payload)
Canonical payload inputs (sorted, deterministic):
- normalized `manifest.json`
- publisher metadata from `plugin-publisher.json`
- declared file digest map (sorted by relative path)
Verification statuses:
- `trusted-local` — bundled/in-repo plugin path trusted by local policy exception
- `verified-trusted` — signature verifies and publisher key is trusted
- `verified-untrusted` — signature verifies but publisher/key is not trusted yet
- `unsigned` — no signature bundle present
- `invalid` — signature or digest validation failed (tampered/corrupt)
Trust decisions are explicit and keyed by publisher ID + key fingerprint. Manifest author/homepage strings are informational only and are never used as trust proof.
### Plugin Author Checklist for Signed Releases
1. Produce deterministic file digests for distributed plugin files
2. Publish `plugin-publisher.json` with stable publisher ID and key fingerprint
3. Sign the canonical payload and ship `plugin-signature.json`
4. Keep digest/signature files in source control and release artifacts
5. In release notes, include publisher ID + key fingerprint so operators can verify trust prompts
### Plugin Project Structure
```
@@ -1101,6 +1132,10 @@ This keeps regressions durable while preserving clear ownership boundaries acros
npm publish --access public
```
### Signed plugin recommendation
For production distribution, publish signed artifacts (`plugin-publisher.json` + `plugin-signature.json`) alongside your compiled plugin output so operators can verify provenance under warn/enforce trust policy modes.
### Installation
Users can install your plugin via CLI:

View File

@@ -820,13 +820,16 @@ Plugin lifecycle management.
fn plugin list
fn plugin install <path> [--ai-scan]
fn plugin rescan <id>
fn plugin trust <id>
fn plugin untrust <id>
fn plugin verify <id>
fn plugin uninstall <id> --force
fn plugin enable <id>
fn plugin disable <id>
fn plugin create <name>
```
Subcommands: `list|ls`, `install`, `rescan`, `uninstall`, `enable`, `disable`, `create`.
Subcommands: `list|ls`, `install`, `rescan`, `trust`, `untrust`, `verify`, `uninstall`, `enable`, `disable`, `create`.
Scope semantics:
- `fn plugin install` / `fn plugin uninstall` are **global** operations

View File

@@ -173,6 +173,7 @@ Defaults from `DEFAULT_PROJECT_SETTINGS`; key scope from `PROJECT_SETTINGS_KEYS`
| `unavailableNodePolicy` | `"block" \| "fallback-local"` | `"block"` | Project routing policy used during scheduler dispatch when a task resolves to a remote node and node health is known. `"block"` keeps the task in `todo` if the node is unhealthy; `"fallback-local"` reroutes dispatch to local execution. See [Architecture → Task Routing Architecture](./architecture.md#task-routing-architecture). |
| `groupOverlappingFiles` | `boolean` | `true` | Serialize execution when file scopes overlap. |
| `pluginTrustPolicy` | `"off" | "warn" | "enforce"` | `"warn"` | Plugin provenance enforcement mode: `off` records verification metadata only, `warn` blocks only `invalid` signatures, `enforce` allows only `verified-trusted` or `trusted-local`. |
| `overlapIgnorePaths` | `string[]` | `[]` | Optional project-relative file or directory paths to exclude from overlap blocking (for example `docs` or `generated/openapi.json`). Entries are trimmed, deduplicated, and must not be absolute or contain `..` traversal. |
| `autoMerge` | `boolean` | `true` | Auto-finalize tasks from `in-review`. |
| `mergeStrategy` | `"direct" \| "pull-request"` | `"direct"` | Completion mode (local direct merge vs PR-first). |
@@ -340,6 +341,16 @@ Follow-up policy meanings:
- `suggest-only`: emit suggestions without automatic task creation
- `auto-create`: permit automatic task creation for qualifying follow-ups
### Plugin trust policy (project scope)
`pluginTrustPolicy` controls loader behavior after signature verification:
- `off`: always continue load decisions based on existing plugin lifecycle checks; signature/trust metadata is still persisted
- `warn`: block only `invalid` signatures (tampered/corrupt). `unsigned` and `verified-untrusted` remain loadable with warnings
- `enforce`: allow only `verified-trusted` and `trusted-local`; block `verified-untrusted`, `unsigned`, and `invalid`
`trusted-local` is reserved for bundled in-repo plugin paths so existing shipped plugins remain usable without retro-signing.
### Node Routing settings (project scope)
Node routing controls in the project settings table are configured from **Settings → Node Routing** in the dashboard or via CLI: