fix(security): reconcile asset control plane truth
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m27s
CD Pipeline / build-and-deploy (push) Failing after 3m57s
CD Pipeline / post-deploy-checks (push) Has been skipped

This commit is contained in:
ogt
2026-07-14 10:47:33 +08:00
parent 467542a018
commit b6ddee7984
9 changed files with 869 additions and 170 deletions

View File

@@ -0,0 +1,40 @@
-- Reconcile the production asset_inventory type constraint with source truth.
-- Safety: allowlist-only DDL, bounded locks, no row data reads or deletes.
SET lock_timeout = '5s';
SET statement_timeout = '30s';
ALTER TABLE asset_inventory
DROP CONSTRAINT IF EXISTS asset_inventory_type_valid;
ALTER TABLE asset_inventory
ADD CONSTRAINT asset_inventory_type_valid CHECK (asset_type IN (
'host','container','k8s_workload','k8s_resource','database','table',
'website','api_endpoint','package','log_stream','km_entry',
'frontend','backend','ci_pipeline','gitea_repo','monitoring_target',
'secret','volume','network','certificate','scheduled_job',
'message_queue','cache','dashboard','ai_agent','llm_model',
'third_party_service','backup_target'
)) NOT VALID;
ALTER TABLE asset_inventory
VALIDATE CONSTRAINT asset_inventory_type_valid;
INSERT INTO automation_operation_log (
operation_type,
actor,
status,
input,
output,
tags
) VALUES (
'asset_discovered',
'gitea_cd_asset_schema_reconciler',
'success',
'{"work_item_id":"AIA-P0-006","migration":"asset_inventory_database_types_2026-07-14"}'::jsonb,
'{"constraint_validated":true,"constraint_type_set_exact":true,"database_type_allowed":true,"table_type_allowed":true}'::jsonb,
ARRAY['asset_control_plane','schema_migration','controlled_apply','post_verified']
);
COMMENT ON CONSTRAINT asset_inventory_type_valid ON asset_inventory IS
'Asset control-plane allowlist reconciled by Gitea CD; includes database and table metadata assets.';

View File

@@ -0,0 +1,57 @@
-- Roll back database/table asset types only when no such inventory rows exist.
-- This script never deletes rows to make rollback possible.
SET lock_timeout = '5s';
SET statement_timeout = '30s';
DO $migration$
DECLARE
dependent_rows BIGINT;
BEGIN
SELECT COUNT(*)
INTO dependent_rows
FROM asset_inventory
WHERE asset_type IN ('database', 'table');
IF dependent_rows > 0 THEN
RAISE EXCEPTION
'rollback blocked: % database/table asset rows must be reconciled first',
dependent_rows;
END IF;
ALTER TABLE asset_inventory
DROP CONSTRAINT IF EXISTS asset_inventory_type_valid;
ALTER TABLE asset_inventory
ADD CONSTRAINT asset_inventory_type_valid CHECK (asset_type IN (
'host','container','k8s_workload','k8s_resource',
'website','api_endpoint','package','log_stream','km_entry',
'frontend','backend','ci_pipeline','gitea_repo','monitoring_target',
'secret','volume','network','certificate','scheduled_job',
'message_queue','cache','dashboard','ai_agent','llm_model',
'third_party_service','backup_target'
)) NOT VALID;
ALTER TABLE asset_inventory
VALIDATE CONSTRAINT asset_inventory_type_valid;
INSERT INTO automation_operation_log (
operation_type,
actor,
status,
input,
output,
tags
) VALUES (
'asset_discovered',
'gitea_cd_asset_schema_reconciler',
'rolled_back',
'{"work_item_id":"AIA-P0-006","migration":"asset_inventory_database_types_2026-07-14_down"}'::jsonb,
'{"database_type_allowed":false,"table_type_allowed":false,"dependent_rows":0}'::jsonb,
ARRAY['asset_control_plane','schema_migration','controlled_rollback']
);
END
$migration$;
COMMENT ON CONSTRAINT asset_inventory_type_valid ON asset_inventory IS
'Rollback allowlist without database/table types; blocked while dependent asset rows exist.';