internalplatform

package
v1.0.37 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 21, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package platformhost is the bootstrap-time orchestrator that turns the global plugin registry (extension/platform.RegisteredPlugins) into:

  • a populated internal/hook.Registry (Observer / Wrapper / Lifecycle)
  • a list of cmdpolicy.PluginRule contributions (one per plugin that called r.Restrict)

Two key invariants:

  • **Atomic install.** A plugin's Install() runs against a staging Registrar; only when Install returns nil AND validateSelf passes does the host commit the staged hooks/rule. Partial install never reaches the live Registry, so a half-loaded plugin cannot leave stale Observer / Wrap entries behind.

  • **FailurePolicy honoured.** Each plugin declares FailOpen or FailClosed. FailOpen plugins are skipped on error (warning to stderr); FailClosed plugins abort the whole bootstrap. The framework also enforces the Restricts↔FailClosed consistency contract (a Restricts=true plugin with FailOpen would be a silent security hole and is rejected during install).

The host returns:

  • a *hook.Registry ready to install on the command tree
  • a []cmdpolicy.PluginRule for the pruning resolver
  • an error when a FailClosed plugin failed

Index

Constants

View Source
const (
	ReasonInvalidPluginName   = "invalid_plugin_name"
	ReasonPluginNamePanic     = "plugin_name_panic"
	ReasonInvalidHookName     = "invalid_hook_name"
	ReasonDuplicateHookName   = "duplicate_hook_name"
	ReasonInvalidHookRegister = "invalid_hook_registration"
	ReasonInvalidRule         = "invalid_rule"
	ReasonDoubleRestrict      = "double_restrict"
	ReasonRestrictsMismatch   = "restricts_mismatch"
	ReasonCapabilityUnmet     = "capability_unmet"
	ReasonCapabilitiesPanic   = "capabilities_panic"
	// ReasonInvalidCapability flags a plugin authoring error in
	// Capabilities() output -- e.g. a syntactically malformed
	// RequiredCLIVersion string. This is distinct from
	// ReasonCapabilityUnmet (legitimate version mismatch): an authoring
	// bug must NOT be hidden by FailurePolicy=FailOpen, so this code is
	// classified as untrusted-config and aborts unconditionally.
	ReasonInvalidCapability   = "invalid_capability"
	ReasonInstallFailed       = "install_failed"
	ReasonInstallPanic        = "install_panic"
	ReasonDuplicatePluginName = "duplicate_plugin_name"
	ReasonMultipleRestricts   = "multiple_restrict_plugins"
)

ReasonCodes for PluginInstallError. The closed enum is referenced by the design doc's hard-constraint #15 (reason_code enum closure) and drives the JSON envelope's error.detail.reason_code field.

Variables

This section is empty.

Functions

func SetActiveInventory

func SetActiveInventory(inv *Inventory)

SetActiveInventory records the inventory built at bootstrap. Called once from cmd/policy.go after install + wireHooks complete.

A deep copy is taken so the snapshot is immune to later mutations of the input by the caller (or by any other goroutine reading the same PluginEntry slice). Without deep-copy, the shallow `cp := *inv` previously still aliased Plugins / observer / wrapper / lifecycle slices and the embedded RuleView's slice fields.

func SetCurrentCLIVersionForTesting

func SetCurrentCLIVersionForTesting(v string) func()

SetCurrentCLIVersionForTesting overrides the version reported to the RequiredCLIVersion check. Returns a restore function tests must defer.

Types

type CapabilitiesView

type CapabilitiesView struct {
	Restricts          bool   `json:"restricts"`
	FailurePolicy      string `json:"failure_policy"`
	RequiredCLIVersion string `json:"required_cli_version,omitempty"`
}

CapabilitiesView mirrors platform.Capabilities for display. We keep a separate struct so the JSON shape stays under our control and does not drift with extension/platform.

func NewCapabilitiesView

func NewCapabilitiesView(c platform.Capabilities) CapabilitiesView

NewCapabilitiesView converts a platform.Capabilities value into the display struct.

type HookEntry

type HookEntry struct {
	Name  string `json:"name"`
	When  string `json:"when,omitempty"`  // observers only
	Event string `json:"event,omitempty"` // lifecycle only
}

HookEntry is the displayable form of one registered hook.

type InstallResult

type InstallResult struct {
	Registry    *hook.Registry
	PluginRules []cmdpolicy.PluginRule
	Plugins     []PluginInfo
}

InstallResult is the output of InstallAll. Registry is ready for hook.Install; PluginRules feeds into cmdpolicy.Resolve as the "plugin contribution" half of the resolver input. Plugins lists every plugin that committed successfully (FailOpen-skipped plugins are absent), for downstream diagnostics.

func InstallAll

func InstallAll(plugins []platform.Plugin, errOut io.Writer) (*InstallResult, error)

InstallAll runs every registered plugin through the staging Registrar, validates, and commits the survivors. FailOpen plugins that fail are skipped with a warning; the first FailClosed failure stops the loop and returns the error.

Plugins are processed in registration order so the result is deterministic.

errOut receives warnings about FailOpen plugin skips. nil errOut means warnings are dropped (useful in tests).

type Inventory

type Inventory struct {
	Plugins []PluginEntry
}

Inventory is the full snapshot.

func BuildInventory

func BuildInventory(plugins []PluginInventorySource, registry *hook.Registry, rules []RuleInventorySource) *Inventory

BuildInventory assembles an Inventory from the parts produced by InstallAll: the plugin metadata list, the hook registry (may be nil when no hooks were registered), and the plugin rules.

Hooks are attributed to plugins by the namespaced name convention: each entry's Name starts with "<plugin>.", and we group by the leading segment up to the first dot.

func GetActiveInventory

func GetActiveInventory() *Inventory

GetActiveInventory returns a deep copy of the inventory, or nil if bootstrap has not finished. Same reasoning as SetActiveInventory: returning a shallow copy would let callers reach into the stored global through any of the embedded slices.

type PluginEntry

type PluginEntry struct {
	Name         string
	Version      string
	Capabilities CapabilitiesView

	// Rule is non-nil only when the plugin called r.Restrict.
	Rule *RuleView

	Observers  []HookEntry
	Wrappers   []HookEntry
	Lifecycles []HookEntry
}

PluginEntry collects everything one plugin contributed.

type PluginInfo

type PluginInfo struct {
	Name         string
	Version      string
	Capabilities platform.Capabilities
}

PluginInfo is the metadata of a successfully-installed plugin, captured at install time so diagnostic commands (config plugins show) can enumerate plugins without re-calling potentially panic-prone plugin methods at display time.

type PluginInstallError

type PluginInstallError struct {
	PluginName string
	ReasonCode string
	Reason     string
	Cause      error
}

PluginInstallError is the typed install-time failure. ReasonCode comes from the closed enum in the design doc (section 5.3 reason_code table). Cause carries the underlying error, if any, so consumers can errors.As to inspect it.

func (*PluginInstallError) Error

func (e *PluginInstallError) Error() string

func (*PluginInstallError) Unwrap

func (e *PluginInstallError) Unwrap() error

type PluginInventorySource

type PluginInventorySource struct {
	Name         string
	Version      string
	Capabilities platform.Capabilities
}

PluginInventorySource is the minimum slice of PluginInfo BuildInventory needs.

type RuleInventorySource

type RuleInventorySource struct {
	PluginName       string
	Allow            []string
	Deny             []string
	MaxRisk          string
	Identities       []string
	RuleName         string
	Desc             string
	AllowUnannotated bool
}

RuleInventorySource is the minimum slice of cmdpolicy.PluginRule BuildInventory needs. Kept as plain strings to avoid an import cycle with cmdpolicy (the caller converts platform.Risk / Identity to string at the boundary).

type RuleView

type RuleView struct {
	Name             string   `json:"name"`
	Description      string   `json:"description,omitempty"`
	Allow            []string `json:"allow"`
	Deny             []string `json:"deny"`
	MaxRisk          string   `json:"max_risk"`
	Identities       []string `json:"identities"`
	AllowUnannotated bool     `json:"allow_unannotated"`
}

RuleView is the displayable form of a Plugin.Restrict contribution.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL