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 ¶
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 ¶
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 ¶
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.