This commit is contained in:
StellaOps Bot
2025-12-14 23:20:14 +02:00
parent 3411e825cd
commit b058dbe031
356 changed files with 68310 additions and 1108 deletions

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.Abstractions.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.Cisco.CSAF.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.MSRC.CSAF.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.OCI.OpenVEX.Attest.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.Oracle.CSAF.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.RedHat.CSAF.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.SUSE.RancherVEXHub.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,5 @@
using System.Runtime.CompilerServices;
using StellaOps.Plugin.Versioning;
[assembly: InternalsVisibleTo("StellaOps.Excititor.Connectors.Ubuntu.CSAF.Tests")]
[assembly: StellaPluginVersion("1.0.0", MinimumHostVersion = "1.0.0", MaximumHostVersion = "1.99.99")]

View File

@@ -0,0 +1,102 @@
-- VEX Schema Migration 003: Row-Level Security
-- Sprint: SPRINT_3421_0001_0001 - RLS Expansion
-- Category: B (release migration, requires coordination)
--
-- Purpose: Enable Row-Level Security on all tenant-scoped tables in the vex
-- schema to provide database-level tenant isolation as defense-in-depth.
--
-- Note: VEX tables use 'tenant' column (not 'tenant_id') as per original schema.
BEGIN;
-- ============================================================================
-- Step 1: Create helper schema and function for tenant context
-- ============================================================================
CREATE SCHEMA IF NOT EXISTS vex_app;
-- Tenant context helper function
CREATE OR REPLACE FUNCTION vex_app.require_current_tenant()
RETURNS TEXT
LANGUAGE plpgsql STABLE SECURITY DEFINER
AS $$
DECLARE
v_tenant TEXT;
BEGIN
v_tenant := current_setting('app.tenant_id', true);
IF v_tenant IS NULL OR v_tenant = '' THEN
RAISE EXCEPTION 'app.tenant_id session variable not set'
USING HINT = 'Set via: SELECT set_config(''app.tenant_id'', ''<tenant>'', false)',
ERRCODE = 'P0001';
END IF;
RETURN v_tenant;
END;
$$;
REVOKE ALL ON FUNCTION vex_app.require_current_tenant() FROM PUBLIC;
-- ============================================================================
-- Step 2: Enable RLS on all tenant-scoped tables
-- ============================================================================
-- vex.linksets
ALTER TABLE vex.linksets ENABLE ROW LEVEL SECURITY;
ALTER TABLE vex.linksets FORCE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS linksets_tenant_isolation ON vex.linksets;
CREATE POLICY linksets_tenant_isolation ON vex.linksets
FOR ALL
USING (tenant = vex_app.require_current_tenant())
WITH CHECK (tenant = vex_app.require_current_tenant());
-- vex.linkset_observations (inherits tenant via FK to linksets)
ALTER TABLE vex.linkset_observations ENABLE ROW LEVEL SECURITY;
ALTER TABLE vex.linkset_observations FORCE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS linkset_observations_tenant_isolation ON vex.linkset_observations;
CREATE POLICY linkset_observations_tenant_isolation ON vex.linkset_observations
FOR ALL
USING (
linkset_id IN (
SELECT linkset_id FROM vex.linksets
WHERE tenant = vex_app.require_current_tenant()
)
);
-- vex.linkset_disagreements (inherits tenant via FK to linksets)
ALTER TABLE vex.linkset_disagreements ENABLE ROW LEVEL SECURITY;
ALTER TABLE vex.linkset_disagreements FORCE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS linkset_disagreements_tenant_isolation ON vex.linkset_disagreements;
CREATE POLICY linkset_disagreements_tenant_isolation ON vex.linkset_disagreements
FOR ALL
USING (
linkset_id IN (
SELECT linkset_id FROM vex.linksets
WHERE tenant = vex_app.require_current_tenant()
)
);
-- vex.linkset_mutations (inherits tenant via FK to linksets)
ALTER TABLE vex.linkset_mutations ENABLE ROW LEVEL SECURITY;
ALTER TABLE vex.linkset_mutations FORCE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS linkset_mutations_tenant_isolation ON vex.linkset_mutations;
CREATE POLICY linkset_mutations_tenant_isolation ON vex.linkset_mutations
FOR ALL
USING (
linkset_id IN (
SELECT linkset_id FROM vex.linksets
WHERE tenant = vex_app.require_current_tenant()
)
);
-- ============================================================================
-- Step 3: Create admin bypass role
-- ============================================================================
DO $$
BEGIN
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'vex_admin') THEN
CREATE ROLE vex_admin WITH NOLOGIN BYPASSRLS;
END IF;
END
$$;
COMMIT;

View File

@@ -0,0 +1,95 @@
-- VEX Schema Migration 004: Generated Columns for JSONB Hot Keys
-- Sprint: SPRINT_3423_0001_0001 - Generated Columns for JSONB Hot Keys
-- Category: A (safe, can run at startup)
--
-- Purpose: Extract frequently-queried fields from JSONB columns as generated columns
-- to enable efficient B-tree indexing and accurate query planning statistics.
BEGIN;
-- ============================================================================
-- vex.vex_raw_documents: Extract metadata and provenance hot fields
-- ============================================================================
-- Format version from metadata (e.g., "openvex/0.2.0", "csaf/2.0")
ALTER TABLE vex.vex_raw_documents
ADD COLUMN IF NOT EXISTS doc_format_version TEXT
GENERATED ALWAYS AS (metadata_json->>'formatVersion') STORED;
-- Tool name that produced the VEX document
ALTER TABLE vex.vex_raw_documents
ADD COLUMN IF NOT EXISTS doc_tool_name TEXT
GENERATED ALWAYS AS (metadata_json->>'toolName') STORED;
-- Tool version for provenance tracking
ALTER TABLE vex.vex_raw_documents
ADD COLUMN IF NOT EXISTS doc_tool_version TEXT
GENERATED ALWAYS AS (metadata_json->>'toolVersion') STORED;
-- Author/supplier from provenance (common filter)
ALTER TABLE vex.vex_raw_documents
ADD COLUMN IF NOT EXISTS doc_author TEXT
GENERATED ALWAYS AS (provenance_json->>'author') STORED;
-- Timestamp from provenance (useful for ordering)
ALTER TABLE vex.vex_raw_documents
ADD COLUMN IF NOT EXISTS doc_timestamp TIMESTAMPTZ
GENERATED ALWAYS AS ((provenance_json->>'timestamp')::timestamptz) STORED;
-- ============================================================================
-- Indexes on generated columns
-- ============================================================================
-- Index for filtering by format version (common dashboard query)
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_vex_raw_docs_format_version
ON vex.vex_raw_documents (doc_format_version)
WHERE doc_format_version IS NOT NULL;
-- Index for filtering by tool name (compliance reporting)
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_vex_raw_docs_tool_name
ON vex.vex_raw_documents (tenant, doc_tool_name)
WHERE doc_tool_name IS NOT NULL;
-- Index for author-based queries (supplier filtering)
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_vex_raw_docs_author
ON vex.vex_raw_documents (tenant, doc_author)
WHERE doc_author IS NOT NULL;
-- Composite index for time-ordered tool queries
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_vex_raw_docs_tool_time
ON vex.vex_raw_documents (tenant, doc_tool_name, doc_timestamp DESC)
WHERE doc_tool_name IS NOT NULL;
-- Covering index for document listing dashboard
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_vex_raw_docs_listing
ON vex.vex_raw_documents (tenant, retrieved_at DESC)
INCLUDE (format, doc_format_version, doc_tool_name, doc_author);
-- Update statistics for query planner
ANALYZE vex.vex_raw_documents;
COMMIT;
-- ============================================================================
-- Verification queries (run manually to confirm):
-- ============================================================================
--
-- -- Check generated columns are populated:
-- SELECT
-- digest,
-- format,
-- doc_format_version,
-- doc_tool_name,
-- doc_author,
-- doc_timestamp
-- FROM vex.vex_raw_documents
-- LIMIT 10;
--
-- -- Verify index usage:
-- EXPLAIN ANALYZE
-- SELECT digest, doc_tool_name, doc_timestamp
-- FROM vex.vex_raw_documents
-- WHERE tenant = 'test-tenant'
-- AND doc_tool_name = 'trivy'
-- ORDER BY doc_timestamp DESC
-- LIMIT 20;