From f89359c07a90d72a8c54d29f398ab7c4a10ea409 Mon Sep 17 00:00:00 2001 From: ogt Date: Wed, 15 Jul 2026 03:03:04 +0800 Subject: [PATCH] fix(mcp): keep lifecycle receipt schema least privilege --- .../mcp_version_lifecycle_controller_2026-07-15.sql | 10 ++++++---- apps/api/tests/test_mcp_version_lifecycle_service.py | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/api/migrations/mcp_version_lifecycle_controller_2026-07-15.sql b/apps/api/migrations/mcp_version_lifecycle_controller_2026-07-15.sql index 958fea9a5..8aae3f5ef 100644 --- a/apps/api/migrations/mcp_version_lifecycle_controller_2026-07-15.sql +++ b/apps/api/migrations/mcp_version_lifecycle_controller_2026-07-15.sql @@ -13,8 +13,7 @@ CREATE TABLE IF NOT EXISTS awooop_mcp_version_lifecycle_run ( run_id UUID PRIMARY KEY, trace_id VARCHAR(128) NOT NULL, work_item_id VARCHAR(128) NOT NULL, - project_id VARCHAR(64) NOT NULL - REFERENCES awooop_projects(project_id) ON DELETE RESTRICT, + project_id VARCHAR(64) NOT NULL, trigger_kind VARCHAR(32) NOT NULL, status VARCHAR(48) NOT NULL, candidate_count INTEGER NOT NULL DEFAULT 0, @@ -29,6 +28,8 @@ CREATE TABLE IF NOT EXISTS awooop_mcp_version_lifecycle_run ( CONSTRAINT uix_mcp_version_lifecycle_trace UNIQUE (project_id, trace_id), + CONSTRAINT chk_mcp_version_lifecycle_project + CHECK (project_id = 'awoooi'), CONSTRAINT chk_mcp_version_lifecycle_trigger CHECK (trigger_kind IN ('startup','scheduled','operator_replay','test')), CONSTRAINT chk_mcp_version_lifecycle_status @@ -58,8 +59,7 @@ CREATE TABLE IF NOT EXISTS awooop_mcp_version_observation ( REFERENCES awooop_mcp_version_lifecycle_run(run_id) ON DELETE RESTRICT, trace_id VARCHAR(128) NOT NULL, work_item_id VARCHAR(128) NOT NULL, - project_id VARCHAR(64) NOT NULL - REFERENCES awooop_projects(project_id) ON DELETE RESTRICT, + project_id VARCHAR(64) NOT NULL, candidate_id VARCHAR(160) NOT NULL, catalog_source VARCHAR(32) NOT NULL, source_url TEXT NOT NULL, @@ -78,6 +78,8 @@ CREATE TABLE IF NOT EXISTS awooop_mcp_version_observation ( CONSTRAINT uix_mcp_version_observation_run_candidate UNIQUE (run_id, candidate_id), + CONSTRAINT chk_mcp_version_observation_project + CHECK (project_id = 'awoooi'), CONSTRAINT chk_mcp_version_catalog_source CHECK (catalog_source IN ('smithery','mcp-so')), CONSTRAINT chk_mcp_version_source_url_hash diff --git a/apps/api/tests/test_mcp_version_lifecycle_service.py b/apps/api/tests/test_mcp_version_lifecycle_service.py index 885e9a3eb..17c3f77de 100644 --- a/apps/api/tests/test_mcp_version_lifecycle_service.py +++ b/apps/api/tests/test_mcp_version_lifecycle_service.py @@ -244,6 +244,8 @@ def test_migration_is_additive_rls_and_does_not_store_raw_content() -> None: "with check (project_id = current_setting('app.project_id', true))" in lowered ) assert "drop table" not in lowered + assert "references awooop_projects" not in lowered + assert lowered.count("check (project_id = 'awoooi')") == 2 assert "request_body" not in lowered assert "response_body" not in lowered assert "raw_content jsonb" not in lowered