# Plugin Framework Architecture > Technical architecture for the universal plugin lifecycle, sandboxing, and registry framework. ## Overview The Plugin Framework provides the core extensibility infrastructure for the Stella Ops platform. It defines how plugins are discovered, loaded, initialized, monitored, and shut down. A three-tier trust model ensures that untrusted plugins cannot compromise the host process, while built-in plugins benefit from zero-overhead in-process execution. The framework is consumed as a library by other modules; it does not expose HTTP endpoints. ## Design Principles 1. **Security by default** - Untrusted plugins are process-isolated; capabilities are explicitly declared and enforced 2. **Lifecycle consistency** - All plugins follow the same state machine regardless of trust level 3. **Zero-overhead for built-ins** - BuiltIn plugins run in-process with direct method calls; no serialization or IPC cost 4. **Testability** - Every component has an in-memory or mock alternative for deterministic testing ## Components ``` Plugin/ ├── StellaOps.Plugin.Abstractions/ # Core interfaces (IPlugin, PluginInfo, PluginCapabilities) ├── StellaOps.Plugin.Host/ # Plugin host, lifecycle manager, trust enforcement ├── StellaOps.Plugin.Registry/ # Plugin catalog (InMemory + PostgreSQL backends) ├── StellaOps.Plugin.Sandbox/ # Process isolation and gRPC IPC for untrusted plugins ├── StellaOps.Plugin.Sdk/ # SDK for plugin authors (base classes, helpers) ├── StellaOps.Plugin.Testing/ # Test utilities (mock host, fake registry) ├── Samples/ │ └── HelloWorld/ # Sample plugin demonstrating the SDK └── __Tests/ └── StellaOps.Plugin.Tests/ # Unit and integration tests ``` ## Core Interfaces ### IPlugin ```csharp public interface IPlugin { PluginInfo Info { get; } PluginCapabilities Capabilities { get; } Task InitializeAsync(IPluginContext context, CancellationToken ct); Task StartAsync(CancellationToken ct); Task StopAsync(CancellationToken ct); } ``` ### PluginInfo ```csharp public sealed record PluginInfo { public required string Id { get; init; } public required string Name { get; init; } public required Version Version { get; init; } public required PluginTrustLevel TrustLevel { get; init; } public string? Description { get; init; } public string? Author { get; init; } } ``` ### PluginCapabilities Declares what the plugin can do (e.g., `CanScan`, `CanEvaluatePolicy`, `CanConnect`). The host checks capabilities before routing work to a plugin. ## Plugin Lifecycle ``` [Discovery] --> [Loading] --> [Initialization] --> [Active] --> [Shutdown] │ │ │ │ │ │ └── failure ──> [Failed] │ │ └── failure ──> [Failed] │ └── not found ──> (skip) ``` | State | Description | |-------|-------------| | **Discovery** | Host scans configured paths for assemblies or packages containing `IPlugin` implementations | | **Loading** | Assembly or process is loaded; plugin metadata is read and validated | | **Initialization** | `InitializeAsync` is called with an `IPluginContext` providing configuration and service access | | **Active** | Plugin is ready to receive work; `StartAsync` has completed | | **Shutdown** | `StopAsync` is called during graceful host shutdown or plugin unload | | **Failed** | Plugin encountered an unrecoverable error during loading or initialization; logged and excluded | ## Trust Levels | Level | Execution Model | IPC | Use Case | |-------|----------------|-----|----------| | **BuiltIn** | In-process, direct method calls | None | First-party plugins shipped with the platform | | **Trusted** | In-process with monitoring | None | Vetted third-party plugins with signed manifests | | **Untrusted** | Separate process via `ProcessSandbox` | gRPC | Community or unverified plugins | ### ProcessSandbox (Untrusted Plugins) Untrusted plugins run in a child process managed by `ProcessSandbox`: 1. **Process creation:** The sandbox spawns a new process with restricted permissions 2. **gRPC channel:** A bidirectional gRPC channel is established for host-plugin communication 3. **Capability enforcement:** The host proxy only forwards calls matching declared capabilities 4. **Resource limits:** CPU and memory limits are enforced at the process level 5. **Crash isolation:** If the plugin process crashes, the host logs the failure and marks the plugin as Failed; the host process is unaffected ## Database Schema Database: PostgreSQL (via `PostgresPluginRegistry`) | Table | Purpose | |-------|---------| | `plugins` | Registered plugins (id, name, trust_level, status, config_json, registered_at) | | `plugin_versions` | Version history per plugin (plugin_id, version, assembly_hash, published_at) | | `plugin_capabilities` | Declared capabilities per plugin version (plugin_version_id, capability, parameters) | The `InMemoryPluginRegistry` provides an equivalent in-memory implementation for testing and offline scenarios. ## Data Flow ``` [Module Host] ── discover ──> [Plugin.Host] │ load plugins │ ┌───────────────┼───────────────┐ │ │ │ [BuiltIn] [Trusted] [Untrusted] (in-process) (in-process) (ProcessSandbox) │ │ │ └───────────────┼───────────────┘ │ [Plugin.Registry] ── persist ──> [PostgreSQL] ``` ## Security Considerations - **Trust level enforcement:** The host never executes untrusted plugin code in-process; all untrusted execution is delegated to the sandbox - **Capability restrictions:** Plugins can only perform actions matching their declared capabilities; the host rejects unauthorized calls - **Assembly hash verification:** Plugin assemblies are hashed at registration; the host verifies the hash at load time to detect tampering - **No network access for untrusted plugins:** The sandbox process has restricted network permissions; plugins that need network access must be at least Trusted - **Audit trail:** Plugin lifecycle events (registration, activation, failure, shutdown) are logged with timestamps and actor identity ## Observability - **Metrics:** `plugin_active_count{trust_level}`, `plugin_load_duration_ms`, `plugin_failures_total{plugin_id}`, `sandbox_process_restarts_total` - **Logs:** Structured logs with `pluginId`, `trustLevel`, `lifecycleState`, `capability` - **Health:** The registry exposes plugin health status; modules can query whether a required plugin is active ## Performance Characteristics - BuiltIn plugins: zero overhead (direct method dispatch) - Trusted plugins: negligible overhead (monitoring wrapper) - Untrusted plugins: gRPC serialization cost per call (~1-5ms depending on payload size) - Plugin discovery: runs at host startup; cached until restart or explicit re-scan ## References - [Module README](./README.md) - [Integrations Architecture](../integrations/architecture.md) - Primary consumer - [Scanner Architecture](../scanner/architecture.md) - Plugin-based analysis