Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: add chat model config RBAC resource - #27957

Merged
ethanndickson merged 2 commits into
ethan/codagt-709-model-config-migrationfrom
ethan/codagt-709-model-config-rbac
Aug 24, 2026
Merged

feat: add chat model config RBAC resource#27957
ethanndickson merged 2 commits into
ethan/codagt-709-model-config-migrationfrom
ethan/codagt-709-model-config-rbac

Conversation

@ethanndickson

@ethanndickson ethanndickson commented Aug 10, 2026

Copy link
Copy Markdown
Member

Add the chat_model_config RBAC resource, actions, and API key scopes. This layer includes the scope migration and generated API types. Model list queries apply token scopes, SQL authorization filters, and row ACLs.

Write and default-management handlers keep deployment configuration authorization until the next API layer replaces it.

Depends on #27956

This pull request description was generated by Coder Agents.

@linear-code

linear-code Bot commented Aug 10, 2026

Copy link
Copy Markdown

CODAGT-709

@github-actions

github-actions Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Docs preview

Check 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.

@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@ethanndickson

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Chat: Review posted | View chat
Requested: 2026-08-19 18:45 UTC by @ethanndickson

Review history
  • R1 (2026-08-10): 21 reviewers, 5 Nit, 2 Note, 1 P1, 5 P2, 14 P3, REQUEST_CHANGES. Review
  • R2 (2026-08-10): 12 reviewers, 6 Nit, 3 Note, 1 P1, 6 P2, 20 P3, COMMENT. Review
  • R3 (2026-08-18), 6 Nit, 3 Note, 1 P1, 6 P2, 20 P3, COMMENT. Review
  • R4 (2026-08-19), 6 Nit, 3 Note, 1 P1, 6 P2, 20 P3, COMMENT. Review

deep-review v0.9.0 | Round 4 | 038921b..6c72e7d

Last posted: Round 4, 36 findings (1 P1, 6 P2, 20 P3, 6 Nit, 3 Note), COMMENT. Review

Finding inventory

Finding inventory, PR #27957

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P3 Author fixed (ee602bd) coderd/exp_chats.go:6543 isAdmin name no longer describes branch condition after auth refactor R1 Netero Yes
CRF-2 P3 Author fixed (91eeb0b: ChatModelConfigNoOwner compile case added) coderd/rbac/regosql/configs.go:88 ChatModelConfigConverter has no compile test; ACL matchers untested at any level R1 Netero, Chopper Yes
CRF-3 P1 Author fixed (ee602bd) coderd/exp_chats.go:6543 Non-default-org admins/auditors regress from full enabled list to empty list during fallback window R1 Pariston P1, Kite P1, Hisoka P2, Mafuuu P2, Kurapika P2, Melody P2 Yes
CRF-4 P2 Author fixed (ee602bd) coderd/exp_chats.go:6551 PR description claims member read via seeded org ACL; actual mechanism is chatd subject grant, and the stated regression is overstated R1 Mafu-san P2, Pariston Note Yes
CRF-5 P3 Author fixed (ee602bd) coderd/database/dbauthz/dbauthz.go:3758 GetEnabled* family authorizes site-only object, denying the org-scoped readers this PR creates R1 Knov P3, Razor P3, Ryosuke P3, Meruem P3 Yes
CRF-6 P3 Author contested; panel closed R2 (11/11 accept) coderd/rbac/policy/policy.go:88 Resource publishes create/update/delete/share while API honors only read; granted write actions are inert R1 Ryosuke P3, Chopper Note Yes
CRF-7 P2 Author fixed (ee602bd) coderd/exp_chats_model_config_list_test.go:42 ownDisabled fixture is actually enabled; the disabled-visibility assertions prove nothing R1 Bisky P2 Yes
CRF-8 P3 Author fixed (ee602bd) coderd/exp_chats_model_config_list_test.go:24 No test pins the disclosed deployment_config:read-only demotion R1 Bisky P3 Yes
CRF-9 P3 Author fixed (ee602bd) coderd/exp_chats_test.go:4115 Custom-role fixtures seed an org role with site permissions, a shape no production path can create R1 Razor P3, Hisoka P3, Kite Note Yes
CRF-10 P2 Author fixed (ee602bd) coderd/exp_chats.go:6616 Gate comment justifies itself with a dbauthz create-in-org check that does not exist R1 Gon P2, Leorio P3 Yes
CRF-11 P2 Author fixed (ee602bd) coderd/exp_chats_test.go:4189 Test comment mis-wires causal chain: missing read grant is not why UnsetDefaultChatModelConfigs rejects R1 Gon P2 Yes
CRF-12 P2 Author fixed (ee602bd) coderd/exp_chats_test.go:4109 "M1"/"M3"/"reverted" plan shorthand in comments has no repo referent (3 locations) R1 Gon P2 Yes
CRF-13 P3 Author fixed (ee602bd) coderd/exp_chats.go:6543 Multi-org user passing gate in one org sees other orgs' disabled configs via everyone-group ACL matchers R1 Meruem P3 Yes
CRF-14 P3 Author fixed (ee602bd) coderd/exp_chats.go:6551 chatd fallback branch is the only interim site without an M3 TODO; cross-org enabled disclosure survives cutover unless tagged R1 Kurapika P3, Hisoka Note, Mafuuu Note, Meruem Note Yes
CRF-15 P3 Author fixed (ee602bd; comment documents the deferral, ACL path stays inert until CODAGT-709 M3) coderd/exp_chats.go:6543 ACL-only readers never reach the authorized list; seeded ACLs and future share grants are dead in the read path R1 Knov P3, Razor Note, Ryosuke Note Yes
CRF-16 P3 Author fixed (ee602bd) coderd/database/dbauthz/dbauthz.go:9365 Candidates read delegates to q.db.GetChatModelConfigs so its own metric label never fires R1 Knuckle P3 Yes
CRF-17 Nit Author fixed (ee602bd) coderd/database/dbauthz/dbauthz.go:3472 Bare return nil, err after prepareSQLFilter drops the (dev error) marker every sibling carries R1 Knuckle Nit Yes
CRF-18 P3 Author fixed (ee602bd) coderd/exp_chats_model_config_list_test.go:127 CustomSiteReadRole comment claims both orgs' rows admitted but test never asserts otherEnabled visible R1 Chopper P3, Kurapika Nit, Bisky Yes
CRF-19 P3 Author fixed (ee602bd) coderd/exp_chats_test.go:4205 Rollback subtests assert bare require.Error; any failure mode satisfies them R1 Chopper P3 Yes
CRF-20 P3 Author fixed (ee602bd) coderd/exp_chats_test.go:4118 One 25s context spans DB setup, server start, and three nested subtests R1 Komugi P3, Bisky Note Yes
CRF-21 Nit Author fixed (ee602bd) coderd/exp_chats_model_config_list_test.go:63 contains closure hand-rolls slices.ContainsFunc R1 Ging-Go Nit, Robin Nit Yes
CRF-22 Note Author fixed (ee602bd) coderd/exp_chats_model_config_list_test.go:39 Everyone-group seeding idiom duplicated in two files; explanation lives on one copy R1 Robin Note Yes
CRF-23 Nit Author fixed (ee602bd) coderd/database/dbauthz/dbauthz.go:9354 "Candidates" doc comment narrows contract below what the method returns (deployment-wide, unfiltered) R1 Zoro Nit Yes
CRF-24 Nit Author fixed (ee602bd) coderd/rbac/regosql/configs.go:85 Doc comment says "chat_model_configs alias"; the alias is cmc R1 Gon Nit Yes
CRF-25 Nit Author fixed (ee602bd) coderd/rbac/roles.go:479 "retain their deployment-config read parity with a site-level read" does not parse R1 Gon Nit, Leorio Nit Yes
CRF-26 P3 Author fixed (ee602bd); orig downgraded from Gon's P2 coderd/database/dbauthz/dbauthz.go:2178 Comment duplication class: four dbauthz comments duplicate their own TODO; rationale copy-pasted five times; three comments restate adjacent code or assertions R1 Gon P2, Leorio Nit Yes
CRF-27 Note Author contested; panel closed R2 (11/11 accept) coderd/database/migrations/000567_chat_model_config_scopes.up.sql:1 Five of six irreversible enum values are speculative; only read has behavior behind it R1 Pariston Note Yes
CRF-28 P3 Author fixed (91eeb0b: RBACObject method deleted) coderd/database/modelmethods.go:234 ChatModelConfig.RBACObject() has no caller anywhere in the tree R2 Netero Yes
CRF-29 P3 Author fixed (722e64a: UnsetDefaultChatModelConfigs now deployment_config:update; tests expect 403 and successful bootstrap) coderd/exp_chats_test.go:12130 Authz denial inside write tx surfaces as 500; admitted role cannot bootstrap or transition the default; test pins the 500 R2 Mafuuu P3, Leorio P3, Ryosuke P3, Chopper P3, Kite P3 Yes
CRF-30 P2 Author fixed (91eeb0b: comment now cites the org-scoped chat authorization) coderd/database/dbauthz/dbauthz.go:3696 GetDefaultChatModelConfig comment justifies actor-only check with a default-org fallback the base commit deleted R2 Leorio P2 Yes
CRF-31 P3 Author fixed (91eeb0b: stale fallback sentence removed from dbauthz anchor) coderd/database/dbauthz/dbauthz.go:6041 Anchor write-gate rationale claims configs still serve every org via default-org fallback; false after base commit; sentence duplicated at handler anchor R2 Leorio P3, Gon P2 (duplication) Yes
CRF-32 P3 Author fixed (91eeb0b: all five sites trimmed); orig downgraded from Gon's P2 coderd/database/dbauthz/dbauthz.go:3455 R2 comment additions overshoot: narrating sentences and TODO repetition at dbauthz 3455/7225, exp_chats.go 6539/6617, roles.go:479; candidates rationale lives in test not owning def R2 Gon P2 x5 + Nit Yes
CRF-33 P3 Author fixed (722e64a) coderd/exp_chats_test.go:4208 Comment "A second existing config" describes a fixture that does not exist R2 Gon P3 Yes
CRF-34 P3 Author fixed (722e64a: scope gate before DB read, chatd fallback removed) coderd/exp_chats.go:6554 Enabled-config fallback ignores token scope mask; token minted without chat_model_config:read still enumerates deployment-wide configs R2 Hisoka P3, Kurapika Note Yes
CRF-35 Nit Open, silent R3 and R4 (never threaded: body-folded in R2 and R3; comment byte-identical at head 6c72e7d) coderd/x/chatd/chatd.go:1538 chatdModelConfigLookupContext comment still says deployment-config reads; check now uses chat_model_config:read R2 Mafuuu Nit Yes
CRF-36 Note Author fixed (722e64a: comment removed in listChatModelConfigs rewrite) coderd/exp_chats.go:6543 Seeded everyone-group ACL admits disabled rows once the cutover routes members through the filter; seeded data and promised destination point at different contracts R2 Pariston Note Yes

Contested and acknowledged

CRF-6 (P3, coderd/rbac/policy/policy.go:88) - write actions published but inert

  • Finding: Resource publishes create/update/delete/share while the API honors only read; custom roles granting write actions get policy-engine yes and API 403. Proposed declaring only ActionRead until the cutover wires the writes.
  • Author defense (R2): Keeping the complete action set follows the repository pattern of declaring the full RBAC contract when a resource is introduced; the next API layer consumes create/update/delete; removing them here would create churn and desynchronize the resource from the scope migration.
  • Status: Contested, no panel decision yet.

CRF-27 (Note, coderd/database/migrations/000567_chat_model_config_scopes.up.sql:1) - five of six irreversible enum values speculative

  • Finding: Only chat_model_config:read has behavior behind it in this PR; the other five enum values are permanent residue if the cutover reshapes the action set (share has no consumer anywhere).
  • Author defense (R2): The migration must match the full resource action set including the wildcard; the next API layer consumes create/update/delete; share is part of the declared resource contract even without a share endpoint yet.
  • Status: Contested, no panel decision yet.

CRF-6 panel closure (R2, 11/11 accept)

  • All eleven evaluating reviewers (Netero advisory, Bisky, Hisoka, Mafu-san, Mafuuu, Pariston, Kurapika, Chopper, Gon, Ryosuke, Kite) accepted the defense on consequence grounds: the inert grants fail closed (policy yes, API 403), the window is bounded by ticketed CODAGT-709 M3 TODOs on every gate, and roles_test pins the admission set the cutover inherits. Ryosuke and Pariston strengthened the defense beyond the pattern claim: scopes_constants_gen.go is generated from policy.RBACPermissions and the api_key_scope enum must contain every generated scope, so declaring ActionRead only would force a second irreversible enum migration at cutover. Mafu-san noted the "repository pattern" claim itself was unverified; closure rests on the consequence argument, not the pattern argument.

CRF-27 panel closure (R2, 11/11 accept)

  • Downstream of CRF-6 via the generation chain (policy actions -> generated scopes -> enum values); one decision, not two. Consequence of residue: inert, fail-closed enum values with zero runtime effect. Pariston (original raiser) withdrew the concern. Ryosuke added that share is not structurally consumer-free: this PR ships the ACL columns, RBACObject wiring, and compiled ACL matchers that share will gate at cutover.

Cross-check notes

  • CRF-3 severity: reviewers split P1/P2. Kept at P1 (higher wins; empirically reproduced by three reviewers independently; hits built-in roles on every multi-org deployment via the UI model picker; undisclosed in PR description).
  • CRF-26 downgrade gate: keep-argument was "project one-fact-one-place rule is explicit and five drifting dbauthz copies will be edited at M3 cutover; Gon audited all 33 comments." Downgraded because the duplicated sentences make no false claim and the two comment findings with behavioral consequence (CRF-10, CRF-11) stay at P2.
  • Kurapika's Note calling the GetEnabled* scoping "correct" conflicts with CRF-5 (four reviewers at P3 with a concrete one-line fix). Kurapika argued from current callers only; CRF-5 argues from the method contract. Stronger evidence sets the floor: P3 kept.
  • CRF-2 refined by Chopper: the integration test exercises the converter's compile and org_owner path, but ACL mapping matchers remain unexercised at every level. Melody adds RBACObject() has no non-test caller; Pariston adds the ACL matcher branches are dead code until M3.

Round log

Round 1

Netero pass: 2 P3 (CRF-1, CRF-2). Panel of 21 (19 trigger-matched + 2 wildcards: Takumi, Melody). New: 1 P1, 5 P2, 12 P3, 5 Nit, 2 Note. Takumi: no findings. Reviewed against 9f6d499..6c26421.

Round 2

Churn guard: PROCEED. 25 addressed (author claims, pending panel verification), 2 contested (CRF-6, CRF-27), 0 silent. Reviewed against 483b499..ee602bd.

Round 2 panel

Panel of 12 (11 trigger-matched + wildcard Kite; Netero advisory first). All 25 addressed findings verified fixed by at least one reviewer (tests run against Postgres). CRF-2 re-raised (owner-matcher compile case missing). CRF-6 and CRF-27 closed 11/11 on author defense. New: 1 P2, 6 P3, 1 Nit, 1 Note (CRF-28 through CRF-36). Komugi: no findings. Mafu-san note: CRF-16 fix leaves emitted SQL tagged "-- name: GetChatModelConfigs" (residue only, method removed at M3, not posted as finding).

Round 3

BLOCKED by churn guard. Silent: CRF-35 (body-folded Nit, no response) and CRF-2 re-raise (no reply, owner-matcher compile case still absent at head). Author replies for CRF-28 and CRF-30 claim fixes the head contradicts (RBACObject still present; GetDefaultChatModelConfig comment byte-identical); CRF-31 and CRF-32 fixed at some sites, unchanged at the anchor sites the findings targeted. PR restructured onto stack base #27956 (migrations renumbered to 000571/000572); CI failing (test-go-pg, test-go-pg-17, test-go-race-pg, required); Codex flagged migration renumbering as upgrade-breaking. No reviewers spawned. Reviewed against d0f5fa0..722e64a.

Round 4

BLOCKED by churn guard, solely on CRF-35 (Nit, silent second consecutive round; the finding has never had a reviewable thread because its line is outside every diff). All other open findings verified fixed in 91eeb0b: CRF-2 (ChatModelConfigNoOwner compile case), CRF-28 (RBACObject deleted), CRF-30, CRF-31, CRF-32. CI green at head 6c72e7d; migration renumbering resolved (scopes migration now 000575). No reviewers spawned. Reviewed against 038921b..6c72e7d.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Chef's kiss.

Reviewed commit: 6c2642149f

ℹ️ 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".

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR gets the hard parts of the read cutover right, and the panel said so repeatedly: the GetDefaultChatModelConfigCandidates split prevents a silent no-default commit that an authorized-filter candidate list would have shipped (five reviewers traced it, and the write-window test pins the rollback semantics against real Postgres), the converter mirrors the established WorkspaceConverter shape, the migration follows the enum-add precedent, and every interim write gate carries a ticketed TODO. Takumi ran the concurrency trace and found nothing: "The timing is fine."

Severity count: 1 P1, 5 P2, 14 P3, 5 Nit, 2 Note.

The P1 is the headline: six reviewers converged independently, three with empirical probes against Postgres, on org admins and org auditors of non-default organizations regressing from the full enabled model list to an empty list for the whole fallback window, while plain members of the same org keep the full list. The PR description discloses the custom-site-role regression but not this one, and this one hits built-in roles on every multi-org deployment through the UI model picker.

Two P2s are description/comment honesty: the PR body attributes member read to the seeded org ACL when the code preserves it via the chatd subject grant, and the create-gate comment justifies itself with a dbauthz create-in-org check that does not exist in this PR. One P2 is a test fixture that silently inverts (Enabled: false is dbgen's zero value), turning the centerpiece disabled-visibility assertions into no-ops.

Process observations: CI shows "Pixel / Review" failing on this head. The only frontend changes are generated files, so the diff is an unlikely cause, but a failing check is not "pre-existing"; resolve it or state why it is out of scope before merge. Separately, Gon audited all 33 new comments and found a pattern: several were written for the PR's development narrative (plan milestones, revert history) rather than for the next reader of the file; the individual findings are inline.

Fun quote, from Hisoka: "I pulled the isAdmin thread and something on the other end moved. Shall I show you?"


coderd/exp_chats.go:6551

P2 [CRF-4] The PR description justifies the accepted regression with a mechanism the code does not implement: "members read through the org ACL seeded in the schema PR." (Mafu-san P2, Pariston Note)

Mafu-san traced every member-subject read path: "The list handler routes non-admins to GetEnabledChatModelConfigs(dbauthz.AsChatd(ctx)), so members read because the chatd service subject gained site-level chat_model_config:read (dbauthz.go:795), not through any ACL." ChatModelConfig.RBACObject() has zero non-test callers, and an ACL-only grantee can never reach the SQL filter because the AnyOrganization gate evaluates a bare object with empty ACL lists.

Consequence: the human accepting the tradeoff is told member read is preserved by the seeded ACL. If M3 removes or narrows the chatd grant on that assumption, member read breaks silently. Pariston adds the regression itself is overstated: custom deployment_config:read roles fall to the else branch and still see every enabled config; what they lose is the management view (disabled rows), not "the model list."

Fix: correct the PR description to name the chatd-subject path as the member read mechanism and to scope the stated loss to the management view.

🤖

coderd/exp_chats.go:6551

P3 [CRF-14] The non-admin branch is the only interim authorization site in this PR without a cutover TODO. (Kurapika P3; Hisoka, Mafuuu, Meruem Notes)

Kurapika: "Every authenticated user of any org therefore enumerates every org's enabled configs (model names, provider IDs, context limits, reasoning options), and the org ACLs the schema PR seeded decide nothing on this path. ... After the M3 cutover, when configs are per-org, this branch becomes a standing cross-org disclosure unless someone remembers to scope it. Every other interim decision in this PR carries TODO(mafredri): ... after CODAGT-709 M3; this branch carries only a nolint:gocritic comment."

Three other reviewers flagged the same asymmetry: org-scoped readers are SQL-filtered to their orgs while every plain member sees all orgs' enabled configs. Fine during the window; untagged interim behavior is the kind that survives its window. Add the M3 TODO stating the branch must switch to an org-scoped query at cutover.

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread coderd/exp_chats.go Outdated
Comment thread coderd/exp_chats.go Outdated
Comment thread coderd/exp_chats.go Outdated
Comment thread coderd/exp_chats.go Outdated
Comment thread coderd/rbac/regosql/configs.go
Comment thread coderd/database/dbauthz/dbauthz.go Outdated
Comment thread coderd/rbac/regosql/configs.go Outdated
Comment thread coderd/rbac/roles.go Outdated
Comment thread coderd/database/dbauthz/dbauthz.go Outdated
Comment thread coderd/database/migrations/000581_chat_model_config_scopes.up.sql
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from 6c26421 to 2026b3f Compare August 10, 2026 06:57
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from 2026b3f to ee602bd Compare August 10, 2026 10:43
@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@ethanndickson

Copy link
Copy Markdown
Member Author

/coder-agents-review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: ee602bd6e4

ℹ️ 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".

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 2 is what a fix round should look like. All 25 addressed findings were verified against the code by the panel, most by running the tests against Postgres: the P1 access regression is gone (site-scoped gate, non-default-org roles pinned by new test cases), the fixture actually disables what it claims, the custom-role fixtures use a shape production can hold, and the comment surgery from round 1 landed. Mafu-san's process read: corrections were generalized, not spot-patched (the bare require.Error became a shared helper across all three rollback subtests; the fixture fix came with enabled-flag pins on all three fixtures).

Both contested findings are closed on the author's defense, 11/11. CRF-6 (write actions published but inert): fail-closed, ticketed window, and the panel found the defense stronger than stated: the scope constants are generated from the policy action set and the enum must match, so trimming to read-only would force a second irreversible enum migration at cutover. CRF-27 inherits that decision through the same generation chain; Pariston, its raiser, withdrew it. Related observation from Ryosuke, recorded for the M3 checklist rather than re-raised: the org auditor's new read grant also has no consuming path until cutover, same forward-declaration class.

New this round: 1 P2, 6 P3, 1 Nit, 1 Note, plus one re-raise. The P2 and one P3 are the same disease CRF-10 had, in new locations: authorization comments justifying checks with a "default-org fallback" serving mechanism that this PR's own base commit (483b499) deleted. The largest convergence (five reviewers) is the 500-for-authz-denial contract that the new test helper now pins. The re-raise: the converter compile tests cover four of five matchers; the owner matcher (AlwaysFalse) has no case.

Small residue, not findings: the CRF-16 fix makes the Prometheus label fire, but the emitted SQL still carries "-- name: GetChatModelConfigs", so slow-query-log correlation attributes candidates traffic to the wrong name; the whole method is TODO-tagged for M3 removal. Leorio also notes the fix commit body is empty for a 289/235-line change treating 25 findings; the PR description carries the durable record, so Note weight only.

Fun quote, from Hisoka: "I came back for a rematch and the author rebuilt the arena."


coderd/x/chatd/chatd.go:1538

Nit [CRF-35] The chatdModelConfigLookupContext comment still says the elevation exists for "daemon-scoped deployment-config reads," but this PR changed GetEnabledChatModelConfigByID to authorize chat_model_config:read. (Mafuuu)

"Outside the diff, but the diff falsified it: dbauthz.go:3740 now checks rbac.ResourceChatModelConfig, and the chatd subject's matching grant is the new chat_model_config:read at dbauthz.go:795, not its deployment-config read. Stale permission comments are exactly the drift class CRF-12/CRF-26 cleaned up elsewhere in this PR."

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread coderd/database/modelmethods.go Outdated
Comment thread coderd/exp_chats_test.go Outdated
Comment thread coderd/database/dbauthz/dbauthz.go Outdated
Comment thread coderd/database/dbauthz/dbauthz.go Outdated
Comment thread coderd/database/dbauthz/dbauthz.go Outdated
Comment thread coderd/exp_chats_test.go Outdated
Comment thread coderd/exp_chats.go Outdated
Comment thread coderd/exp_chats.go Outdated
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from ee602bd to 3adca40 Compare August 10, 2026 13:33
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch 3 times, most recently from f395ff2 to a04ca61 Compare August 11, 2026 00:14
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from a04ca61 to 7131db5 Compare August 11, 2026 13:18
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from 7131db5 to c440fe0 Compare August 17, 2026 13:25
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from c440fe0 to 45729fd Compare August 18, 2026 06:53
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Another round soon, please!

Reviewed commit: 6c72e7d184

ℹ️ 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".

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Round 4 is blocked on a single finding, and it is the last open item on this PR.

Everything else from rounds 1 through 3 is now verified fixed at head 6c72e7d (commit 91eeb0b): the CRF-2 re-raise (the ChatModelConfigNoOwner compile case landed, exactly the one table row asked for), CRF-28 (ChatModelConfig.RBACObject() deleted), CRF-30 (the GetDefaultChatModelConfig comment now cites the real safety argument, the org-scoped chat authorization), CRF-31 (the stale fallback sentence is gone from the dbauthz anchor), and CRF-32 (all five comment sites trimmed). CI is green and the migration renumbering concern is resolved (the scopes migration now takes a fresh number, 000575).

The one open finding, silent for two consecutive rounds:

[CRF-35] (Nit) chatdModelConfigLookupContext at coderd/x/chatd/chatd.go:1596-1599: the nolint comment still says "Chat message admission needs daemon-scoped deployment-config reads for model config validation." The check it feeds (GetEnabledChatModelConfigByID, dbauthz.go:3750) has authorized chat_model_config:read since round 2, and the chatd subject's matching grant is chat_model_config:read, not its deployment-config read. Concrete fix, a one-line comment edit: "Chat message admission needs daemon-scoped chat_model_config reads for model config validation."

To be fair about why this keeps slipping: the line sits outside every diff in this PR, so the finding has been folded into review bodies since round 2 and has never appeared as a reviewable thread. It still needs one of: the one-line fix above, a filed ticket, or a stated reason it should not change. A bare pass-over cannot close it.

Per the review process, no panel runs on a blocked round. Respond to or fix CRF-35 and the next round proceeds to a normal panel review.

🤖 This review was automatically generated with Coder Agents.

@ethanndickson
ethanndickson marked this pull request as ready for review August 20, 2026 10:33

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6c72e7d184

ℹ️ 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".

Comment thread coderd/exp_chats.go
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from 6c72e7d to e022ab1 Compare August 20, 2026 12:03
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from e022ab1 to b6656a4 Compare August 21, 2026 18:24
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from b6656a4 to 58e4333 Compare August 21, 2026 18:50
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from 58e4333 to 771557b Compare August 21, 2026 19:11
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from 771557b to fe8c02b Compare August 23, 2026 10:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe8c02b8f8

ℹ️ 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".

Comment thread coderd/exp_chats.go
Comment on lines +6967 to +6968
return scopes.Has(database.ApiKeyScopeCoderAll) ||
scopes.Has(database.ApiKeyScopeChatModelConfigRead)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Honor wildcard model-config scopes

When an internally minted or restored API key carries the valid chat_model_config:* scope, this exact-membership check returns false and the list endpoint responds with 403, even though RBAC expands that wildcard to include read. Include ApiKeyScopeChatModelConfig here, or use the scope-only RBAC authorization pattern used by the MCP config endpoint so wildcard and future covering scopes retain their documented semantics.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: fe8c02b8f8

ℹ️ 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".

@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from fe8c02b to d945749 Compare August 24, 2026 09:04
@ethanndickson
ethanndickson force-pushed the ethan/codagt-709-model-config-rbac branch from d945749 to 618f3f9 Compare August 24, 2026 09:30
@ethanndickson
ethanndickson merged commit cbe24a3 into main Aug 24, 2026
31 of 52 checks passed
@ethanndickson
ethanndickson deleted the ethan/codagt-709-model-config-rbac branch August 24, 2026 09:43
nothingtosurprise pushed a commit to nothingtosurprise/coder that referenced this pull request Aug 24, 2026
Rename the admin-managed SDK resource from `ChatModelConfig` to
`ChatModel`. Rename catalog entries from `ChatModel` to
`ChatModelCatalogEntry` and replace `ChatModelsResponse` with
`ChatModelAvailabilityResponse`.

API routes and JSON fields do not change. Experimental SDK and OpenAPI
schema names do change.

Depends on coder#27957

_This pull request description was generated by Coder Agents._
aslilac pushed a commit that referenced this pull request Aug 24, 2026
Add the `chat_model_config` RBAC resource, actions, and API key scopes.
This layer includes the scope migration and generated API types. Model
list queries apply token scopes, SQL authorization filters, and row
ACLs.

Write and default-management handlers keep deployment configuration
authorization until the next API layer replaces it.

Depends on #27956

_This pull request description was generated by Coder Agents._
aslilac pushed a commit that referenced this pull request Aug 24, 2026
Rename the admin-managed SDK resource from `ChatModelConfig` to
`ChatModel`. Rename catalog entries from `ChatModel` to
`ChatModelCatalogEntry` and replace `ChatModelsResponse` with
`ChatModelAvailabilityResponse`.

API routes and JSON fields do not change. Experimental SDK and OpenAPI
schema names do change.

Depends on #27957

_This pull request description was generated by Coder Agents._
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants