Follow-up to commit 7efa424fe (EXCITITOR-CFG-01/02/03). Captures the
continuation edits that landed alongside/after the initial commit:
- VexIngestOrchestrator.cs: additional effective-settings resolver
hardening (+63 lines).
- DefaultVexProviderRunner.cs: worker-path settings merge refinement.
- VexIngestOrchestratorTests.cs (new): focused test coverage for the
effective-settings + blocked-readiness path.
- DefaultVexProviderRunnerTests.cs: corresponding worker-path coverage.
- TASKS.md entries updated in both test projects.
Docs reconciliation:
- provider-credentials.md (new): operator credential-entry dossier
mirroring the Concelier source-credentials.md pattern.
- provider-control-plane.md: cross-link updates.
- ops/connector-setup-guide.md: authoritative-inventory pointers updated
to reference the new credential dossiers; microsoft-entra API-permission
steps generalized to "your MSRC onboarding flow" (MSRC Security Updates
API availability varies by tenant).
- SPRINT_20260422_007 execution log appended.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.9 KiB
Connector Setup Guide — Concelier + Excititor
Operator reference for bringing up the Concelier (advisory source) and Excititor (VEX provider) connectors. This guide distinguishes the aspirational catalog (~78 entries exposed through stellaops-cli sources list) from the actually backend-wired connectors that run on ingest today, and lays out credential-creation steps for the few providers that require operator-minted secrets.
Actual state (verified 2026-04-22 against the local dev stack)
Concelier — 9 wired sources, 8 healthy, 787 advisories ingested
| Source | Backend wired? | Health check | Docs in DB | Last updated |
|---|---|---|---|---|
redhat |
YES | healthy | 651 | 2026-04-22 17:16 |
osv |
YES | healthy (498ms) | 59 | 2026-04-22 17:40 |
debian |
YES | healthy | 41 | 2026-04-22 17:07 |
suse |
YES | healthy | 26 | 2026-04-22 17:00 |
alpine |
YES | healthy | 8 | 2026-04-22 17:06 |
ubuntu |
YES | healthy | 2 | 2026-04-22 17:41 |
auscert |
YES | healthy | 0 | never |
vmware |
YES | healthy | 0 | never |
stella-mirror |
YES | unhealthy (404) | 0 | never |
The stella-mirror failure on the dev stack is expected — that source expects a reachable StellaOps infrastructure mirror that's not wired in dev.
Excititor — 4 wired providers, all enabled
| Provider | Kind | Base URIs |
|---|---|---|
excititor:redhat |
distro | (pulls via CSAF feeds) |
excititor:ubuntu |
distro | https://ubuntu.com/security/notices.json |
excititor:cisco |
vendor | https://www.cisco.com/.well-known/csaf/ (public CSAF — no auth) |
excititor:oracle |
vendor | (pulls via public Oracle Critical Patch Updates) |
Note about Cisco: the VEX side uses Cisco's public CSAF feed (unauthenticated). The Concelier advisory side of Cisco (which WOULD require PSIRT openVuln OAuth) is currently in the aspirational catalog but not backend-wired.
Aspirational catalog (~65 entries — NOT yet backend-wired)
stellaops-cli sources list reports 78 entries. The other ~65 (npm, pypi, go, rubygems, maven, crates, packagist, hex, rustsec, pypa, govuln, bundler-audit, exploitdb, metasploit, intel, amd, arm, siemens, kaspersky-ics, cert-ua/pl/in, krcert, fstec-bdu, nkcki, mitre-attack, mitre-d3fend, nuget, poc-github, and more) are present in the static catalog but have no source_type → connector mapping in the backend. Calling stellaops-cli sources enable <id> on these returns [OK] but does NOT persist the source — the call is a no-op because there's no runtime implementation to register against.
Tracked in:
docs/implplan/SPRINT_20260422_004_Concelier_full_connector_control_plane.md(archived — covered Excititor backend; Concelier-catalog mapping remains)docs/implplan/SPRINT_20260422_007_Concelier_excititor_persisted_provider_credentials.md(open — persisted per-provider configuration)
Credential requirements
Authoritative current-state inventories live here:
docs/modules/concelier/connectors.mddocs/modules/concelier/operations/source-credentials.mddocs/modules/excititor/operations/provider-control-plane.mddocs/modules/excititor/operations/provider-credentials.md
Current UI/CLI-configurable credentialed paths:
- Concelier advisory sources:
ghsa,cisco,microsoft - Concelier endpoint-override paths:
oracle,adobe,chromium - Excititor VEX providers:
excititor:cisco,excititor:suse-rancher,excititor:msrc
The sections below keep the acquisition steps for the most common credentialed providers.
GitHub Security Advisories (GHSA)
What Stella Ops needs: a GitHub Personal Access Token (classic).
Steps:
- https://github.com/settings/tokens → Generate new token (classic).
- Name:
stella-ops-concelier-ghsa. Expiration: 90 days minimum. - Scopes:
read:packages+public_repo(or the fine-grainedread:public_repoequivalent). - If your GitHub org enforces SAML SSO: Configure SSO next to the token → authorize per org.
Cisco PSIRT openVuln (Concelier advisory only; VEX uses public CSAF)
What Stella Ops needs: a Cisco PSIRT OAuth 2.0 client (grant_type=client_credentials).
Steps:
- https://apiconsole.cisco.com/apps/myapps → Register a New App.
- Name:
stella-ops-concelier-psirt. Tick Client Credentials grant. Grant openVuln API. - Copy
client_id+client_secretfrom the app detail page.
Cisco ref: https://developer.cisco.com/docs/psirt/authentication/.
Microsoft MSRC (Concelier advisory + Excititor VEX)
What Stella Ops needs: a Microsoft Entra confidential client app with the consent and scope required by your MSRC onboarding flow.
Steps:
- https://entra.microsoft.com/ → App registrations → New registration.
- Name:
stella-ops-concelier-msrc. Single-tenant. Redirect URI blank. - From Overview: copy Directory (tenant) ID + Application (client) ID.
- Certificates & secrets → New client secret → 24-month expiry → copy the
Valuecolumn immediately. - Grant the application permissions and consent required by your MSRC onboarding process before storing the values in Stella Ops.
Microsoft refs: https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app, https://learn.microsoft.com/en-us/entra/identity-platform/how-to-add-credentials.
Day-to-day operator commands
# Using the CLI (src/Cli/StellaOps.Cli/bin/Debug/net10.0/StellaOps.Cli.dll):
dotnet StellaOps.Cli.dll sources list --json # catalog view
dotnet StellaOps.Cli.dll sources status # runtime readiness
dotnet StellaOps.Cli.dll sources check <id> # connectivity probe
dotnet StellaOps.Cli.dll sources enable <id> [<id>...] # enable (no-op for unwired)
dotnet StellaOps.Cli.dll sources disable <id>
dotnet StellaOps.Cli.dll db fetch --source <id> --stage fetch # trigger ingest
Environment:
STELLAOPS_BACKEND_URL=https://stella-ops.local(required fordb fetch)- Self-signed cert: resolve by either trusting the dev cert system-wide or running the CLI from a container already in the compose network (the CLI currently has no
--insecureflag).
Verify persisted state directly:
SELECT key, source_type, enabled FROM vuln.sources ORDER BY key;
SELECT s.key, COUNT(d.*) AS docs, MAX(d.updated_at) AS last_update
FROM vuln.sources s LEFT JOIN concelier.source_documents d ON d.source_id = s.id
GROUP BY s.key ORDER BY docs DESC;
SELECT id, kind, enabled, array_to_string(base_uris,' | ') FROM vex.providers ORDER BY id;
What the UI workflow looks like
/setup/integrations→ advisory sources catalog.- Each source row shows
enabled,readiness(ready/blocked/disabled/unsupported), and the stored configuration schema. readiness=blockedmeans the source is persisted as enabled but is missing required fields (credentials, URIs). The source will be excluded from automatic and manual sync with a blocked-outcome response (contract:SOURCE_CONFIG_REQUIRED, delivered via SPRINT_20260422_003 SRC-CREDS-005 work landed earlier today).- Paste credentials in the source's detail editor. The server persists them; subsequent reads surface only a masked "secret retained" badge — secrets are never echoed back.
- Updating an unrelated field doesn't require re-entering the secret; the server detects "no change" and preserves the stored value.
Follow-up for this stack
- ~65 aspirational catalog entries still need backend connector wiring — tracked in
SPRINT_20260422_004and follow-up sprints. Concelier.Advisories.Readpolicy requiresadvisory:readscope which requiresaoc:verifyscope pairing, and thestellaops-cliOAuth client isn't allowed to mintaoc:verify. The UI (stella-ops-uiclient, authorization_code flow) CAN mint it. Result: the CLI can execute the write path (enable, disable, sync) but cannot call the read-only status/catalog endpoints directly — it uses a separate auth path. This is a known asymmetry; documented here for future operators.