Files
git.stella-ops.org/docs/10_PLUGIN_SDK_GUIDE.md
2025-12-24 12:38:14 +02:00

125 lines
5.1 KiB
Markdown
Executable File

# Plugin SDK Guide
This guide explains how StellaOps loads, validates, and wires restart-time plugins. It is intentionally cross-cutting: module-specific plugin contracts (Authority identity providers, Concelier connectors, Scanner analyzers, CLI command modules, etc.) live in the corresponding module dossiers under `docs/modules/`.
## 1) What a "plugin" means in StellaOps
StellaOps uses plugins to extend behavior without losing:
- Determinism (stable ordering, stable identifiers, replayable outputs).
- Offline posture (no hidden outbound calls; explicit trust roots and caches).
- Security boundaries (no client-controlled identity injection; signed artifacts where enforced).
Most services load plugins at process start (restart-time). Hot-reload is not a goal: restart-time loading keeps memory and dependency isolation predictable.
## 2) Service plugin loading model (restart-time)
Service plugins are loaded by the `StellaOps.Plugin` library:
- Discovery occurs in a configured plugin directory.
- Assemblies are loaded in an isolated `AssemblyLoadContext`.
- A compatibility gate runs before DI registration:
- version attribute presence and host compatibility
- optional signature verification
### 2.1 Plugin directory and discovery patterns
Default behavior (from `StellaOps.Plugin.Hosting.PluginHostOptions`):
- Base directory: `AppContext.BaseDirectory` (unless overridden).
- Plugin directory:
- `<PrimaryPrefix>.PluginBinaries` when `PrimaryPrefix` is set, otherwise `PluginBinaries`.
- Discovery glob(s):
- `<prefix>.Plugin.*.dll` for each configured prefix.
Hosts may override the directory and/or add explicit `searchPatterns` in their config. Use module operations docs to see the authoritative configuration for a given service.
### 2.2 Deterministic ordering
The loader is deterministic:
- When no explicit order is configured, discovered plugin assemblies are sorted by filename (case-insensitive).
- When an explicit order is configured, that order is applied first and the remainder stays sorted.
## 3) Version compatibility requirements
Plugins should declare the assembly-level attribute:
```csharp
using StellaOps.Plugin.Versioning;
[assembly: StellaPluginVersion("1.2.3", MinimumHostVersion = "1.0.0")]
```
The host can enforce:
- Required attribute presence (`RequireVersionAttribute`).
- Compatibility bounds (`MinimumHostVersion` / `MaximumHostVersion`).
- Strict major compatibility when `MaximumHostVersion` is not set (`StrictMajorVersionCheck`).
## 4) Dependency injection wiring
StellaOps supports two DI registration mechanisms.
### 4.1 Simple bindings via `ServiceBindingAttribute`
Annotate implementations with `ServiceBindingAttribute`:
```csharp
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
[ServiceBinding(typeof(IMyContract), ServiceLifetime.Singleton, RegisterAsSelf = true)]
public sealed class MyPluginService : IMyContract
{
}
```
### 4.2 Advanced wiring via `IDependencyInjectionRoutine`
For full control, include a concrete `IDependencyInjectionRoutine` implementation. The host discovers and runs all routines in loaded plugin assemblies:
```csharp
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using StellaOps.DependencyInjection;
public sealed class MyPluginDi : IDependencyInjectionRoutine
{
public IServiceCollection Register(IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<IMyContract, MyPluginService>();
return services;
}
}
```
## 5) Signing and verification (Cosign)
When enabled, the host can verify plugin assemblies using Cosign (`cosign verify-blob`). The signature file is expected adjacent to the assembly:
- `MyPlugin.dll`
- `MyPlugin.dll.sig`
Verification is performed by `StellaOps.Plugin.Security.CosignPluginVerifier` and controlled by host configuration (for example `EnforceSignatureVerification` plus verifier options).
Offline note: verification can be performed without transparency log access when the host is configured accordingly (for example by ignoring tlog or using an offline receipt flow).
## 6) Repo layout (this monorepo)
In this repository, plugin binaries are typically staged under module-specific `*.PluginBinaries` directories (examples):
- `src/StellaOps.Authority.PluginBinaries/`
- `src/Concelier/StellaOps.Concelier.PluginBinaries/`
The authoritative loader configuration is owned by the host module and documented in its operations/architecture docs.
## 7) Testing expectations
Plugins should ship tests that protect determinism and compatibility:
- Stable ordering of outputs and collections.
- Stable timestamps (UTC ISO-8601).
- Fixture-backed inputs for offline operation.
- Compatibility checks for host version boundaries.
Reference tests for the generic plugin host live under:
- `src/__Libraries/__Tests/StellaOps.Plugin.Tests/`
## 8) Where to go next
- Authority plugins and operations: `docs/modules/authority/`
- Concelier connectors and operations: `docs/modules/concelier/`
- Scanner analyzers and operations: `docs/modules/scanner/`
- CLI command modules: `docs/modules/cli/`