Documentation
¶
Overview ¶
Package plugin is the wick connector plugin platform: the shared transport (hashicorp/go-plugin + gRPC) used by the host to drive a connector that runs in its own process, and the SDK a connector binary uses to serve itself. See docs/proposals/connector-plugin-platform.
Index ¶
- Constants
- Variables
- func DumpManifest(mod connector.Module) ([]byte, error)
- func GenerateKeypair() (privB64, pubB64 string)
- func NewServer(mod connector.Module) pb.ConnectorServer
- func NormalizeKind(k string) string
- func ProtoVersionSupported(v int) bool
- func RequireSig() bool
- func Serve(mod connector.Module)
- func SignSHA256(privKeyPath, sha256hex string) (string, error)
- func SupportedProtoVersions() []int
- func TrustedKeys() []string
- func ValidateKey(key string) error
- func VerifyManifest(m Manifest, binaryPath string) error
- func VerifySHA256(trustedPubsB64 []string, sha256hex, sigB64 string) bool
- type ConnectorGRPCPlugin
- type ExecCall
- type GRPCConn
- type Manifest
Constants ¶
const ( KindConnector = "connector" KindTool = "tool" KindJob = "job" )
Plugin kinds. connector is the default and the only kind with a host-side execution adapter today; tool/job are accepted by the manifest + build tooling so the layout and CLI are forward-compatible (§18).
const ManifestSchemaVersion = 1
ManifestSchemaVersion is the current envelope format version.
const MinProtoVersion = 1
MinProtoVersion is the OLDEST proto version this host still accepts. The host supports the inclusive range [MinProtoVersion, ProtoVersion]; a plugin built against any version in that range loads, anything outside is rejected at handshake/verify with a clear error (never a crash).
This is the range-negotiation contract (§19.2): bumping ProtoVersion for a breaking change while leaving MinProtoVersion behind opens a transition window where v(old) and v(new) plugins both run; dropping support for an old version is a deliberate MinProtoVersion bump, not an accident.
const PluginName = "connector"
PluginName is the dispense key both sides agree on.
const ProtoVersion = 1
ProtoVersion is the wire-contract version a freshly built plugin stamps into its manifest (the version this build of the SDK speaks natively). It bumps ONLY on a breaking proto change.
Variables ¶
var ErrPluginOp = errors.New("plugin operation error")
ErrPluginOp wraps an operation-level error returned by the plugin (vs a transport error). Callers can errors.Is against it.
var Handshake = goplugin.HandshakeConfig{ ProtocolVersion: ProtoVersion, MagicCookieKey: "WICK_CONNECTOR_PLUGIN", MagicCookieValue: "b3f1c2a4-wick-connector-grpc", }
Handshake is the basic mutual sanity check go-plugin runs before any RPC: a plugin launched without the matching magic cookie exits with a human-readable error instead of hanging.
var RequireSignature bool
RequireSignature, when true (set via ldflags in release builds), makes the loader reject any plugin without a valid signature from a trusted key. The env var WICK_PLUGIN_REQUIRE_SIGNATURE ("1"/"0") overrides it at runtime.
var TrustedPubKey string
TrustedPubKey is the publisher's base64 ed25519 public key baked into a released wick binary via -ldflags. Empty in dev builds.
var Version = "0.0.0-dev"
Version is the connector release version stamped into the manifest. It is overridden at build time via -ldflags "-X .../pkg/plugin.Version=1.2.3".
var VersionedPlugins = buildVersionedPlugins()
VersionedPlugins maps proto_version -> plugin set. The host advertises every version in [MinProtoVersion, ProtoVersion]; go-plugin negotiates the highest version common to host and plugin and rejects (clear error, no crash) a plugin whose version falls outside the host's range. Built from the supported range so adding a future v2 plugin set is the only edit needed.
Functions ¶
func DumpManifest ¶
DumpManifest returns json.Marshal(mod) — the manifest is the module itself, so the plugin.json on disk can never drift from the binary.
func GenerateKeypair ¶
func GenerateKeypair() (privB64, pubB64 string)
GenerateKeypair returns a fresh ed25519 keypair as base64 strings (private = 64-byte seed||pub, public = 32-byte).
func NewServer ¶
func NewServer(mod connector.Module) pb.ConnectorServer
NewServer builds the plugin-side service for one connector module.
func NormalizeKind ¶
NormalizeKind returns a valid kind, defaulting empty/unknown to connector.
func ProtoVersionSupported ¶
ProtoVersionSupported reports whether v is within the accepted range.
func RequireSig ¶
func RequireSig() bool
RequireSig reports the effective signature-required policy (env overrides the baked default).
func Serve ¶
Serve is the entire main() of a connector plugin binary. Call it with the module the binary wraps. When invoked with --dump-manifest it prints the manifest JSON and exits (used by `make plugins` / CI); otherwise it serves the gRPC plugin and blocks until the host disconnects.
func SignSHA256 ¶
SignSHA256 reads a base64 ed25519 private key from privKeyPath and signs the sha256 hex string, returning the base64 signature.
func SupportedProtoVersions ¶
func SupportedProtoVersions() []int
SupportedProtoVersions returns every proto version this host can speak, newest first. Used both to advertise VersionedPlugins to go-plugin and to validate a manifest's declared version.
func TrustedKeys ¶
func TrustedKeys() []string
TrustedKeys returns every trusted base64 public key: the baked TrustedPubKey plus any in WICK_PLUGIN_PUBKEY (comma-separated).
func ValidateKey ¶
ValidateKey enforces that a plugin's Meta.Key is a safe slug. Key is the one identity used everywhere — the source folder, the zip name, the on-disk install dir (DefaultDir/<key>), and the runtime registry key — so it must be a plain lowercase slug with no path separators or traversal (it becomes a directory name; a key like "../x" or "a/b" would escape the plugins dir). Enforced at BOTH build time and install time so a hand-written manifest can't sneak a bad key past the build.
func VerifyManifest ¶
VerifyManifest checks a plugin envelope against the binary at binaryPath and the host's trust policy. Returns nil when the plugin is safe to load. Order: os_arch -> proto_version -> sha256 integrity -> signature.
func VerifySHA256 ¶
VerifySHA256 reports whether sigB64 is a valid signature of sha256hex by ANY of the trusted base64 public keys. Bad inputs return false (no panic).
Types ¶
type ConnectorGRPCPlugin ¶
type ConnectorGRPCPlugin struct {
goplugin.NetRPCUnsupportedPlugin
Impl pb.ConnectorServer
}
ConnectorGRPCPlugin is the go-plugin descriptor. Impl is set only on the plugin side (it carries the server implementation); the host leaves it nil and receives a client from GRPCClient.
func (*ConnectorGRPCPlugin) GRPCClient ¶
func (p *ConnectorGRPCPlugin) GRPCClient(_ context.Context, _ *goplugin.GRPCBroker, c *grpc.ClientConn) (any, error)
func (*ConnectorGRPCPlugin) GRPCServer ¶
func (p *ConnectorGRPCPlugin) GRPCServer(_ *goplugin.GRPCBroker, s *grpc.Server) error
type ExecCall ¶
type ExecCall struct {
Operation string
Input map[string]string
Creds map[string]string
RequestID string
SessionID string
}
ExecCall is the host-side call descriptor the adapter closure fills from a *connector.Ctx (operation + plaintext input + plaintext creds).
type GRPCConn ¶
type GRPCConn interface {
Execute(ctx context.Context, call ExecCall) ([]byte, error)
ExecuteStream(ctx context.Context, call ExecCall) ([]byte, error)
Schema(ctx context.Context) ([]byte, error)
ResolveIdentity(ctx context.Context, accessToken string) (userID, displayName string, err error)
}
GRPCConn is the host-facing surface of a connector plugin client. The manager hands this to the adapter closure; *grpcClient implements it.
type Manifest ¶
type Manifest struct {
SchemaVersion int `json:"schema_version"`
// Kind is the plugin kind: "connector" (default), "tool", or "job". The
// platform routes installed plugins by kind into the matching registry;
// all kinds share the same gRPC service (Execute(op,args)→result is generic
// enough for a tool's Run(input) and a job's Run(trigger)). Empty = the
// pre-kind default "connector" for backward compatibility.
Kind string `json:"kind,omitempty"`
Version string `json:"version"`
ProtoVersion int `json:"proto_version"`
Entry string `json:"entry"`
OSArch []string `json:"os_arch"`
SHA256 string `json:"sha256"`
Signature string `json:"signature"`
Module connector.Module `json:"module"`
}
Manifest is the on-disk plugin.json envelope: the connector module plus the distribution metadata the host needs to verify and load it. The connector module marshals with its func fields excluded (json:"-"), so the envelope is fully round-trippable.
func BuildSelfManifest ¶
BuildSelfManifest builds the envelope for a connector plugin binary from the binary itself (self-pack): it hashes os.Executable() and, when signKeyPath is non-empty, signs that hash. mod is the connector's module.