Skip to content

🤖 feat: write a cleanup record before each CoderAIGatewayKey create (#353 part 2c) - #385

Merged
ThomasK33 merged 1 commit into
mainfrom
feat/ai-gateway-key-cleanup-records
Oct 14, 2026
Merged

ThomasK33 merged 1 commit into
mainfrom
feat/ai-gateway-key-cleanup-records

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Refs #353 (part 2c: the CoderAIGatewayKey half of option B′, records). Refs #156.

Summary

Before each AI Gateway key create, the operator now writes a cleanup record for the CoderAIGatewayKey object: a ConfigMap ck8s-cleanup-<object UID> in the operator namespace, the same kind of record that #374 added for CoderAIProvider. If the record cannot be written, no key is created. The delete path removes the record only after a LIST in the record's Coder deployment shows no key of the object. In every other release without a delete (for example a namespace deletion), the record stays. The sweep that uses it follows in the stacked PR (part 2d).

Design note (option B′, maintainer decision #353 (comment))

How each invariant maps to keys:

  1. Record before create. issueKey writes the record after the Secret claim and dry run, and before the create marker (pendingKey, nextSerial). A failed deployment ID read is a CoderUnavailable wait. A failed write is an error. Either way no POST is sent and no marker is written.
  2. No secrets. Kind, UID, namespace, name, deployment ID, the key name prefix ck8s-<UID without dashes>- (in the nonce field), the time of the last create, and the current key ID. The test helper reconcileErr now also checks the record for every key plaintext, in every key test.
  3. Deployment ID from Coder (/api/v2/buildinfo), read in the reconcile that sends the create. When a record already names another deployment, the create step stalls with CoderDeploymentChanged and creates nothing in the new deployment (same rule as providers).
    4.–6. Sweep rules: next PR.
  4. The record goes only after Coder confirms. It goes at the end of a normal delete (a LIST shows no key of the object). It also goes after the one bounded pass, but only when the last create was more than 5 minutes (the settle window) before it, so no create can still commit after that LIST. Before any delete pass, the operator checks that the control plane still reaches the recorded deployment. If it does not, the finalizer goes without a delete and the record stays. An object with nextSerial == 0 sent no create, so its record (left by a failed marker write) goes with no Coder call.
    8.–9. Same Role and namespace as 🤖 feat: write a cleanup record before each CoderAIProvider create (#353 part 2a) #374. No RBAC change.

Key-specific choices:

  • One record per object, many keys. A key object creates a new key at every rotation and drift re-issue. The prefix finds all of them, so the record stores only the current key ID, for admins. The ID is written right after a successful issue, with no extra Coder call. If that write fails, the next reconcile that sees the key listed writes it (recordAIGatewayKeyID). The same path also gives a record to an object from before records existed.
  • The record's create time is the marker's instant. One attemptStart stamps the record, lastCreateAttemptTime and the Secret write-age limit, so the sweep's settle window covers every create.

Also in this PR: #384 follow-up 4 for keys (#353 (comment), item 4). A delete pass under the control plane hold now ends at the hold end (context.WithDeadline), and its retry counts from the end of the pass, as #384 did for CoderMCPServer.

Validation

  • New tests: TestCoderAIGatewayKeyCleanupRecord, TestCoderAIGatewayKeyNoCreateWithoutRecord, TestCoderAIGatewayKeyDeploymentChanged, TestCoderAIGatewayKeyRecordAfterBoundedPass, TestCoderAIGatewayKeyRecordWithoutCreate, TestCoderAIGatewayKeyRecordBackfill, and TestAIGatewayKeyDeleteUnderHoldEndsAtHoldEnd.
  • Red then green: 11 mutations, each caught by a test: no record before the create, no deployment-change check, no deployment check on delete, the bounded pass always or never removing the record, a serial-0 delete keeping the record, a release keeping the record, no issued ID, no backfill, no hold deadline, and the requeue counted from the start of the pass.
  • Local gates: build-installer, codegen, docs-reference, drift, verify-vendor, build, lint, govulncheck, test, test-integration, race (./internal/controller/...), docs-check, actionlint. All passed.
  • Kind dogfood with a licensed Coder runs on the stacked PR (part 2d), because the sweep is needed for the namespace deletion scenario.

Risks

  • The key create path sends one more Coder request (GET /api/v2/buildinfo) per create. A failure of that read blocks the create with a 60 s retry, as for providers.
  • Each reconcile with a listed current key does one live ConfigMap GET in the operator namespace. Writes happen only when the ID changed.

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

… part 2c)

Change-Id: I6c7f7e46475e8077e1e05bace6651255696f5782
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-14T21:51:40.664166Z 0bb1e03 PR opened
🔒 Security Review ✅ Completed 2026-10-14T21:55:07.567066Z 0bb1e03 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: 0bb1e03bf7

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 aab11e7 Oct 14, 2026
13 checks passed
@ThomasK33
ThomasK33 deleted the feat/ai-gateway-key-cleanup-records branch October 14, 2026 22:41
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.

1 participant