Run plugins¶
A plugin can run in three places. Pick the trust boundary that fits the system.
| Mode | Credentials stay | Best for |
|---|---|---|
| Local | On the operator's machine | Fastest setup, personal or admin laptops |
| Customer VPC runner | Inside your network | Regulated environments |
| Publisher-hosted | With the publisher | Turnkey SaaS collection |
Local (default)¶
cs plugin install <name> # public catalog
# or, from a source checkout:
cs plugin dev
cs scan # local run; data stays local
cs sync # optional: upload the snapshot to Horizon
Installing in a Horizon workspace without a hosted endpoint creates a workspace record, not a hosted scan. The workspace tracks version and permissions; scans still run locally.
Customer VPC runner¶
Run the v3 source plugin inside your own network, expose it over TLS, and let Horizon call it. Credentials never leave your VPC.
# build the plugin server
go build -o plugin .
./plugin --manifest > release-metadata.json
# it listens on LISTEN_ADDR (default 127.0.0.1:8443)
# terminate TLS at your ingress; the public endpoint must be grpcs://host:443
LISTEN_ADDR=0.0.0.0:8443 \
TLS_CERT_FILE=/certs/tls.crt TLS_KEY_FILE=/certs/tls.key \
./plugin
Then in Horizon:
- Add the plugin release on the registry Publish page and set the endpoint.
- Add the workspace record and a connection for the plugin.
- The operator approves that exact release, endpoint, and manifest digest.
- Run the scan; only read capabilities are executed.
You can also keep the runner completely offline from Horizon and run the same
plugin through cs scan on a host inside the VPC.
Self-hosted hosted endpoint (cs plugin host)¶
cs plugin host <source> --run is the turnkey path for a workspace-private
hosted source. It builds the plugin's cmd/hosted entrypoint, injects the
installed manifest version, starts a local TLS server, and opens a temporary
Cloudflare quick tunnel.
- The plugin server serves native gRPC and gRPC-Web on the same listener
(
v3hosted.ServeTLS). Horizon uses gRPC-Web because HTTP-only tunnels do not preserve native gRPC trailers. - The CLI runs the quick tunnel with an isolated
HOMEand--protocol http2. This avoids the 404 caused by attaching an existing named-tunnel certificate to a trycloudflare hostname. - No Cloudflare account, API token, named tunnel or DNS record is required.
- The endpoint is registered as
grpcs://<random>.trycloudflare.com; the listing stays workspace-private. - Re-run the command to update the release. Connections must be re-verified when the endpoint or capability schema changes.
The same command works for any plugin. The plugin owns its connection fields, permissions and optional setup page; the core only opens the plugin-supplied setup URL and creates the connection. See Hosted plugin transport.
Publisher-hosted endpoint¶
Publisher-hosted is the turnkey path for customers, but it makes the publisher a trust boundary: the endpoint receives customer connection configuration while it collects. Only publish one if you can operate it securely.
- Scaffold a v3 source project (Horizon → DEVI → Plugin Studio, or the SDK templates).
- Implement
PreflightandScan; declare read-only capabilities and connection methods. - Export metadata and deploy the gRPC server behind public TLS on port 443:
- Publish the release on the registry, set
grpcs://your-host, and submit the exact manifest digest for operator review. - Customers install the workspace plugin and add a connection. The connection form is the one you declared; credentials are encrypted at rest and scoped to one job.
Hosted execution is read-only. A plan is still compiled and executed by the customer's local core, never by the plugin endpoint.
Which install does what¶
| Install | Scans run | Credentials | Execution |
|---|---|---|---|
| Local CLI | On the host | Host chain | Local |
| CLI-only workspace record | On the host, snapshot synced | Host chain | Local |
| Customer runner | In the VPC | VPC | Customer |
| Publisher-hosted | Publisher endpoint | Leased, read-only | Publisher |
For the full trust checklist, see Hosted plugins.