Excititor Provider Control Plane
Audience: Operators configuring, enabling, and troubleshooting Excititor VEX providers through the Web UI, CLI, or backend API.
This guide describes the operator-facing control plane for Excititor VEX providers: the entry points, readiness model, run counters, the provider inventory, and what configuration each provider persists. For credential acquisition and step-by-step setup, see the Provider Credential Entry guide.
Operator entry points
- Web UI:
Ops -> Integrations -> Advisory & VEX Sources -> VEX Providers - CLI:
stella vex providers configure <provider> [--set key=value ...] [--clear key ...] [--format text|json]stella vex providers configure <provider> --source-url <https-url> --confirm-source-url [--trust-mode signed-required|cache-only|quarantine-only]
Backend API:
GET /excititor/providersGET /excititor/providers/{providerId}PUT /excititor/providers/{providerId}POST /excititor/providers/{providerId}/enablePOST /excititor/providers/{providerId}/disablePOST /excititor/providers/{providerId}/runGET /excititor/providers/{providerId}/configuration— persisted connector settings (masked secrets)PUT /excititor/providers/{providerId}/configuration—{ values, clearKeys }request shape, retains secrets submitted blank
Read endpoints accept Authority’s canonical vex:read scope and the legacy vex.read spelling for compatibility with older local tests and clients. Mutation endpoints require vex.admin.
If PostgreSQL refuses a connection because the shared server has reached its client limit, GET /excititor/providers returns RFC 7807 status 503, code excititor.providers.storage_unavailable, and Retry-After: 5. It never emits database text or a stack trace. The canonical compose stack also caps the Web and Worker pools independently with Postgres:Excititor:MaxPoolSize (default 8 per process) and retires idle connections after 60 seconds. Clients should honor Retry-After; they must not interpret a temporary storage failure as an empty or healthy provider catalog.
Persisted connector configuration (Sprint 20260422_007) is the primary operator path for credentialed VEX providers. Host-config and environment binding remain compatibility fallbacks only. Persisted settings win when both define the same key.
Related credential guide:
Readiness states
Excititor providers use four runtime readiness states:
ready: persisted-enabled and the current host has a runnable connectorblocked: persisted-enabled but missing required persisted configuration, cooling down, rejected every attempted VEX document before raw storage, or otherwise not runnabledisabled: persisted-disabledplanned: cataloged provider without a runnable connector registered on the current host
enabled remains the operator intent flag. A provider can be enabled=true and still show planned or blocked.
Blocked-readiness codes (Sprint 20260422_007, extended Sprint 20260507_004)
When a persisted-enabled provider lacks required settings or fails connector-option validation, the blocked-reason surface carries one of:
PROVIDER_CONFIG_REQUIRED— one or more required fields are absent, such as UbuntuetagSecret, OCI OpenVEXimages, MSRCtenantId/clientId/clientSecretwhenauthMode=ClientCredentials, or MSRCofflineTokenPath/staticAccessTokenwhenauthMode=OfflineToken.PROVIDER_CONFIG_INVALID— settings are present but the connector’s own option validator rejected them (e.g. CiscometadataUriis not an absolute URI, Rancher hub credential set is partial).PROVIDER_SOURCE_URL_REQUIRED— a provider needs either an HTTPS source URL or an approved offline snapshot before sync can run.PROVIDER_SOURCE_URL_NOT_HTTPS— an operator-supplied source URL uses a non-HTTPS scheme and is rejected before ingestion.PROVIDER_SOURCE_URL_CONFIRMATION_REQUIRED— an operator-supplied or high-risk default source URL has not been explicitly confirmed for this Stella Ops Mirror setup.PROVIDER_TRUST_MATERIAL_REQUIRED—trustMode=signed-requiredis selected for a provider that cannot rely on built-in provider metadata and no pinned PGP/Cosign trust material has been configured.RUN_ZERO_YIELD_REJECTED— the last run attempted downloads but all attempted documents were rejected or quarantined before raw storage, so the provider is not healthy even if the job loop reached the end of the connector stream.
These codes mirror the Concelier SOURCE_CONFIG_REQUIRED / SOURCE_CONFIG_INVALID contract from SRC-CREDS-005 so CLI and Web surfaces can reuse the same rendering. The /excititor/providers list response exposes them via blockingReasonCode and blockingReason.
Run counters
Provider list/detail responses expose lastRunCounters when the connector has persisted run evidence in vex.connector_states.resume_tokens. Direct run endpoints (POST /excititor/ingest/run, POST /excititor/ingest/resume, and POST /excititor/providers/{providerId}/run) return the same per-provider counters object in their run result payloads.
The counter payload contains:
status,startedAt,completedAt,firstRejectionReason, anderrordiscovered,downloaded,rawStored,yielded,quarantined,rejected,claims, andstatements
Counters are stored under the __run.* resume-token prefix so the control plane can explain the last run without a schema migration or log scraping. When a connector does not expose an upstream catalog candidate count, discovered and downloaded are conservative lower-bound attempt counts derived from rawStored + rejected.
Run status rules:
succeeded: raw documents were stored and no quarantines/rejections were counted.degraded: at least one raw document was stored or yielded, but one or more documents were quarantined/rejected.blocked: no document was yielded or stored and at least one attempted document was rejected before raw storage. This surfaces asRUN_ZERO_YIELD_REJECTEDin provider readiness.failedorcancelled: the run exited through an exception or cancellation and the same counters are preserved witherror.
Provider inventory
| Provider ID | Kind | Default enabled | Registered in WebService | UI control plane | CLI control plane | Credential / config status | Notes |
|---|---|---|---|---|---|---|---|
excititor:redhat | distro | true | yes | yes | yes | Public defaults; metadata and trust overrides can be persisted through the provider control plane. | Registered by default in StellaOps.Excititor.WebService. |
excititor:ubuntu | distro | true | yes | yes | yes | Default public OpenVEX archive mode requires no credentials; etagSecret is required only when an operator selects legacy LiveNotices / CSAF catalog modes. | Registered by default and uses Canonical’s public OpenVEX archive unless configured otherwise. |
excititor:oracle | vendor | true | yes | yes | yes | Public CSAF JSON/RSS is reachable but observed detached signatures/provider trust material are absent. Operators must confirm catalogUri and choose cache-only/quarantine-only, or provide pinned trust material for signed-required. | Registered by default and blocked for trusted Stella Ops Mirror VEX until verifiable signing material or an explicit unsigned quarantine policy exists. |
excititor:cisco | vendor | true | yes | yes | yes | Persisted scalar config supports metadataUri override plus optional apiToken. Default public Cisco CSAF works without credentials. | Registered by default in StellaOps.Excititor.WebService. |
excititor:suse-rancher | hub | false | yes | yes | yes | Default discovery metadata is unavailable from this environment. Operators can confirm a reachable discoveryUri, configure an offline snapshot, and provide signed-required trust material or select cache/quarantine mode. | Disabled by default for public mirror mode and reports discovery/offline-snapshot requirements when no reachable public hub metadata is configured. |
excititor:oci-openvex | attestation | false | yes | yes | yes | Persisted config supports image subscriptions, registry credentials, cosign mode/identity settings, and artifact references for cosign/TUF material. | Disabled by default and reports configuration-required until image subscriptions are supplied. |
excititor:msrc | vendor | false | yes | yes | yes | Persisted scalar config supports authMode, tenantId, clientId, clientSecret, optional scope, preferOfflineToken, offlineTokenPath, and staticAccessToken. The default Public mode does not require credentials. | Registered by default. It is runnable in public mode and surfaces as configuration-blocked only when the selected auth mode is missing required fields. |
What the current provider control plane persists
The current update-provider surface persists:
- display name
- provider kind
- base URIs
- well-known metadata URI
- ROLIE service URI
- trust weight
- PGP fingerprints
- cosign issuer
- cosign identity pattern
- enabled / disabled intent
The provider control plane now persists the connector-secret fields needed by the built-in providers listed below. Host configuration remains a compatibility fallback for existing deployments, but persisted settings win whenever they are present.
Persisted scalar-provider configuration (Sprint 20260422_007)
The following provider connector settings can now be persisted through the UI or CLI and are kept in a dedicated vex.provider_settings row (distinct from vex.providers metadata):
| Provider | Persisted fields |
|---|---|
excititor:cisco | metadataUri (optional override; default uses Cisco’s public download metadata endpoint), sourceUrlConfirmed, sourceUrlConfirmedAt, sourceUrlConfirmedBy, trustMode, apiToken (sensitive) |
excititor:ubuntu | sourceMode, archiveUri, archiveAllowUnsigned, indexUri, noticeDetailBaseUri, etagSecret (sensitive, required only for legacy notice/catalog modes), cosignIssuer, cosignIdentityPattern, pgpFingerprints, allowUnsigned |
excititor:redhat | metadataUri, sourceUrlConfirmed, sourceUrlConfirmedAt, sourceUrlConfirmedBy, trustMode, offlineSnapshotPath, cosignIssuer, cosignIdentityPattern, pgpFingerprints, allowUnsigned |
excititor:oracle | catalogUri, sourceUrlConfirmed, sourceUrlConfirmedAt, sourceUrlConfirmedBy, trustMode, cpuCalendarUri, offlineSnapshotPath, pgpKeyFingerprint, allowUnsigned |
excititor:suse-rancher | discoveryUri, sourceUrlConfirmed, sourceUrlConfirmedAt, sourceUrlConfirmedBy, trustMode, offlineSnapshotPath, optional OAuth client fields, allowAnonymousDiscovery, cosignIssuer, cosignIdentityPattern, pgpFingerprints, allowUnsigned |
excititor:msrc | feedMode (ProviderMetadata or SecurityUpdateGuideApi), metadataUri, authMode (Public, ClientCredentials, or OfflineToken), tenantId, clientId, clientSecret (sensitive), scope (optional override), preferOfflineToken, offlineTokenPath, staticAccessToken (sensitive) |
excititor:oci-openvex | images, registrySourcesConfirmed, sourceUrlConfirmedAt, sourceUrlConfirmedBy, trustMode, registry credentials, cosign mode/identity settings, artifact references for cosign keys/certificates/TUF roots, offline bundle root |
Source confirmation is intentionally separate from trust admission. sourceUrlConfirmed=true only records that the operator reviewed the HTTPS source URL for this Stella Ops Mirror setup. trustMode controls whether the source may be admitted as signed-required, collected as cache-only, or restricted to quarantine-only workflows. At worker and manual WebService ingest runtime, trustMode=cache-only projects to the connector allowUnsigned=true setting so unsigned public material can be collected with vex.signature.status=unsigned; this is cache admission only and must not be treated as trusted VEX publication.
Operator surfaces:
- CLI:
stella vex providers configure <provider> [--set key=value ...] [--clear key ...] [--format text|json] - CLI source helper:
stella vex providers configure oracle --source-url https://www.oracle.com/ocom/groups/public/@otn/documents/webcontent/rss-otn-sec.xml --confirm-source-url --trust-mode cache-only - Web: provider configuration panel rendering masked secret state, required-field markers, and explicit clear toggles.
Sensitive values are never re-exposed on reads — the API returns only hasValue/isSecretRetained flags. Blank submissions retain existing secrets; explicit clearKeys entries delete them.
Persisted provider settings win over host configuration. For Ubuntu legacy notice/catalog modes, the worker also projects Excititor:Connectors:Ubuntu:EtagSecret and related host keys into the built-in schedule as a compatibility fallback when no persisted etagSecret is present. Default OpenVEX archive mode does not require that secret. For MSRC, host configuration can still supply the same auth-mode and credential fields for compatibility, but the control-plane settings are the operator-owned source once saved.
Host wiring notes
StellaOps.Excititor.WebServicealways registers:- Red Hat CSAF
- Ubuntu CSAF
- Oracle CSAF
- Cisco CSAF
- SUSE Rancher VEX Hub
- OCI OpenVEX attestations
- Microsoft MSRC CSAF
StellaOps.Excititor.Workerseeds these public defaults when no explicit provider schedule list is supplied:excititor:redhatexcititor:ubuntuexcititor:oracleexcititor:ciscoexcititor:suse-rancherexcititor:oci-openvexexcititor:msrc
Worker scheduling authority & full-corpus opt-in (VRB-1)
There are two independent enable surfaces — do not confuse them:
- DB-backed catalog
Enabled(vex.providers,POST /excititor/providers/{id}/enable|disable, the Web UI/CLI above): operator intent for the WebService management surface. It does not gate the background worker’s scheduled ingest. - Worker options
Enabled(Excititor:Worker:Providers[n].Enabled, resolved byVexWorkerOptions.ResolveSchedules): the actual scheduling authority for background ingest.VexWorkerHostedServiceonly launches providers this gate returns.
Because every current public default (Red Hat CSAF, Ubuntu, Oracle, Cisco, SUSE Rancher, OCI-OpenVEX, MSRC) is a full-corpus (“heavy”) connector, an unguarded auto-seed used to make a fresh dev/airgap box start pulling entire vendor corpora after the staggered initial delay — the root cause of the 420 GB dev-DB crash (SPRINT_20260630_001).
Default-safe behavior (VRB-1): on a fresh install with no explicit provider list, the worker seeds all 7 public providers into the schedule catalog but leaves every heavy connector Enabled=false, so ResolveSchedules() schedules zero of them and there is no auto-ingest — no manual vex.providers.enabled=false step is needed (that manual 2026-06-30 mitigation is now the default).
Opting in to full-corpus ingest (two documented, discoverable mechanisms):
- Global flag (one switch, all heavy connectors):
Excititor:Worker:EnableFullCorpusConnectors=true(envExcititor__Worker__EnableFullCorpusConnectors=true). Flips the auto-seeded heavy set toEnabled=true. Reference compose:devops/compose/docker-compose.vex-full-corpus-optin.override.yml. - Explicit per-source list (surgical): declare
Excititor:Worker:Providers[n].ProviderId+Enabled=true. Any non-empty provider list fully replaces the auto-seed (BuiltInVexProviderDefaults.SeedPublicDefaultsearly-returns), so the operator controls exactly which providers run. Reference compose:devops/compose/docker-compose.vex-ingest-live.override.yml.
When heavy connectors are gated off, the worker logs a VRB-1 warning naming the skipped providers and the exact opt-in flag, so a prod deployment is never silently starved — it must declare intent once.
This preventive gate is orthogonal to the reactive disk-ceiling guardrail (VRB-5 / R5, VexIngestGuardrail.CheckDbCeilingAsync): VRB-1 decides whether a run starts; R5 still pauses a runaway run mid-flight at the DB-size ceiling. Both stay on independently. Downstream PROVIDER_CONFIG_REQUIRED / PROVIDER_TRUST_MATERIAL_REQUIRED validations remain a further layer even for opted-in providers.
Verification state
Reverified in Sprint 20260422_004:
- targeted backend tests for provider management endpoints passed against
StellaOps.Excititor.WebService.Tests.ProviderManagementEndpointsTests - Angular route helper spec passed for the new VEX provider route
- Angular development build passed with the new provider catalog page
- CLI provider inspection and control verbs were added for the backend surface
The verification above covers the provider control plane and readiness behavior. It does not claim a fresh live ingest verification run for every upstream VEX provider in this sprint.
