feat!: enforce organization scope for chat models - #27959
Conversation
Docs previewCheck off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here. |
be2b1b4 to
e9f0c68
Compare
cb9032f to
fa3900e
Compare
fa3900e to
a4849d6
Compare
a4849d6 to
ffd1ca8
Compare
ffd1ca8 to
38c6051
Compare
38c6051 to
bb85dce
Compare
bb5a1f0 to
33b2e62
Compare
33b2e62 to
1c366f3
Compare
|
@codex review |
|
/coder-agents-review |
|
Chat: Review posted | View chat Review history
deep-review v0.9.0 | Round 1 | Last posted: Round 1, 11 findings (4 P0, 1 P1, 4 P2, 1 P3, 1 Nit), COMMENT. Review Finding inventoryFinding inventoryLaw analysis
Findings
Round logRound 1Netero-only + Law triage. 4 P0, 1 P1, 4 P2, 1 P3, 1 Nit. Law verdict "Don't split" (advisory). Reviewed against 359b944..1c366f3. About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
55a51e6 to
5ebba21
Compare
9b754be to
2362273
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1db74cd8dc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
1db74cd to
757d0ee
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 757d0eee51
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| userID uuid.UUID, | ||
| ) ([]codersdk.ChatModelProviderDescriptor, error) { | ||
| //nolint:gocritic // Fixed redacted projection under the model read gate; see function doc. | ||
| providers, err := api.Database.GetAIProviders(dbauthz.AsChatd(ctx), database.GetAIProvidersParams{}) |
There was a problem hiding this comment.
Include disabled providers in model descriptors
When an AI provider is disabled while its model configs remain live, GetChatModelConfigs still returns those configs but this zero-valued query excludes the disabled provider. The organization collection therefore returns models whose ai_provider_id has no matching descriptor, so authoring clients cannot resolve the provider metadata and the descriptor's enabled field can never report false. Request disabled providers here, as the administrative provider listing does, while continuing to exclude deleted providers.
Useful? React with 👍 / 👎.
| turnStartReadyWaitGroup.Add(1) | ||
| } | ||
|
|
||
| modelID, err := modelForOrg(targetWorkspace.OrganizationID) |
There was a problem hiding this comment.
Cache scaletest model IDs per organization
When a scale test creates multiple chats for the same workspace or organization, this call runs once per chat inside both loops, and each invocation performs a synchronous ChatModels request before the harness starts. Large --chats-per-workspace runs consequently issue hundreds or thousands of identical serial bootstrap requests, substantially delaying or stalling the load test itself. Resolve each organization's model once and reuse the ID for all of its runners.
Useful? React with 👍 / 👎.
|
@codex review re: Allow create-only tokens to resolve the organization This is working as intended after this revision. We deliberately aligned the chat model routes with every other organization-scoped resource: they now use the generic re: Keep default election within delete authorization Working as intended. Post-delete default election updates a different config, so deleting the current default legitimately requires |
757d0ee to
31c6bca
Compare
31c6bca to
5410e66
Compare
…caletest chat model lookups
5410e66 to
cc1b5b4
Compare

Summary
Move chat model management and runtime availability to organization-scoped API routes. The API now identifies the organization in every model-management operation, applies chat model RBAC and ACLs within that organization, and returns only models the caller can use there.
Depends on #27958.
Problem
Chat model configurations now belong to organizations, but the existing experimental management and discovery APIs are deployment-shaped. Their routes do not identify an organization, SDK methods do not accept an organization ID, and item operations address a model configuration by ID alone.
That contract cannot safely expose organization-owned model configurations. It also does not provide the organization-specific provider information, authorization behavior, ACL management, or recovery guidance needed by the settings and chat clients later in the stack.
Fix
Add organization-scoped chat model endpoints under:
The new API provides:
Historical chats can retain a model reference owned by another organization, but runtime selection uses an authorized local default when one is available. Foreign, inaccessible, disabled, and otherwise unusable models are not exposed as usable selections for the organization.
The existing collection and availability routes remain as default-organization compatibility endpoints in this layer:
These compatibility routes do not provide access to models in non-default organizations. The previous unscoped item update and delete routes are removed because item operations must include the owning organization.
Breaking change
This changes the experimental HTTP API and Go SDK contracts for chat model management.
Clients must migrate model-management and availability requests to the organization-scoped routes and provide an organization identifier. In the Go SDK, the following methods now require an organization ID:
ChatModelAvailabilityChatModelsCreateChatModelUpdateChatModelDeleteChatModelChatModelsalso changes its return value from[]ChatModeltoOrganizationChatModelsResponse, which includes the organization models and the redacted provider descriptors required by management clients. New item and ACL methods likewise require both the organization ID and model ID.The default-organization compatibility routes reduce the immediate impact for collection and availability callers, but they do not preserve the previous item API or SDK method signatures. Generated clients and direct consumers of the experimental API must be updated before adopting this change.
This pull request description was generated by Coder Agents.