Repository navigation
fix(web): scope the ChatGPT BYOK connection to one account - #6317
Conversation
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe follow-up commit resolves the actionable findings from the prior review: Files Reviewed (5 files)
Previous Review Summaries (4 snapshots, latest commit f72dd37)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit f72dd37)Status: 4 Issues Found | Recommendation: Address before merge Executive SummaryThe per-account ChatGPT connection scoping is sound, but the new Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (37 files)
Fix these issues in Kilo Cloud Previous review (commit 61a6edc)Status: No Issues Found | Recommendation: Merge Executive SummaryThe incremental commit reverts the organization-wide ChatGPT cleanup: unlinking a personal OpenAI identity now clears only the personal connection while an organization connection survives. The behavior is intentional, matches the updated code comment, and is covered by the updated tests, so no new issues were found in the changed code. Files Reviewed (4 files)
Previous review (commit 894ce46)Status: No Issues Found | Recommendation: Merge Files Reviewed (5 files)
Previous review (commit 97dbbae)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (1 file)
Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0 Review guidance: REVIEW.md from base branch |
The "Sign in with ChatGPT" connection was personal only, so an organization request used the caller's personal connection. Give each account its own connection: an organization request resolves the organization row and falls back to gateway pricing when the organization has no connection. - Store, refresh, and route the connection by owner (person or organization). - Thread the organization through the OAuth linking session. - Tag organization models from the organization connection. - Render the card on the organization BYOK page.
Unlinking OpenAI cleared only the personal connection, so an organization kept the delegated credential created from the detached identity. Clear every `openai-chatgpt` row the person created, personal and organization, and keep `created_by` current when a connection is replaced.
Unlinking the personal OpenAI identity must not delete an organization's BYOK connection. The organization connection is a separate account setting that an organization admin manages on the organization BYOK page. Clear only the personal row and keep the organization row.
The "Sign in with ChatGPT" connection is inherently personal. Store each connection in a dedicated `openai_chatgpt_connections` table keyed by `(kilo_user_id, organization_id)`, where the organization is null for the personal account. A member's connection for an organization is theirs alone: another member's connection is never used, and an account without one falls through to the API path. - Add the table and migration. - Resolve ChatGPT routing by the (member, account) pair. - Any organization member can connect or disconnect their own. - The organization BYOK page shows the card to every member; the pasted-key manager stays owner/admin only. - Unlinking OpenAI clears the personal connection only.
Members see the BYOK nav item when the flag is on and only their own ChatGPT card; the pasted-key manager stays owner/admin. The copy states the connection is the member's own for the organization. The flag still hides the option everywhere when it is off.
4dde025 to
33c202f
Compare
…ing scope - Delete `openai_chatgpt_connections` rows in `anonymizeCloudUserData`, so a soft-deleted account does not retain the credential and linked email. - Give `unlinkAuthProvider` its own input schema; it no longer advertises an `organizationId` it ignores. - Attach the organization only when the linking session targeted OpenAI, and reject an organization-scoped link for any other provider. - Regenerate the MCP catalog.
Problem
The "Sign in with ChatGPT" BYOK connection was personal only and shared everywhere. An organization request used the caller's personal connection, and the storage table allowed only one owner per row (person OR organization), so a member could not connect their own subscription to an organization.
Change
The connection is inherently personal. Each connection is keyed by
(kilo_user_id, organization_id), where the organization is null for the personal account. The same person can connect the same ChatGPT subscription to several accounts by connecting each separately.(user, null)(user, orgA)openai_chatgpt_connectionstable and migration. The sharedbyok_api_keystable is untouched.store.ts,refresh.ts, androuting.tsresolve by the(member, account)pair.openAiChatGpt.status/disconnectandlinkAuthProviderrequire organization membership only: the connection is the member's own.Verification
softDeleteUsertiming flake).localhost:7100redirect, real DB):429 subscription_sharing_usage_limit_exceeded).(user, orgA)row; the card shows connected.402), never the first member's ChatGPT connection.