Skip to content

Commit b92181c

Browse files
committed
docs: plugin trust policy (fail-closed default), capability tiers, signing
- document Ed25519 signing, digest binding, fail-closed allow_unsigned_host_risk default; capability risk tiers; system/wasm/worker boundaries
1 parent 8e18f79 commit b92181c

5 files changed

Lines changed: 129 additions & 7 deletions

File tree

README.md

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ This directory is the starting point for new Lattice extensions.
44

55
Plugin categories:
66

7-
- `system-go/` - trusted system plugin process template for host operations.
7+
- `system-go/` - trusted first-party system plugin process template for host operations.
88
- `worker/` - capability-limited dashboard/server Worker template.
9-
- `wasm/` - future Wasm plugin template notes.
9+
- `wasm/` - future sandboxed third-party Wasm plugin template notes.
1010

1111
## Manifest
1212

@@ -17,13 +17,108 @@ Every plugin must declare an explicit capability list:
1717
"id": "example.nft-guard",
1818
"name": "Example nft Guard",
1919
"type": "system",
20+
"version": "0.1.0",
21+
"publisher": "latticenet",
22+
"entrypoint": "system-go/lattice-plugin-example",
23+
"digest_sha256": "<artifact sha256 hex>",
24+
"signature_ed25519": "<base64 ed25519 signature>",
2025
"capabilities": ["network:plan"]
2126
}
2227
```
2328

2429
Unknown capabilities are rejected by the server. Dangerous capabilities such as
2530
`network:apply` should never be granted to third-party plugins by default.
2631

32+
Manifest identity is intentionally strict:
33+
34+
- `id` is a stable lowercase identifier using only `a-z`, `0-9`, `.`, and `-`;
35+
it must not contain whitespace, slashes, path traversal, or uppercase letters.
36+
- `name` must be printable and at most 80 characters.
37+
- `capabilities` must be non-empty and must not contain duplicates.
38+
- `version` and `entrypoint` are part of the public plugin contract even when a
39+
current template does not need generated code yet.
40+
- `publisher` identifies the signer/trust root. Production loaders should
41+
accept high-risk system plugins only from trusted publishers.
42+
- `digest_sha256` is the lowercase hex SHA-256 of the plugin artifact/package.
43+
- `signature_ed25519` signs the canonical Lattice plugin payload for
44+
`id`, `name`, `type`, `version`, `entrypoint`, `publisher`, `digest_sha256`, and
45+
capabilities. It prevents replacing the artifact or reusing a signature for a
46+
different plugin id.
47+
48+
## Capability Guide
49+
50+
Low-risk read capabilities:
51+
52+
- `node:read`
53+
- `monitor:read`
54+
- `audit:read`
55+
- `kv:read`
56+
- `static:read`
57+
- `task:read`
58+
59+
Operator-write capabilities:
60+
61+
- `kv:write`
62+
- `worker:route`
63+
- `notify:send`
64+
65+
High-risk host capabilities:
66+
67+
- `node:admin`
68+
- `monitor:admin`
69+
- `ddns:admin`
70+
- `tunnel:admin`
71+
- `static:write`
72+
- `task:run`
73+
- `network:plan`
74+
- `network:apply`
75+
76+
Type restrictions:
77+
78+
- `system` plugins may request high-risk capabilities, but should be reserved
79+
for first-party or operator-audited plugins.
80+
- `worker` plugins may request only `worker:route`, `kv:read`, and
81+
`static:read`.
82+
- `wasm` plugins may request read and operator-write capabilities, but may not
83+
request high-risk host capabilities.
84+
85+
Third-party plugins should start with read-only capabilities. First-party system
86+
plugins may request high-risk capabilities only when their actions produce an
87+
auditable dry-run plan and go through the Lattice approval flow.
88+
89+
`task:read` is intentionally separate from `task:run`: reading task metadata and
90+
results must not imply the ability to queue remote execution.
91+
92+
## Signing Model
93+
94+
Development manifests may omit `digest_sha256` and `signature_ed25519`, but a
95+
production Lattice loader should verify them for any host-risk capability such as
96+
`network:plan`, `network:apply`, `task:run`, `ddns:admin`, or `tunnel:admin`.
97+
98+
The server-side verifier expects:
99+
100+
- `publisher` to match a trusted Ed25519 public key configured by the operator.
101+
- `digest_sha256` to match the exact plugin artifact bytes.
102+
- `signature_ed25519` to verify against the canonical Lattice signing payload.
103+
104+
Trust policy JSON:
105+
106+
```json
107+
{
108+
"allow_unsigned_host_risk": false,
109+
"trusted_publishers": {
110+
"latticenet": "base64-raw-ed25519-public-key"
111+
}
112+
}
113+
```
114+
115+
> Fail-closed by default: omitting `allow_unsigned_host_risk` (or setting it
116+
> `false`) requires a trusted-publisher Ed25519 signature for **every** host-risk
117+
> plugin. Set it `true` only for local development on a host you fully control.
118+
119+
Do not sign unpacked source directories casually. Build a deterministic artifact
120+
first, hash that artifact, then sign the manifest payload for that digest.
121+
27122
## System Plugin Contract
28123

29124
The bootstrap template uses newline-delimited JSON over stdio:
@@ -42,4 +137,3 @@ Output:
42137

43138
Future Lattice releases can replace stdio with gRPC/hashicorp-go-plugin while
44139
keeping the same capability and approval semantics.
45-

SECURITY.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,24 @@ Rules:
88
- No process execution in third-party plugins.
99
- No environment variable access by default.
1010
- No arbitrary network access by default.
11-
- `network:apply`, `task:run`, and `static:write` must be treated as high-risk.
11+
- Manifest ids must be stable lowercase identifiers, never paths or user-facing
12+
labels. Capability lists must be explicit, non-empty, and duplicate-free so
13+
reviews and audit events cannot disagree about what was granted.
14+
- Production manifests for high-risk/system plugins must include a trusted
15+
`publisher`, artifact `digest_sha256`, and `signature_ed25519`. Unsigned
16+
development manifests are acceptable only before installation/loading.
17+
- `network:apply`, `task:run`, `node:admin`, `ddns:admin`, `tunnel:admin`,
18+
`monitor:admin`, `network:plan`, and `static:write` must be treated as high-risk.
19+
- `task:read` is read-only and must never grant task creation or remote
20+
execution.
21+
- `worker` plugins may only declare `worker:route`, `kv:read`, and
22+
`static:read`.
23+
- `wasm` plugins may not declare high-risk host capabilities.
24+
- High-risk capabilities require a trusted `system` plugin.
25+
- Plugins that affect a node must be constrained by the caller's node allowlist.
26+
- Webhook-style plugins must use the server's guarded outbound HTTP client; they
27+
must not dial loopback, private, link-local, metadata, or special-use ranges.
1228
- All privileged operations must be auditable by `lattice-server`.
1329

1430
System plugins are trusted built-ins. Third-party plugins should target the
1531
future Wasm host or the restricted Worker interface.
16-

manifest.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
"id": "example.lattice-plugin",
33
"name": "Example Lattice Plugin",
44
"type": "system",
5+
"version": "0.1.0",
6+
"publisher": "latticenet",
7+
"entrypoint": "system-go/lattice-plugin-example",
58
"capabilities": ["network:plan"]
69
}
7-

wasm/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ sandbox. Lattice will use an explicit host API model:
88
- No environment variable access.
99
- No arbitrary network access.
1010
- KV/static/notify APIs only when the manifest grants the matching capability.
11+
- No high-risk host capabilities: `node:admin`, `monitor:admin`,
12+
`ddns:admin`, `tunnel:admin`, `static:write`, `task:run`,
13+
`network:plan`, or `network:apply`.
1114

1215
The current MVP validates manifests but does not execute Wasm yet. Keep new
1316
third-party plugin designs compatible with this capability model.
14-

worker/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,12 @@ Suggested manifest:
2121
}
2222
```
2323

24+
Worker plugins are deliberately narrow. The server accepts only these
25+
capabilities for `type: "worker"`:
26+
27+
- `worker:route`
28+
- `kv:read`
29+
- `static:read`
30+
31+
Use a trusted `system` plugin when a feature needs host, process, network-plan,
32+
DDNS, tunnel, or remote-task capabilities.

0 commit comments

Comments
 (0)