7.2 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	Vexer Connector Packaging Guide
Audience: teams implementing new Vexer provider plug‑ins (CSAF feeds, OpenVEX attestations, etc.)
Prerequisites: readdocs/modules/vexer/architecture.mdand the moduleAGENTS.mdinsrc/Excititor/__Libraries/StellaOps.Excititor.Connectors.Abstractions/.
The Vexer connector SDK gives you:
VexConnectorBase– deterministic logging, SHA‑256 helpers, time provider.VexConnectorOptionsBinder– strongly typed YAML/JSON configuration binding.IVexConnectorOptionsValidator<T>– custom validation hooks (offline defaults, auth invariants).VexConnectorDescriptor& metadata helpers for consistent telemetry.
This guide explains how to package a connector so the Vexer Worker/WebService can load it via the plugin host.
1. Project layout
Start from the template under
docs/dev/templates/vexer-connector/. It contains:
Vexer.MyConnector/
├── src/
│   ├── Vexer.MyConnector.csproj
│   ├── MyConnectorOptions.cs
│   ├── MyConnector.cs
│   └── MyConnectorPlugin.cs
└── manifest/
    └── connector.manifest.yaml
Key points:
- Target 
net10.0, enableTreatWarningsAsErrors, reference theStellaOps.Vexer.Connectors.Abstractionsproject (or NuGet once published). - Keep project ID prefix 
StellaOps.Vexer.Connectors.<Provider>so the plugin loader can discover it with the default search pattern. 
1.1 csproj snippet
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="..\..\..\src\StellaOps.Vexer.Connectors.Abstractions\StellaOps.Vexer.Connectors.Abstractions.csproj" />
  </ItemGroup>
</Project>
Adjust the ProjectReference for your checkout (or switch to a NuGet package
once published).
2. Implement the connector
- Options model – create an options POCO with data-annotation attributes.
Bind it via 
VexConnectorOptionsBinder.Bind<TOptions>in your connector constructor orValidateAsync. - Validator – implement 
IVexConnectorOptionsValidator<TOptions>to add complex checks (e.g., ensure bothclientIdandclientSecretare present). - Connector – inherit from 
VexConnectorBase. Implement:ValidateAsync– run binder/validators, log configuration summary.FetchAsync– stream raw documents tocontext.RawSink.NormalizeAsync– convert raw documents intoVexClaimBatchvia format-specific normalizers (context.Normalizers).
 - Plugin adapter – expose the connector via a plugin entry point so the host can instantiate it.
 
2.1 Options binding example
public sealed class MyConnectorOptions
{
    [Required]
    [Url]
    public string CatalogUri { get; set; } = default!;
    [Required]
    public string ApiKey { get; set; } = default!;
    [Range(1, 64)]
    public int MaxParallelRequests { get; set; } = 4;
}
public sealed class MyConnectorOptionsValidator : IVexConnectorOptionsValidator<MyConnectorOptions>
{
    public void Validate(VexConnectorDescriptor descriptor, MyConnectorOptions options, IList<string> errors)
    {
        if (!options.CatalogUri.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
        {
            errors.Add("CatalogUri must use HTTPS.");
        }
    }
}
Bind inside the connector:
private readonly MyConnectorOptions _options;
public MyConnector(VexConnectorDescriptor descriptor, ILogger<MyConnector> logger, TimeProvider timeProvider)
    : base(descriptor, logger, timeProvider)
{
    // `settings` comes from the orchestrator; validators registered via DI.
    _options = VexConnectorOptionsBinder.Bind<MyConnectorOptions>(
        descriptor,
        VexConnectorSettings.Empty,
        validators: new[] { new MyConnectorOptionsValidator() });
}
Replace VexConnectorSettings.Empty with the actual settings from context
inside ValidateAsync.
3. Plugin adapter & manifest
Create a simple plugin class that implements
StellaOps.Plugin.IConnectorPlugin. The Worker/WebService plugin host uses
this contract today.
public sealed class MyConnectorPlugin : IConnectorPlugin
{
    private static readonly VexConnectorDescriptor Descriptor =
        new("vexer:my-provider", VexProviderKind.Vendor, "My Provider VEX");
    public string Name => Descriptor.DisplayName;
    public bool IsAvailable(IServiceProvider services) => true; // inject feature flags if needed
    public IFeedConnector Create(IServiceProvider services)
    {
        var logger = services.GetRequiredService<ILogger<MyConnector>>();
        var timeProvider = services.GetRequiredService<TimeProvider>();
        return new MyConnector(Descriptor, logger, timeProvider);
    }
}
Note: the Vexer Worker currently instantiates connectors through the shared
IConnectorPlugincontract. Once a dedicated Vexer plugin interface lands you simply swap the base interface; the descriptor/connector code remains unchanged.
Provide a manifest describing the assembly for operational tooling:
# manifest/connector.manifest.yaml
id: vexer-my-provider
assembly: StellaOps.Vexer.Connectors.MyProvider.dll
entryPoint: StellaOps.Vexer.Connectors.MyProvider.MyConnectorPlugin
description: >
  Official VEX feed for ExampleCorp products (CSAF JSON, daily updates).
tags:
  - vexer
  - csaf
  - vendor
Store manifests under /opt/stella/vexer/plugins/<connector>/manifest/ in
production so the deployment tooling can inventory and verify plug‑ins.
4. Packaging workflow
dotnet publish -c Release→ copy the published DLLs to/opt/stella/vexer/plugins/<Provider>/.- Place 
connector.manifest.yamlnext to the binaries. - Restart the Vexer Worker or WebService (hot reload not supported yet).
 - Verify logs: 
VEX-ConnectorLoadershould list the connector descriptor. 
4.1 Offline kits
- Add the connector folder (binaries + manifest) to the Offline Kit bundle.
 - Include a 
settings.sample.yamldemonstrating offline-friendly defaults. - Document any external dependencies (e.g., SHA mirrors) in the manifest 
notesfield. 
5. Testing checklist
- Unit tests around options binding & validators.
 - Integration tests (future 
StellaOps.Vexer.Connectors.Abstractions.Tests) verifying deterministic logging scopes:logger.BeginScopeshould producevex.connector.id,vex.connector.kind, andvex.connector.operation. - Deterministic SHA tests: repeated 
CreateRawDocumentcalls with identical content must return the same digest. 
6. Reference template
See docs/dev/templates/vexer-connector/ for the full quick‑start including:
- Sample options class + validator.
 - Connector implementation inheriting from 
VexConnectorBase. - Plugin adapter + manifest.
 
Copy the directory, rename namespaces/IDs, then iterate on provider-specific logic.
Last updated: 2025-10-17