Jason Woltje
864c23dc94
ci/woodpecker/push/woodpecker Pipeline failed
feat(#355): Create UserCredential model with RLS and encryption support
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>
2026-02-07 16:39:15 -06:00
..
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 20:24:41 -06:00
2026-02-03 19:17:13 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 15:27:00 -06:00
2026-02-02 15:27:00 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 12:34:24 -06:00
2026-02-03 12:55:37 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 13:30:16 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 13:45:00 -06:00
2026-02-03 14:03:44 -06:00
2026-02-03 14:18:18 -06:00
2026-02-03 14:51:59 -06:00
2026-02-03 14:51:59 -06:00
2026-01-31 11:38:38 -06:00
2026-01-31 12:10:43 -06:00
2026-01-31 12:22:14 -06:00
2026-01-31 11:57:40 -06:00
2026-02-01 17:56:04 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:22:07 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:52:43 -06:00
2026-02-01 20:56:45 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 21:01:25 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:16:23 -06:00
2026-02-01 21:26:40 -06:00
2026-02-01 21:32:53 -06:00
2026-02-01 21:42:44 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 08:18:55 -06:00
2026-02-01 21:44:04 -06:00
2026-02-01 21:54:34 -06:00
2026-02-01 20:54:25 -06:00
2026-02-01 21:09:03 -06:00
2026-02-01 20:54:57 -06:00
2026-02-02 11:41:11 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 12:51:17 -06:00
2026-02-02 12:41:12 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 12:30:19 -06:00
2026-02-02 12:03:36 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 22:29:42 -06:00
2026-02-03 22:38:13 -06:00
2026-02-03 22:44:54 -06:00
2026-02-02 12:51:17 -06:00
2026-02-02 12:55:17 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 22:55:57 -06:00
2026-02-03 22:59:41 -06:00
2026-02-03 16:50:06 -06:00
2026-02-03 18:58:00 -06:00
2026-02-03 19:53:09 -06:00
2026-02-03 20:17:47 -06:00
2026-02-03 20:21:06 -06:00
2026-02-03 20:24:46 -06:00
2026-02-03 20:27:45 -06:00
2026-02-03 20:35:00 -06:00
2026-02-03 20:47:41 -06:00
2026-02-04 03:08:09 +00:00
2026-02-04 03:08:09 +00:00
2026-02-04 03:08:09 +00:00
2026-02-03 22:48:59 -06:00
2026-02-03 22:51:25 -06:00
2026-02-07 16:39:15 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00
2026-02-02 14:33:31 -06:00
2026-02-03 21:43:01 -06:00
2026-02-03 14:37:06 -06:00
2026-02-03 14:37:06 -06:00