Fix build and code structure improvements. New but essential UI functionality. CI improvements. Documentation improvements. AI module improvements.

This commit is contained in:
StellaOps Bot
2025-12-26 21:54:17 +02:00
parent 335ff7da16
commit c2b9cd8d1f
3717 changed files with 264714 additions and 48202 deletions

View File

@@ -0,0 +1,141 @@
-- ReachGraph Store Schema
-- Content-addressed storage for reachability subgraphs
-- Version: 1.0.0
-- Created: 2025-12-27
BEGIN;
-- Create schema if not exists
CREATE SCHEMA IF NOT EXISTS reachgraph;
-- Main subgraph storage
-- Stores compressed reachgraph.min.json with content-addressed digest
CREATE TABLE reachgraph.subgraphs (
digest TEXT PRIMARY KEY, -- BLAKE3 of canonical JSON
artifact_digest TEXT NOT NULL, -- Image/artifact this applies to
tenant_id TEXT NOT NULL, -- Tenant isolation
scope JSONB NOT NULL, -- {entrypoints, selectors, cves}
node_count INTEGER NOT NULL,
edge_count INTEGER NOT NULL,
blob BYTEA NOT NULL, -- Compressed reachgraph.min.json (gzip)
blob_size_bytes INTEGER NOT NULL,
provenance JSONB NOT NULL, -- {intoto, inputs, computedAt, analyzer}
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT chk_digest_format CHECK (digest ~ '^blake3:[a-f0-9]{64}$'),
CONSTRAINT chk_artifact_digest_format CHECK (artifact_digest ~ '^(sha256|sha512):[a-f0-9]+$'),
CONSTRAINT chk_node_count_positive CHECK (node_count >= 0),
CONSTRAINT chk_edge_count_positive CHECK (edge_count >= 0),
CONSTRAINT chk_blob_size_positive CHECK (blob_size_bytes > 0)
);
-- Composite index for tenant + artifact lookup (most common query pattern)
CREATE INDEX idx_subgraphs_tenant_artifact
ON reachgraph.subgraphs (tenant_id, artifact_digest, created_at DESC);
-- Index for fast artifact lookup across tenants (admin queries)
CREATE INDEX idx_subgraphs_artifact
ON reachgraph.subgraphs (artifact_digest, created_at DESC);
-- Index for CVE-based queries using GIN on scope->'cves'
CREATE INDEX idx_subgraphs_cves
ON reachgraph.subgraphs USING GIN ((scope->'cves') jsonb_path_ops);
-- Index for entrypoint-based queries
CREATE INDEX idx_subgraphs_entrypoints
ON reachgraph.subgraphs USING GIN ((scope->'entrypoints') jsonb_path_ops);
-- Index for provenance input lookup (find graphs by source SBOM/VEX/callgraph)
CREATE INDEX idx_subgraphs_provenance_inputs
ON reachgraph.subgraphs USING GIN ((provenance->'inputs') jsonb_path_ops);
-- Slice cache (precomputed slices for hot queries)
CREATE TABLE reachgraph.slice_cache (
cache_key TEXT PRIMARY KEY, -- {digest}:{queryType}:{queryHash}
subgraph_digest TEXT NOT NULL REFERENCES reachgraph.subgraphs(digest) ON DELETE CASCADE,
slice_blob BYTEA NOT NULL, -- Compressed slice JSON
query_type TEXT NOT NULL, -- 'package', 'cve', 'entrypoint', 'file'
query_params JSONB NOT NULL, -- Original query parameters
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
expires_at TIMESTAMPTZ NOT NULL, -- TTL for cache expiration
hit_count INTEGER NOT NULL DEFAULT 0,
CONSTRAINT chk_query_type CHECK (query_type IN ('package', 'cve', 'entrypoint', 'file'))
);
-- Index for cache expiry cleanup
CREATE INDEX idx_slice_cache_expiry
ON reachgraph.slice_cache (expires_at);
-- Index for cache lookup by subgraph
CREATE INDEX idx_slice_cache_subgraph
ON reachgraph.slice_cache (subgraph_digest, created_at DESC);
-- Audit log for replay verification
CREATE TABLE reachgraph.replay_log (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
subgraph_digest TEXT NOT NULL,
input_digests JSONB NOT NULL, -- {sbom, vex, callgraph, runtimeFacts}
computed_digest TEXT NOT NULL, -- Result of replay
matches BOOLEAN NOT NULL, -- Did it match expected digest?
divergence JSONB, -- {nodesAdded, nodesRemoved, edgesChanged} if mismatch
tenant_id TEXT NOT NULL,
computed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
duration_ms INTEGER NOT NULL,
CONSTRAINT chk_duration_positive CHECK (duration_ms >= 0)
);
-- Index for replay log lookups
CREATE INDEX idx_replay_log_digest
ON reachgraph.replay_log (subgraph_digest, computed_at DESC);
-- Index for replay log by tenant
CREATE INDEX idx_replay_log_tenant
ON reachgraph.replay_log (tenant_id, computed_at DESC);
-- Index for finding replay failures
CREATE INDEX idx_replay_log_failures
ON reachgraph.replay_log (matches, computed_at DESC)
WHERE matches = false;
-- Enable Row Level Security
ALTER TABLE reachgraph.subgraphs ENABLE ROW LEVEL SECURITY;
ALTER TABLE reachgraph.slice_cache ENABLE ROW LEVEL SECURITY;
ALTER TABLE reachgraph.replay_log ENABLE ROW LEVEL SECURITY;
-- RLS policies (tenant isolation)
-- Note: current_setting('app.tenant_id', true) returns NULL if not set, which blocks all access
CREATE POLICY tenant_isolation_subgraphs ON reachgraph.subgraphs
FOR ALL
USING (tenant_id = current_setting('app.tenant_id', true))
WITH CHECK (tenant_id = current_setting('app.tenant_id', true));
-- Slice cache inherits tenant from parent subgraph (via foreign key)
CREATE POLICY tenant_isolation_slice_cache ON reachgraph.slice_cache
FOR ALL
USING (
subgraph_digest IN (
SELECT digest FROM reachgraph.subgraphs
WHERE tenant_id = current_setting('app.tenant_id', true)
)
);
CREATE POLICY tenant_isolation_replay_log ON reachgraph.replay_log
FOR ALL
USING (tenant_id = current_setting('app.tenant_id', true))
WITH CHECK (tenant_id = current_setting('app.tenant_id', true));
-- Comments for documentation
COMMENT ON SCHEMA reachgraph IS 'ReachGraph store schema for content-addressed reachability subgraphs';
COMMENT ON TABLE reachgraph.subgraphs IS 'Content-addressed storage for reachability subgraphs with DSSE signing support';
COMMENT ON TABLE reachgraph.slice_cache IS 'Cache for precomputed subgraph slices (package/CVE/entrypoint/file queries)';
COMMENT ON TABLE reachgraph.replay_log IS 'Audit log for deterministic replay verification';
COMMENT ON COLUMN reachgraph.subgraphs.digest IS 'BLAKE3-256 hash of canonical JSON (format: blake3:{hex})';
COMMENT ON COLUMN reachgraph.subgraphs.artifact_digest IS 'Container image or artifact digest this graph applies to';
COMMENT ON COLUMN reachgraph.subgraphs.blob IS 'Gzip-compressed reachgraph.min.json';
COMMENT ON COLUMN reachgraph.subgraphs.scope IS 'Analysis scope: entrypoints, selectors, and optional CVE filters';
COMMENT ON COLUMN reachgraph.subgraphs.provenance IS 'Provenance info: intoto links, input digests, analyzer metadata';
COMMIT;