Files
git.stella-ops.org/docs/product-advisories/28-Nov-2025 - Plugin Architecture & Extensibility Patterns.md
StellaOps Bot b34f13dc03 up
2025-11-29 02:19:50 +02:00

11 KiB

Plugin Architecture & Extensibility Patterns

Version: 1.0 Date: 2025-11-28 Status: Canonical

This advisory consolidates the extensibility patterns used across Stella Ops modules, providing a unified view for architects and developers implementing custom integrations.


1. Overview

Stella Ops uses a plugin-based architecture enabling customers and partners to extend functionality without modifying core code. The platform supports three primary extension types:

Type Module Purpose Examples
Connectors Concelier, Excititor Ingest/export data from external sources NVD, OSV, vendor VEX feeds
Plugins Authority, Scanner Extend runtime behavior LDAP auth, custom analyzers
Analyzers Scanner Add detection capabilities Language-specific, binary analysis

2. Core Principles

2.1 Determinism

All plugins must produce deterministic outputs for identical inputs:

  • No global state between invocations
  • Timestamps in UTC ISO-8601
  • Stable ordering of collections
  • Reproducible hashing with documented algorithms

2.2 Offline-First

Plugins must function in air-gapped environments:

  • No network access unless explicitly configured
  • Local configuration and secrets
  • Bundled dependencies (no runtime downloads)
  • Offline-capable credential stores

2.3 Restart-Safe

Plugins load at service startup only:

  • No hot-reload (security/determinism trade-off)
  • Configuration changes require restart
  • State persists in external stores (MongoDB, filesystem)

3. Plugin Lifecycle

┌─────────────────────────────────────────────────────────────────┐
│                        Host Startup                             │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────┐
│  1. Configuration Load                                          │
│     - Read YAML manifests from etc/<module>.plugins/            │
│     - Validate capability tokens                                │
│     - Resolve relative paths                                    │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────┐
│  2. Assembly Discovery                                          │
│     - Scan plugin binaries directory                            │
│     - Match assemblies to manifest descriptors                  │
│     - Load assemblies into isolated context                     │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────┐
│  3. Registrar Execution                                         │
│     - Find IPluginRegistrar implementations                     │
│     - Bind options from configuration                           │
│     - Register services in DI container                         │
│     - Queue bootstrap tasks (optional)                          │
└─────────────────────────────────┬───────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────┐
│  4. Runtime                                                     │
│     - Host resolves plugin services via DI                      │
│     - Capability metadata guides feature exposure               │
│     - Health checks report plugin status                        │
└─────────────────────────────────────────────────────────────────┘

4. Concelier Connectors

4.1 Purpose

Connectors ingest vulnerability advisories from external sources into the Concelier merge engine.

4.2 Interface

public interface IAdvisoryConnector
{
    string ConnectorId { get; }
    Task<IAsyncEnumerable<RawAdvisory>> FetchAsync(
        ConnectorContext context,
        CancellationToken ct);
    Task<ConnectorHealth> CheckHealthAsync(CancellationToken ct);
}

4.3 Built-in Connectors

Connector Source Format
nvd NVD API 2.0 CVE JSON
osv OSV.dev OSV JSON
ghsa GitHub Advisory Database GHSA JSON
oval Vendor OVAL feeds OVAL XML
csaf CSAF repositories CSAF JSON

4.4 Developer Guide

See: docs/dev/30_EXCITITOR_CONNECTOR_GUIDE.md


5. Authority Plugins

5.1 Purpose

Authority plugins extend authentication with custom identity providers, credential stores, and client management.

5.2 Interface

public interface IAuthorityPluginRegistrar
{
    void ConfigureServices(IServiceCollection services, PluginContext context);
    void ConfigureOptions(IConfiguration config);
}

public interface IIdentityProviderPlugin
{
    string ProviderId { get; }
    AuthorityIdentityProviderCapabilities Capabilities { get; }
    Task<AuthenticationResult> AuthenticateAsync(AuthenticationRequest request);
}

5.3 Capabilities

Plugins declare capabilities via manifest:

plugins:
  descriptors:
    ldap:
      assemblyName: "StellaOps.Authority.Plugin.Ldap"
      capabilities:
        - password
        - mfa
        - clientProvisioning
Capability Description
password Username/password authentication
mfa Multi-factor authentication support
clientProvisioning Dynamic OAuth client registration
bootstrap Initial admin user creation

5.4 Developer Guide

See: docs/dev/31_AUTHORITY_PLUGIN_DEVELOPER_GUIDE.md


6. Scanner Analyzers

6.1 Purpose

Analyzers extend the Scanner with language-specific or binary-level detection capabilities.

6.2 Interface

public interface IScanAnalyzer
{
    string AnalyzerId { get; }
    IReadOnlyList<string> SupportedEcosystems { get; }
    Task<AnalysisResult> AnalyzeAsync(
        ScanContext context,
        IAsyncEnumerable<ScanArtifact> artifacts,
        CancellationToken ct);
}

6.3 Built-in Analyzers

Analyzer Ecosystem Detection Method
syft Multi-ecosystem SBOM generation
grype-db Multi-ecosystem Vulnerability matching
elf-symbols Binary/ELF Symbol table analysis
buildid Binary/ELF Build-ID extraction
dotnet-deps .NET deps.json parsing

6.4 Surface Validation

The Scanner supports extensible surface validation for detecting risky patterns:

public interface ISurfaceValidator
{
    string ValidatorId { get; }
    Task<SurfaceValidationResult> ValidateAsync(
        SurfaceContext context,
        CancellationToken ct);
}

See: docs/modules/scanner/guides/surface-validation-extensibility.md


7. Manifest Structure

All plugins use a standard manifest format:

{
  "pluginId": "example-plugin",
  "version": "1.0.0",
  "assemblyName": "StellaOps.Module.Plugin.Example",
  "hostVersion": ">=2.0.0",
  "capabilities": ["capability1", "capability2"],
  "configuration": {
    "requiredSettings": ["setting1"],
    "optionalSettings": ["setting2"]
  },
  "dependencies": {
    "packages": ["Dependency.Package@1.0.0"]
  }
}

8. Security Considerations

8.1 Assembly Isolation

  • Plugins load in dedicated assembly contexts
  • Host enforces capability-based access control
  • Network access requires explicit configuration

8.2 Configuration Validation

  • Unknown capability tokens rejected at startup
  • Path traversal in relative paths blocked
  • Secrets never logged or exposed in diagnostics

8.3 Audit Trail

  • Plugin loading events logged with assembly hash
  • Configuration changes recorded
  • Runtime errors captured with context

9. Offline Kit Integration

Plugins must support offline distribution:

offline-kit/
├── plugins/
│   ├── authority/
│   │   ├── StellaOps.Authority.Plugin.Ldap.dll
│   │   └── manifest.json
│   ├── scanner/
│   │   ├── StellaOps.Scanner.Analyzer.Custom.dll
│   │   └── manifest.json
│   └── checksums.sha256
├── config/
│   └── plugins.yaml
└── MANIFEST.json

9.1 Checksum Verification

All plugin assemblies verified against checksums.sha256 before loading.

9.2 Version Compatibility

Host rejects plugins with incompatible hostVersion requirements.


10. Testing Requirements

10.1 Unit Tests

  • Registrar binds options correctly
  • Services resolve from DI container
  • Capability metadata accurate

10.2 Integration Tests

  • Plugin loads in host process
  • Health checks pass
  • Functionality works end-to-end

10.3 Test Helpers

// Use StellaOps.Plugin.Tests helpers
var host = new PluginTestHost()
    .WithPlugin<MyPlugin>()
    .WithConfiguration(config)
    .Build();

var plugin = host.GetRequiredService<IMyPlugin>();
var result = await plugin.DoSomethingAsync();

Resource Location
General plugin guide docs/dev/plugins/README.md
Concelier connector guide docs/dev/30_EXCITITOR_CONNECTOR_GUIDE.md
Authority plugin guide docs/dev/31_AUTHORITY_PLUGIN_DEVELOPER_GUIDE.md
Scanner extensibility docs/modules/scanner/guides/surface-validation-extensibility.md
Platform architecture docs/modules/platform/architecture-overview.md

12. Sprint Mapping

No dedicated sprint - plugin infrastructure is foundational. Related tasks appear in:

  • Module-specific sprints (Authority, Scanner, Concelier)
  • Platform infrastructure sprints

13. Success Metrics

Metric Target
Plugin load time < 500ms per plugin
Configuration validation 100% coverage of manifest schema
Offline kit verification All plugins checksum-verified
Documentation coverage All plugin types documented

Last updated: 2025-11-28