feat(plugins): install signed registry binaries - #728
Conversation
📓 Changelog previewThis is what your commits will add to the generated ## [Unreleased]
### Added
- **plugins:** Install signed registry binaries
### Fixed
- **plugins:** Close registry review findings
- **plugins:** Close registry merge blockers
- **plugins:** Gate management controls by role
### Testing
- **plugins:** Prove candidate process transitions
- **plugins:** Exercise protocol v2 install flow |
Greptile SummaryThe PR replaces legacy external-plugin installation with a signed registry binary flow and adds operator trust-anchor configuration, verified staging and activation, startup re-verification, protected management APIs, and permission-aware console controls.
Confidence Score: 5/5The PR appears safe to merge because the previously reported identity and administrator-gating failures are fixed and no blocking failure remains. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| crates/temps-external-plugins/src/catalog.rs | Defines signed catalogue verification, platform release selection, trust-anchor parsing, and monotonic revision handling. |
| crates/temps-external-plugins/src/install.rs | Implements streamed digest verification, secure staging, receipts, active-release verification, and atomic activation. |
| crates/temps-external-plugins/src/manager.rs | Adds verified candidate startup and promotion while consistently indexing processes by validated catalogue identity. |
| crates/temps-external-plugins/src/service.rs | Coordinates signed catalogue selection, installation, discovery, reload, and runtime-surface refresh. |
| crates/temps-external-plugins/src/handler.rs | Exposes protected catalog, install, status, and reload endpoints with sensitive-action and audit integration. |
| crates/temps-cli/src/commands/serve/mod.rs | Adds plugin-registry trust-anchor options and validates the paired configuration during server bootstrap. |
| web/src/pages/settings/PluginsPage.tsx | Adds plugin catalogue, install, status, and reload controls while correctly restricting management actions to administrator roles. |
| web/src/hooks/usePlugins.ts | Adds typed query and mutation hooks for plugin management and supports disabling the admin-only catalogue query. |
Sequence Diagram
sequenceDiagram
participant A as Administrator
participant T as Temps
participant R as Signed registry
participant P as Plugin candidate
A->>T: Install plugin
T->>T: Check SystemAdmin and recent verification
T->>R: Fetch signed catalogue
T->>T: Verify signature and monotonic revision
T->>R: Stream selected platform binary
T->>T: Verify SHA-256 and stage candidate
T->>P: Start candidate
P-->>T: Hello and manifest
T->>T: Validate catalogue identity
T->>P: Launch configuration
P-->>T: Ready
T->>T: Atomically activate release
T-->>A: Installation status
Reviews (14): Last reviewed commit: "chore(plugins): merge main and resolve c..." | Re-trigger Greptile
Confirmed and fixed in Worth separating the two halves, because the first was already addressed and the second is the real one: Which name we look up. Which name the process is actually filed under. This is the finding, and switching to The fix verifies the started plugin's declared identity and, on a mismatch, shuts the process down via the name it actually registered under — otherwise refusing the install would leave precisely the orphan the check exists to prevent — then fails with a message naming both identities so the operator knows which side to correct. The rule is extracted into Flagging one thing you didn't: this is the second bug from the same identity conflation in this code path. The original was binary-filename vs manifest-name; this is declared vs locally-known. Both were silent — everything reports success while the plugin is unreachable — which is why the check now fails loudly rather than warning. |
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
Replace archive and package-manager installation with bounded direct binary downloads authenticated by an Ed25519-signed registry. Persist revision rollback protection, verify the exact installed executable, stage candidates before activation, scrub process secrets, and audit sensitive install outcomes. Signed-off-by: David Viejo <dviejo@kfs.es>
036bc78 to
5eb9086
Compare
Wire operator-controlled registry trust into the shipped CLI, preserve reload failures through the API and audit trail, sanitize public diagnostics, and clean every failed staging path. Add regression coverage for trust parsing, authorization, receipt tampering, handshake bounds, secret disclosure, and lifecycle ordering. Signed-off-by: David Viejo <dviejo@kfs.es>
Exercise promotion and discard with real child processes so rollback behavior proves old processes are reaped, accepted candidates remain active, and rejected candidates never enter the process table. Signed-off-by: David Viejo <dviejo@kfs.es>
Use a real Unix-socket WebSocket fixture to prove signed download, staged handshake, authenticated channel setup, activation, and promotion. Verify a rejected upgrade preserves the active record and running process while removing its candidate directory. Signed-off-by: David Viejo <dviejo@kfs.es>
Signed-off-by: David Viejo <dviejo@kfs.es>
Signed-off-by: David Viejo <dviejo@kfs.es>
Signed-off-by: David Viejo <dviejo@kfs.es>
Summary
registry.temps.shcatalogue.API
GET /x/plugins/catalogPOST /x/plugins/installwith{ "name": "plugin-name" }GET /x/plugins/{name}/statusPOST /x/plugins/reloadreturns 200 for full success, 207 for partial success, and 502 when all activated plugins fail.Registry trust configuration
Temps accepts an operator-controlled Ed25519 trust anchor as a required pair:
Equivalent environment variables are
TEMPS_PLUGIN_REGISTRY_KEY_IDandTEMPS_PLUGIN_REGISTRY_PUBLIC_KEY. Missing trust remains visibly unconfigured and fails closed. Half-configured, malformed, empty, or non-32-byte anchors are rejected before server startup. The public key is never logged; the signing private key remains outside Temps.Artifact model
The registry contains metadata and signed release identities. Each platform release resolves directly to one standalone executable:
TypeScript plugins can be compiled into standalone binaries with Bun, and Rust plugins with Cargo. Temps only receives and runs the final executable.
Evidence
Plugin and CLI regression suites
cargo test --lib -p temps-external-plugins -p temps-cliCoverage includes trust configuration, authorization, signer errors, reload auditing, staging cleanup, receipt/binary tampering, handshake bounds, secret redaction, and lifecycle ordering. A composed protocol-v2 fixture proves signed download → Hello → launch configuration → Ready → authenticated Unix-socket WebSocket → activation/promotion. A rejected upgrade preserves the prior active record/process and removes its candidate directory.
Strict lint
Full workspace library check
cargo fmt --all -- --checkandgit diff --checkalso pass.Security gate: APPROVED, with no remaining findings. Regression coverage proves that a private installation path and sentinel database credential do not reach RFC 7807 responses or serialized audit events.
Deployment dependency
https://registry.temps.sh/api/pluginsmust serve the signed catalogue envelope and direct binary artifacts. Operators must configure the corresponding published Ed25519 public key and key ID. The signing private key must never be stored in the Temps repository or runtime binary.