Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Implements secure user credential storage with comprehensive RLS policies and encryption-ready architecture for Phase 3 of M9-CredentialSecurity. **Features:** - UserCredential Prisma model with 19 fields - CredentialType enum (6 values: API_KEY, OAUTH_TOKEN, etc.) - CredentialScope enum (USER, WORKSPACE, SYSTEM) - FORCE ROW LEVEL SECURITY with 3 policies - Encrypted value storage (OpenBao Transit ready) - Cascade delete on user/workspace deletion - Activity logging integration (CREDENTIAL_* actions) - 28 comprehensive test cases **Security:** - RLS owner bypass, user access, workspace admin policies - SQL injection hardening for is_workspace_admin() - Encryption version tracking ready - Full down migration for reversibility **Testing:** - 100% enum coverage (all CredentialType + CredentialScope values) - Unique constraint enforcement - Foreign key cascade deletes - Timestamp behavior validation - JSONB metadata storage **Files:** - Migration: 20260207_add_user_credentials (184 lines + 76 line down.sql) - Security: 20260207163740_fix_sql_injection_is_workspace_admin - Tests: user-credential.model.spec.ts (28 tests, 544 lines) - Docs: README.md (228 lines), scratchpad Fixes #355 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77 lines
3.6 KiB
SQL
77 lines
3.6 KiB
SQL
-- Rollback: User Credentials Storage with RLS Policies
|
|
-- This migration reverses all changes from migration.sql
|
|
--
|
|
-- Related: #355 - Create UserCredential Prisma model with RLS policies
|
|
|
|
-- =============================================================================
|
|
-- DROP TRIGGERS AND FUNCTIONS
|
|
-- =============================================================================
|
|
|
|
DROP TRIGGER IF EXISTS user_credentials_updated_at ON user_credentials;
|
|
DROP FUNCTION IF EXISTS update_user_credentials_updated_at();
|
|
|
|
-- =============================================================================
|
|
-- DISABLE RLS
|
|
-- =============================================================================
|
|
|
|
ALTER TABLE user_credentials DISABLE ROW LEVEL SECURITY;
|
|
|
|
-- =============================================================================
|
|
-- DROP RLS POLICIES
|
|
-- =============================================================================
|
|
|
|
DROP POLICY IF EXISTS user_credentials_owner_bypass ON user_credentials;
|
|
DROP POLICY IF EXISTS user_credentials_user_access ON user_credentials;
|
|
DROP POLICY IF EXISTS user_credentials_workspace_access ON user_credentials;
|
|
|
|
-- =============================================================================
|
|
-- DROP INDEXES
|
|
-- =============================================================================
|
|
|
|
DROP INDEX IF EXISTS "user_credentials_user_id_workspace_id_provider_name_key";
|
|
DROP INDEX IF EXISTS "user_credentials_scope_is_active_idx";
|
|
DROP INDEX IF EXISTS "user_credentials_workspace_id_scope_idx";
|
|
DROP INDEX IF EXISTS "user_credentials_user_id_scope_idx";
|
|
DROP INDEX IF EXISTS "user_credentials_workspace_id_idx";
|
|
DROP INDEX IF EXISTS "user_credentials_user_id_idx";
|
|
|
|
-- =============================================================================
|
|
-- DROP FOREIGN KEY CONSTRAINTS
|
|
-- =============================================================================
|
|
|
|
ALTER TABLE "user_credentials" DROP CONSTRAINT IF EXISTS "user_credentials_workspace_id_fkey";
|
|
ALTER TABLE "user_credentials" DROP CONSTRAINT IF EXISTS "user_credentials_user_id_fkey";
|
|
|
|
-- =============================================================================
|
|
-- DROP TABLE
|
|
-- =============================================================================
|
|
|
|
DROP TABLE IF EXISTS "user_credentials";
|
|
|
|
-- =============================================================================
|
|
-- DROP ENUMS
|
|
-- =============================================================================
|
|
-- NOTE: ENUM values cannot be easily removed from an existing enum type in PostgreSQL.
|
|
-- To fully reverse this migration, you would need to:
|
|
--
|
|
-- 1. Remove the 'CREDENTIAL' value from EntityType enum (if not used elsewhere):
|
|
-- ALTER TYPE "EntityType" RENAME TO "EntityType_old";
|
|
-- CREATE TYPE "EntityType" AS ENUM (...all values except CREDENTIAL...);
|
|
-- -- Then rebuild all dependent objects
|
|
--
|
|
-- 2. Remove credential-related actions from ActivityAction enum (if not used elsewhere):
|
|
-- ALTER TYPE "ActivityAction" RENAME TO "ActivityAction_old";
|
|
-- CREATE TYPE "ActivityAction" AS ENUM (...all values except CREDENTIAL_*...);
|
|
-- -- Then rebuild all dependent objects
|
|
--
|
|
-- 3. Drop the CredentialType and CredentialScope enums:
|
|
-- DROP TYPE IF EXISTS "CredentialType";
|
|
-- DROP TYPE IF EXISTS "CredentialScope";
|
|
--
|
|
-- Due to the complexity and risk of breaking existing data/code that references
|
|
-- these enum values, this migration does NOT automatically remove them.
|
|
-- If you need to clean up the enums, manually execute the steps above.
|
|
--
|
|
-- For development environments, you can safely drop and recreate the enums manually
|
|
-- using the SQL statements above.
|