- Introduced AGENTS.md, README.md, TASKS.md, and implementation_plan.md for Vexer, detailing mission, responsibilities, key components, and operational notes. - Established similar documentation structure for Vulnerability Explorer and Zastava modules, including their respective workflows, integrations, and observability notes. - Created risk scoring profiles documentation outlining the core workflow, factor model, governance, and deliverables. - Ensured all modules adhere to the Aggregation-Only Contract and maintain determinism and provenance in outputs.
		
			
				
	
	
	
		
			7.1 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	Excititor Connector Packaging Guide
Audience: teams implementing new Excititor provider plug‑ins (CSAF feeds, OpenVEX attestations, etc.)
Prerequisites: readdocs/modules/excititor/architecture.mdand the moduleAGENTS.mdinsrc/Excititor/__Libraries/StellaOps.Excititor.Connectors.Abstractions/.
The Excititor 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 Excititor Worker/WebService can load it via the plugin host.
1. Project layout
Start from the template under
docs/dev/templates/excititor-connector/. It contains:
Excititor.MyConnector/
├── src/
│   ├── Excititor.MyConnector.csproj
│   ├── MyConnectorOptions.cs
│   ├── MyConnector.cs
│   └── MyConnectorPlugin.cs
└── manifest/
    └── connector.manifest.yaml
Key points:
- Target net10.0, enableTreatWarningsAsErrors, reference theStellaOps.Excititor.Connectors.Abstractionsproject (or NuGet once published).
- Keep project ID prefix StellaOps.Excititor.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.Excititor.Connectors.Abstractions\StellaOps.Excititor.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 to- context.RawSink.
- NormalizeAsync– convert raw documents into- VexClaimBatchvia 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("excititor: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 Excititor Worker currently instantiates connectors through the shared
IConnectorPlugincontract. Once a dedicated Excititor 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: excititor-my-provider
assembly: StellaOps.Excititor.Connectors.MyProvider.dll
entryPoint: StellaOps.Excititor.Connectors.MyProvider.MyConnectorPlugin
description: >
  Official VEX feed for ExampleCorp products (CSAF JSON, daily updates).
tags:
  - excititor
  - csaf
  - vendor
Store manifests under /opt/stella/excititor/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/excititor/plugins/<Provider>/.
- Place connector.manifest.yamlnext to the binaries.
- Restart the Excititor 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.Excititor.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/excititor-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