Skip to content

🤖 fix: require https for Coder's revocation URL in the CoderMCPServer consent check, and test the consent disable marker - #363

Merged
ThomasK33 merged 8 commits into
mainfrom
mcp-revocation-https
Oct 14, 2026
Merged

ThomasK33 merged 8 commits into
mainfrom
mcp-revocation-https

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Summary

The dormant CoderMCPServer consent check now requires https for the OAuth2 revocation URL that Coder holds, as the spec does. This PR also adds the consent-path tests for the disable marker that #360 introduced. The kind is not registered, so users see no change.

Base branch: main. #360 landed as 69c18dd5. I merged main into this branch with a merge commit, and the diff against main is the reviewed M6f change only.

Fixes #311
Fixes #334

Background

Implementation

  • mcpServerConsentHolds returns false when Coder's revocation URL is not https (4 lines), so the config is disabled.
  • New tests in internal/controller/codermcpserver_marker_test.go.

Validation

Size

158 lines added, all hand-written: 4 in codermcpserver_disable.go and 154 in the new tests.

Refs #155


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $171.92

…draws its opt-in

When spec.mcpServers is removed, no longer lists the organization, or no
longer allows force_on for a force_on server, the controller now
disables a config that the object created, with one PATCH that holds
only enabled: false. It reads no credential. The disable is a kill
switch, so a restored opt-in needs a spec edit to enable the config. The
read and the PATCH are shared with the consent disable.

Fixes #336
Refs #155

Change-Id: Iebea23e388d9c43540daebf8380f256c59f282cf
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…lookup and resync MCPServersNotAllowed

The organization lookup treated any 404 as a missing organization. A
proxy page or "Route not found." for a listed name then skipped that
name, so the scope check stalled with MCPServersNotAllowed, which had no
timed requeue. The lookup now uses isCoderResourceNotFound, so another
404 waits with CoderUnavailable, and MCPServersNotAllowed resyncs every
10 minutes. The fake answers an unknown organization like Coder.

Fixes #358
Refs #155

Change-Id: I90fa60c56e9f867d4c7c53bce35c1be49be366a8
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…it the opt-in disable to opt-in stalls, and document it

- A read that finds the config already disabled now records the
  generation, so a lost disable answer and a restored opt-in do not apply
  a pending generation that enables the config.
- Only MCPServersNotAllowed and ForceOnNotAllowed run the opt-in disable.
  Another stall of the scope check, such as a mismatched Coder answer,
  keeps the config.
- The spec.mcpServers field docs describe the fail-closed disable.

Refs #155

Change-Id: If9ea006bcd30e178dc579172f03ddce31b0b3923
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: Ib67e349731c2986ff930b25276e6ba3ed6671b2c
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…isable through the pinned organization

- The opt-in and consent disables write appliedGeneration to status
  before the disable PATCH, and a failed status write sends no PATCH.
  A lost disable answer followed by a restored opt-in then gives
  DisabledExternally instead of applying a pending generation.
- When the organization name no longer resolves (OrganizationNotFound)
  or resolves to another ID (OrganizationChanged), a withdrawn opt-in
  still disables the config through the pinned organization ID.

Refs #155

Change-Id: Ie54facd7656489a5436d639734912e3c5c26050b
Signed-off-by: Thomas Kosiewski <tk@coder.com>
… and document appliedGeneration

- A fail-closed disable that finds the config gone (Coder's own 404)
  now records the generation, so a restored opt-in or consent gives
  DeletedExternally instead of creating an enabled config before a
  spec edit.
- The status.appliedGeneration doc now says that a kill switch also
  sets it, before the disable is sent. The dormant CRD is regenerated.

Refs #155

Change-Id: I781f44dfea54d7834faf712e75d4fe764f65323f
Signed-off-by: Thomas Kosiewski <tk@coder.com>
… consent check, and test the consent disable marker

- The consent check now requires https for the OAuth2 revocation URL
  that Coder holds, as the spec does. Coder accepts an http loopback
  revocation URL, so a Secret that lists that origin still does not
  prove consent for it.
- Tests for the consent path of the disable marker: a lost disable
  answer followed by restored consent, a failed marker write, and a
  config found disabled with a pending generation.

Fixes #311
Fixes #334
Refs #155

Change-Id: I15caebdca4e137372ad3171e0f9007b207703413
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T14:08:43.327320Z 24726ca Manual request
🔒 Security Review ✅ Completed 2026-10-14T14:08:52.528669Z 24726ca Manual request
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 32151aeff9

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Base automatically changed from mcp-optin-disable to main October 14, 2026 13:59
Change-Id: I557c4ff360028d952dec024ab0e4338e1fc32d20
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. You're on a roll.

Reviewed commit: 24726ca29c

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

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 24726ca29c

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@ThomasK33
ThomasK33 added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit 3aedefb Oct 14, 2026
10 checks passed
@ThomasK33
ThomasK33 deleted the mcp-revocation-https branch October 14, 2026 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant