History

Clean up scoped OAuth credential rows

Rhys Sullivan committed 6 months ago

Commit d3f9f311 parent fca27593 files · +110 −0Browse files

Unified · Split

3 files
  1. apps/cloud/drizzle/0012_repair_openapi_secret_binding_scopes.sql +73 −0
  2. apps/cloud/drizzle/0013_cleanup_orphan_oauth_rows.sql +23 −0
  3. apps/cloud/drizzle/meta/_journal.json +14 −0
apps/cloud/drizzle/0012_repair_openapi_secret_binding_scopes.sql+73−0
@@ -0,0 +1,73 @@
1+-- Repair OpenAPI secret bindings that point at scopes without the referenced
2+-- Secret row.
3+--
4+-- Most affected rows are user-org bindings for shared org sources where the
5+-- backing Secret lives at the source/org scope. A smaller case is the inverse:
6+-- an org binding whose matching Secret is user-owned under the same org. Copy
7+-- each invalid binding to the matching in-org Secret scope, then remove any
8+-- invalid OpenAPI secret binding that still has no Secret at its own scope.
9+-- This deliberately does not copy secrets across org boundaries.
10+
11+INSERT INTO "credential_binding" (
12+ "id",
13+ "scope_id",
14+ "plugin_id",
15+ "source_id",
16+ "source_scope_id",
17+ "slot_key",
18+ "kind",
19+ "text_value",
20+ "secret_id",
21+ "connection_id",
22+ "created_at",
23+ "updated_at"
24+)
25+SELECT DISTINCT ON (s."scope_id", b."id")
26+ b."id",
27+ s."scope_id",
28+ b."plugin_id",
29+ b."source_id",
30+ b."source_scope_id",
31+ b."slot_key",
32+ b."kind",
33+ b."text_value",
34+ b."secret_id",
35+ b."connection_id",
36+ b."created_at",
37+ now()
38+FROM "credential_binding" b
39+JOIN "secret" s
40+ ON s."id" = b."secret_id"
41+ AND (
42+ s."scope_id" = b."source_scope_id"
43+ OR s."scope_id" LIKE 'user-org:%:' || b."source_scope_id"
44+ )
45+WHERE b."plugin_id" = 'openapi'
46+ AND b."kind" = 'secret'
47+ AND NOT EXISTS (
48+ SELECT 1
49+ FROM "secret" exact
50+ WHERE exact."id" = b."secret_id"
51+ AND exact."scope_id" = b."scope_id"
52+ )
53+ORDER BY s."scope_id", b."id", b."updated_at" DESC
54+ON CONFLICT ("scope_id", "id") DO UPDATE SET
55+ "plugin_id" = excluded."plugin_id",
56+ "source_id" = excluded."source_id",
57+ "source_scope_id" = excluded."source_scope_id",
58+ "slot_key" = excluded."slot_key",
59+ "kind" = excluded."kind",
60+ "text_value" = excluded."text_value",
61+ "secret_id" = excluded."secret_id",
62+ "connection_id" = excluded."connection_id",
63+ "updated_at" = excluded."updated_at";--> statement-breakpoint
64+
65+DELETE FROM "credential_binding" b
66+WHERE b."plugin_id" = 'openapi'
67+ AND b."kind" = 'secret'
68+ AND NOT EXISTS (
69+ SELECT 1
70+ FROM "secret" s
71+ WHERE s."id" = b."secret_id"
72+ AND s."scope_id" = b."scope_id"
73+ );--> statement-breakpoint
apps/cloud/drizzle/0013_cleanup_orphan_oauth_rows.sql+23−0
@@ -0,0 +1,23 @@
1+-- Remove stale OAuth rows left behind after connection cleanup.
2+--
3+-- Connection-owned Secret rows are hidden implementation details for a
4+-- Connection. If the owning Connection row no longer exists at the same scope,
5+-- the Secret row is unreachable and should not remain as dangling metadata.
6+-- Likewise, OAuth sessions for missing Connections cannot complete safely.
7+
8+DELETE FROM "secret" s
9+WHERE s."owned_by_connection_id" IS NOT NULL
10+ AND NOT EXISTS (
11+ SELECT 1
12+ FROM "connection" c
13+ WHERE c."id" = s."owned_by_connection_id"
14+ AND c."scope_id" = s."scope_id"
15+ );--> statement-breakpoint
16+
17+DELETE FROM "oauth2_session" o
18+WHERE NOT EXISTS (
19+ SELECT 1
20+ FROM "connection" c
21+ WHERE c."id" = o."connection_id"
22+ AND c."scope_id" = o."scope_id"
23+ );--> statement-breakpoint
apps/cloud/drizzle/meta/_journal.json+14−0
@@ -85,6 +85,20 @@ · 84 unmodified lines
8585 "when": 1778178300000,
8686 "tag": "0011_repair_openapi_connection_binding_scopes",
8787 "breakpoints": true
88+ },
89+ {
90+ "idx": 12,
91+ "version": "7",
92+ "when": 1778179000000,
93+ "tag": "0012_repair_openapi_secret_binding_scopes",
94+ "breakpoints": true
95+ },
96+ {
97+ "idx": 13,
98+ "version": "7",
99+ "when": 1778179800000,
100+ "tag": "0013_cleanup_orphan_oauth_rows",
101+ "breakpoints": true
88102 }
89103 ]
90104 }