Initial commit

This commit is contained in:
2025-08-30 21:05:34 +00:00
commit b04557a923
40 changed files with 5469 additions and 0 deletions

146
docs/dev/30_PLUGIN_DEV_GUIDE.md Executable file
View File

@@ -0,0 +1,146 @@
# Writing Plugins forStellaOps SDK *Preview3*
> **SDK status:** *Preview3* is compatible with the **v0.1α** runtime.
> Interfaces freeze at **v0.2 β**; binarybreaking changes are still possible
> until then.
| SDK NuGet | Runtime compat | Notes |
|-----------|---------------|-------|
| `StellaOps.SDK 0.2.0-preview3` | `stella-ops >= 0.1.0-alpha` | Current preview |
| `StellaOps.SDK 0.2.xbeta` | v0.2 β (Q12026) | Interface **freeze** |
| `StellaOps.SDK 1.0.0` | v1.0GA (Q42026) | Semantic Ver from here |
---
## 0·Extension points
| Area | Interface / format | Example |
|------|--------------------|---------|
| SBOM mutator | `ISbomMutator` | Inject SPDX licences |
| Additional scanner | `IVulnerabilityProvider` | Rust Crates ecosystem |
| Policy engine | **OPA Rego** file | Custom pass/fail rule |
| Result exporter | `IResultSink` | Slack webhook notifier |
*Hotplugging (live reload) is **post1.0**; modules are discovered once
during service startup.*
---
## 1·Fiveminute quickstart (C# /.NET {{ dotnet }})
```bash
dotnet new classlib -n SlackExporter
cd SlackExporter
dotnet add package StellaOps.SDK --version 0.2.0-preview3
````
```csharp
using System.Net.Http.Json;
using StellaOps.Plugin;
public sealed class SlackSink : IResultSink
{
private readonly string _webhook =
Environment.GetEnvironmentVariable("SLACK_WEBHOOK")
?? throw new InvalidOperationException("Missing SLACK_WEBHOOK");
public string Name => "Slack Notifier";
public async Task ExportAsync(ScanResult result, CancellationToken ct)
{
var payload = new
{
text = $":rotating_light: *{result.Image}* " +
$"→ {result.Findings.Count} findings (max {result.MaxSeverity})"
};
using var client = new HttpClient();
await client.PostAsJsonAsync(_webhook, payload, ct);
}
}
```
```bash
dotnet publish -c Release -o out
sudo mkdir -p /opt/stella/plugins/Slack
sudo cp out/SlackExporter.dll /opt/stella/plugins/Slack/
sudo systemctl restart stella-ops
```
Startup log:
```
[PluginLoader] Loaded 1 plugin:
• Slack Notifier
```
---
## 2·Packaging rules
| Item | Rule |
| ------ | ----------------------------------------- |
| Folder | `/opt/stella/plugins/<NiceName>/` |
| DLLs | Your plugin + nonGAC deps |
| Config | Envvars or `settings.yaml` |
| SBOM | Optional `addon.spdx.json` for provenance |
---
## 3·Security sandbox
* Runs as Linux user **`stellaplugin` (UID1001)**.
* SELinux/AppArmor profile blocks inbound traffic; outbound :80/443 only.
* cgroup default: **1 CPU /256MiB** (adjustable).
* SHA256 of every DLL is embedded in the run report.
---
## 4·Debugging
| Technique | Command |
| ----------------- | ---------------------------------- |
| Verbose core log | `STELLA_LOG=debug` |
| Perplugin log | Inject `ILogger<YourClass>` |
| Dryrun (no fail) | `--plugin-mode warn` |
| Hot reload | *Not supported* (planned post1.0) |
Logs: `/var/log/stella-ops/plugins/YYYYMMDD.log`.
---
## 5·Interface reference (Preview3)
```csharp
namespace StellaOps.Plugin
{
public interface ISbomMutator
{
string Name { get; }
Task<SoftwareBillOfMaterials> MutateAsync(
SoftwareBillOfMaterials sbom,
CancellationToken ct = default);
}
public interface IVulnerabilityProvider
{
string Ecosystem { get; }
Task<IReadOnlyList<Vulnerability>> QueryAsync(
PackageReference p, CancellationToken ct = default);
}
public interface IResultSink
{
string Name { get; }
Task ExportAsync(
ScanResult result, CancellationToken ct = default);
}
}
```
Full POCO docs: [https://git.stella-ops.org/stella-ops/sdk/-/tree/main/docs/api](https://git.stella-ops.org/stella-ops/sdk/-/tree/main/docs/api).
---
*Last updated {{ "now" | date: "%Y%m%d" }} constants autoinjected.*