Repository navigation
feat: let extensions contribute host commands - #95
Conversation
An installed extension's commands/host/ executables become `enclave <name>` verbs, so an extension can ship something that has to run outside the sandbox, like a VNC viewer. Names resolve after the user's own commands/ trees, so an install never takes over a name already in use. These are the only thing an extension ships that executes outside a container. The capability summary leads with them, the diff an update renders repeats the risk, and the result envelope and `list` carry them under --json, where there is no narration to read. commands/ is excluded from the build context and the image identity hash like the provenance sidecar, but the tree hash still covers it, so the rebuild hint now asks whether a change reached the image at all. Implements #87
EclipseSourceAI
left a comment
There was a problem hiding this comment.
Note
Autonomous AI review.
This review was done by an AI agent and therefore may contain mistakes. Feel free to ignore any comment you disagree with. A thumbs-down reaction on a comment marks it as rejected for follow-up reviews. Noting why in a reply helps, since replies are read too.
Resolving all AI comments does not lead to an automatic approval. A maintainer still needs to review and sign off on the overall architecture and design.
To get an updated review after pushing changes, a maintainer may re-request a review from this account.
Running in Eclipse Enclave, submitted via review-guard-mcp
Adds a third source for enclave <verb>: an installed extension's commands/host/ executables. usercmd.Discover scans the user extension root after the user's own host//session/ trees, so an install can never take a name already in use, and every loser gets a warning. commands/ is excluded from the build context and the image identity hash (overlayNamedExtensionDirs), while TreeHash still covers it, with changesReachImage keeping an update confined to that tree from promising a rebuild. The capability surface is extended consistently: a leading "host commands" row in the summary, a diff entry that repeats the risk on update, hostCommands in the list --json and add/update/remove envelopes, and a text [host: ...] suffix.
The approach fits the existing extension machinery well and the test coverage is solid. Points to focus on:
scanExtensionsfilters extension directories withentry.IsDir()only, which pulls in the installer's dot-prefixed.replaced-*leftovers. I reproduced it: a leftover from an interrupted update contributes a working host verb thatlistandremovecannot see. This is the one I would fix before merge.extinstall.hostCommandNamesduplicates the file filter thatusercmd.scanDiralready implements, and the doc comment claims it is the single definition.- The summary and
removereport verbs that may never register (built-in or user-command collisions).
Also a docs-size nit on the new ARCHITECTURE.md bullet.
Skip installer staging directories when scanning extensions, share the command filter between usercmd and extinstall, and stop promising verbs that a built-in or the user's own command already takes.
EclipseSourceAI
left a comment
There was a problem hiding this comment.
Note
Autonomous AI review.
This review was done by an AI agent and therefore may contain mistakes. Feel free to ignore any comment you disagree with. A thumbs-down reaction on a comment marks it as rejected for follow-up reviews. Noting why in a reply helps, since replies are read too.
Resolving all AI comments does not lead to an automatic approval. A maintainer still needs to review and sign off on the overall architecture and design.
To get an updated review after pushing changes, a maintainer may re-request a review from this account.
Running in Eclipse Enclave, submitted via review-guard-mcp
Follow-up review of commit b0e18ea, which addresses all four points from my last pass.
.replaced-*staging dirs are excluded fromscanExtensionsviaconfig.IsExtensionDir(shared withvalidate_extensions.go), with a regression test (TestDiscoverIgnoresInstallerStagingDirs).extinstall.hostCommandNamesis gone;usercmd.ExtensionCommandNamesis now the single filter used by capabilities,Inventory, and (indirectly, viaResolving) remove.- Names shadowed by a built-in or the user's own command are no longer promised:
usercmd.Shadowedbacks aShadowedHostCommandsmap that both the capability summary/diff (addedHostCommands()) and the remove note (usercmd.Resolving) respect, each covered by new tests. - The
ARCHITECTURE.mdbullet is trimmed to the architectural facts and links toextensions/README.md#host-commands.
Verified go build ./... and go test ./internal/usercmd/... ./internal/extinstall/... ./internal/cli/... all pass on the merged tree. Didn't find anything new to flag in this commit; scope is tight and matches its stated purpose.
These previous comments can be resolved as they are now handled:
- installer staging dirs (
.replaced-*) no longer register as host commands - the host-command file filter now has a single shared definition instead of a second copy
- the summary/diff and remove note no longer promise verbs shadowed by a built-in or user command
- the ARCHITECTURE.md bullet is trimmed and links to the extensions doc instead of duplicating it
I can't resolve them myself as I would need write permission on this repository.
tortmayr
left a comment
There was a problem hiding this comment.
Changes look good to me and i tested the PR in combination with eclipse-enclave/enclave-extensions#5.
Work like a charm.
@xai You mentioned that you have some security concerns regarding this feature. Do you want to have a second look. Otherwise we could merge this.
xai
left a comment
There was a problem hiding this comment.
Looks good to me as well, and works as intended 👍
Regarding the security concern: It makes the attack significantly surface larger, but the user is made aware of the risk before the installation of an extension with host commands, so IMHO that is ok.
What it does
An installed extension's commands/host/ executables become
enclave <name>verbs, so an extension can ship something that has to run outside the sandbox, like a VNC viewer. Names resolve after the user's own commands/ trees, so an install never takes over a name already in use.These are the only thing an extension ships that executes outside a container. The capability summary leads with them, the diff an update renders repeats the risk, and the result envelope and
listcarry them under --json, where there is no narration to read.commands/ is excluded from the build context and the image identity hash like the provenance sidecar, but the tree hash still covers it, so the rebuild hint now asks whether a change reached the image at all.
Implements #87
How to test
Install the
vncfeature of https://github.com/sdirix/enclave-extensions which makes use ofhostCommandto offerenclave vnc-viewercommand.Follow-ups
Breaking changes
Review checklist