feat: install plugins from approved source commits
CI / php-store (push) Waiting to run
CI / python-components (push) Waiting to run

This commit is contained in:
2026-08-24 21:37:17 +02:00
parent f36d6be511
commit 26aea40e6a
27 changed files with 414 additions and 47 deletions
+4 -3
View File
@@ -6,7 +6,7 @@ decision is revalidated against the configured JSON API immediately before a lif
The daemon is **dry-run by default**. It serializes operations, persists idempotency and state in
SQLite, accepts one bounded JSON line per Unix-stream connection, verifies Linux peer credentials,
downloads only an approved immutable wheel, and invokes subprocesses only as fixed argument arrays
downloads only an approved immutable wheel or commit-bound source archive, and invokes subprocesses only as fixed argument arrays
with `shell=False`.
## Install and one-time operator setup
@@ -27,7 +27,7 @@ active; this switch only permits private/reserved DNS results.
The agent owns only these two configured files:
- `paths.include_path`, which contains only `STORE_PLUGINS = [...]`;
- `paths.requirements_path`, which contains the locked direct wheel references.
- `paths.requirements_path`, which contains locked wheel references. Locally built wheels are cached below `/opt/netbox/.netbox-store-wheels`.
In the operator-owned NetBox `configuration.py`, add once, after the normal `PLUGINS` declaration:
@@ -112,7 +112,7 @@ value as an opaque Store marker, and the agent compares it exactly with the fres
Artifact `sha256`, in contrast, is always a lowercase 64-character SHA-256.
The plugin and release must be approved, the release immutable and compatible with the configured
NetBox version. The artifact must be a valid wheel whose filename distribution and version match
NetBox version. A wheel's filename distribution and version must match
the catalog, and its byte count, digest, host, scheme and DNS addresses are checked while streaming.
Redirects, source distributions, private/reserved DNS targets (unless explicitly enabled for a test
environment), and catalog additions outside the v1 schema fail closed.
@@ -151,6 +151,7 @@ netbox-store-agent status 20f4274f-d4e5-42bf-9164-967b1a774481
- `install` and `update` re-fetch plugin and release, exactly match the approval token, download and
validate the wheel, then use `pip --no-index --no-deps --only-binary=:all: --require-hashes`.
- Source archives must be tied to an exact commit. The agent rejects unsafe archive members and requires configured `unshare`/`setpriv` executables plus a dedicated build UID/GID. It builds without network access and with dropped privileges via `pip wheel --no-index --no-deps --no-build-isolation`, validates the result, and caches only that wheel for future NetBox upgrades. Reviewing source code remains a privileged trust decision because Python build backends execute code.
- New installs remain disabled. Updating an enabled plugin runs NetBox `migrate`, `collectstatic`,
and restarts every configured service (`netbox` and `netbox-rq` in the example).
- `enable` revalidates its installed release, writes the include, migrates, collects static files,