Files
git.stella-ops.org/docs/implplan
master df66ce10c3 feat(excititor): OCI OpenVEX artifact-backed configuration (SPRINT_20260423_001)
Closes SPRINT_20260423_001 — all 3 tasks DONE, sprint archived. Extends
the scalar persisted-settings model (7efa424fe) with an artifact-
reference storage layer for the complex OCI OpenVEX connector, which
carries image subscription lists + cosign keys + TUF roots that don't
fit the flat values/clearKeys shape.

OCI-CFG-001 — Storage model:
- New vex.provider_artifact_refs table via embedded migration
  009_vex_provider_artifact_refs.sql (auto-applied per §2.7). Columns:
  artifact_id (UUID PK), provider_id, tenant_id, mime_type, size_bytes,
  sha256, payload bytea, staged_at, staged_by. RLS via
  current_setting('app.tenant_id', TRUE); size_bytes CHECK >= 0.
- Upload / list / meta / delete API under /excititor/providers/{id}/
  artifacts. Multipart upload returns { artifactId, sha256, ... };
  meta never returns payload. Scopes: read=vex.read, write=vex.admin.
- VexProviderArtifactMaterializer: scoped session writes artifacts to
  %TMP%/stella-excititor-artifacts/<guid>/<artifactId>.bin with
  chmod 0700/0600 on POSIX; Dispose cleans up the scratch root.
  IDisposable + IAsyncDisposable, idempotent cleanup.
- PostgresVexProviderArtifactStore uses raw Npgsql for bytea I/O
  (bypasses EF compiled-model cache + change tracking); EF entity
  ProviderArtifactRefRow added for future EF-consumer completeness.

OCI-CFG-002 — Config wiring:
- VexProviderConfigurationFieldDefinition.FieldShape extended:
  scalar | list<string> | artifactRef | list<artifactRef>.
- list<string> encoded as newline-or-JSON text; artifactRef stored as
  the artifact UUID. Snapshot exposes FieldShape for clients.
- OCI-specific blocked sub-codes (all inside PROVIDER_CONFIG_INVALID /
  _REQUIRED envelope): PROVIDER_CONFIG_MISSING_IMAGE_SUBSCRIPTIONS,
  _INVALID_IMAGE_REFERENCE, _MISSING_COSIGN_KEY, _MISSING_COSIGN_ISSUER,
  _MISSING_COSIGN_SUBJECT, _MISSING_TUF_ROOT, _INVALID_COSIGN_MODE,
  _HTTP_REGISTRY_BLOCKED.
- Readiness reuses OciOpenVexAttestationConnectorOptions validator.

OCI-CFG-003 — CLI + Web:
- CLI `stella vex providers configure` flags: --image (repeatable),
  --upload-artifact <key>=@<path> (repeatable), --clear-artifact,
  --list-artifacts, --host-path-compat (CLI-only compatibility mode).
- New subcommand `stella vex providers artifacts <provider>` lists
  staged artifacts.
- OciOpenVexConfigurationComponent (Angular standalone): image-
  subscription list editor, artifact slots with file upload + staged
  meta, scalar fields for cosign mode/issuer/subject/registry auth/
  offline bundle, staged-artifact table with delete. Conditionally
  rendered in vex-provider-catalog when provider.id == 'excititor:
  oci-openvex'.
- docs/modules/excititor/operations/provider-credentials.md §5 OCI
  OpenVEX rewritten with 4 canonical setup flows: keyless, keypair,
  TUF+offline, private-registry.

Tests: targeted xUnit via scripts/test-targeted-xunit.ps1:
- VexProviderConfigurationServiceTests — 8/8 (regression)
- VexProviderOciOpenVexTests — 13/13 (OCI schema + sub-codes + artifact
  service size/quota/tenant-isolation + materializer tempfile lifecycle)

Worker-side wiring of VexProviderArtifactMaterializationSession into
DefaultVexProviderRunner (before cosign/TUF validation) is a natural
follow-up — the resolver + API + store exist; a future sprint ties
the runner into the session lifecycle when the first end-to-end OCI
provider scan lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 08:10:14 +03:00
..
2026-02-01 21:37:40 +02:00