Skip to content

Add package approvals to connect secret - #311

Merged
kentcdodds merged 3 commits into
mainfrom
cursor/connect-secret-approved-packages-f10b
May 1, 2026
Merged

kentcdodds merged 3 commits into
mainfrom
cursor/connect-secret-approved-packages-f10b

Conversation

@kentcdodds

@kentcdodds kentcdodds commented May 1, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add allowedPackages parsing, editing, review, and save support to /connect/secret.
  • Persist package approvals through generated UI secret metadata and connector binding metadata.
  • Treat an explicitly provided empty allowedPackages array as a clear operation for connector bindings.
  • Document the new query parameter and cover it in focused handler and E2E tests.
  • Mirror package approval normalization in handler tests so whitespace and duplicate ids are covered.

Walkthrough

connect-secret-package-approval.webm

Testing

  • npx oxfmt --check packages/worker/src/app/handlers/connect-secret.ts packages/worker/client/routes/connect-secret.tsx packages/worker/client/routes/secret-editor-fields.tsx packages/worker/client/routes/secret-normalization.ts packages/worker/src/mcp/generated-ui-api.ts packages/worker/src/app/handlers/connect-secret.node.test.ts e2e/connect-secret.spec.ts docs/guides/connect-secret.md
  • npx vitest run packages/worker/src/app/handlers/connect-secret.node.test.ts
  • npm run typecheck
  • npm run test:e2e:run -- connect-secret.spec.ts
  • npm run lint
  • npx oxfmt --check packages/worker/src/app/handlers/connect-secret.ts packages/worker/src/app/handlers/connect-secret.node.test.ts
  • npx oxfmt --check packages/worker/src/app/handlers/connect-secret.node.test.ts
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Add package-based access control for secrets with UI to add/remove allowed packages and review "Packages to approve".
  • Documentation

    • Updated guide to document the optional allowedPackages parameter and package approval flow.
  • API

    • Secrets responses now include allowed packages so saved secrets reflect package allowlists.
  • Tests

    • New e2e and unit tests covering allowed-packages behavior and persistence.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented May 1, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds support for package-scoped secret allowlisting via an allowedPackages query/body field across docs, E2E tests, client route/UI, normalization helper, server handler persistence, generated API, and handler tests.

Changes

Cohort / File(s) Summary
Docs & Tests
docs/guides/connect-secret.md, e2e/connect-secret.spec.ts
Documented allowedPackages query param; added E2E assertions for package initialization, review UI, and persistence after save.
Client route & state
packages/worker/client/routes/connect-secret.tsx
Parse allowedPackages query param, add state/normalization, include allowedPackages in create/update POST payloads, and hydrate from existing secrets.
Client UI fields
packages/worker/client/routes/secret-editor-fields.tsx
Extended SecretEditorFieldsProps with optional allowedPackages and handlers; added conditional "Allowed packages" grid, add/update/remove controls.
Normalization helper
packages/worker/client/routes/secret-normalization.ts
Added exported normalizeAllowedPackages to trim, dedupe, filter empties, and sort package IDs.
Server handler & tests
packages/worker/src/app/handlers/connect-secret.ts, packages/worker/src/app/handlers/connect-secret.node.test.ts
Accept and normalize allowedPackages in POST, persist via setSecretAllowedPackages, include allowedPackages in stored connector bindings; updated tests/mocks and added empty-array case.
Generated UI API
packages/worker/src/mcp/generated-ui-api.ts
Expose allowed_packages in secrets responses for list and create endpoints.

Sequence Diagram(s)

sequenceDiagram
  participant Browser as Browser (UI)
  participant Route as ConnectSecretRoute (Client)
  participant Server as Connect-Secret Handler (Server)
  participant MCP as MCP Secrets Service
  participant Store as Secret Storage

  Browser->>Route: open /connect/secret?allowedPackages=pkgA,pkgB
  Route->>Route: normalizeAllowedPackages([...]) 
  Route->>Server: POST create/update secret with allowedPackages
  Server->>MCP: setSecretAllowedPackages(secretName, normalizedAllowedPackages)
  MCP->>Store: persist allowed_packages with secret
  Store-->>MCP: confirm persisted
  MCP-->>Server: success
  Server-->>Route: API response with allowed_packages
  Route-->>Browser: render review UI showing Packages to approve
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #110: Previously added editable defaults flow for allowed_* constraints; shares connect-secret route, UI, and handler patterns relevant to allowedPackages.
  • PR #267: Earlier work on allowed_packages secret plumbing and approvals—overlaps server/client persistence and normalization.
  • PR #86: Introduced the original connect-secret route and baseline logic that this change extends.

Poem

🐇 I hopped through code and left a trace,
Packages lined up in tidy place,
From query to store they take a leap,
Secrets snug where approvals keep,
A rabbit nods—these changes are neat!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 11.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add package approvals to connect secret' clearly and specifically summarizes the main change: implementing package approval functionality in the connect-secret workflow. It is directly related to the primary changeset which adds allowedPackages support across documentation, E2E tests, handlers, and UI components.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/connect-secret-approved-packages-f10b

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@kentcdodds
kentcdodds marked this pull request as ready for review May 1, 2026 17:40
@github-actions

github-actions Bot commented May 1, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-311.kentcdodds.workers.dev

Worker: kody-pr-311
D1: kody-pr-311-db
KV: kody-pr-311-oauth-kv

Mocks:

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/worker/client/routes/connect-secret.tsx (1)

266-279: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Treat an empty package list as an explicit clear here.

Users can now remove every package row in the editor, but this fallback preserves the old connector binding whenever the normalized list is empty. That makes the saved connector metadata diverge from the reviewed form state.

♻️ Suggested fix
-					const allowedPackages =
-						normalizedAllowedPackages.length > 0
-							? normalizedAllowedPackages
-							: resolved.allowedPackages
+					const allowedPackages = Object.hasOwn(body, 'allowedPackages')
+						? normalizedAllowedPackages
+						: resolved.allowedPackages
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/worker/client/routes/connect-secret.tsx` around lines 266 - 279, The
POST body currently omits allowedPackages which causes an empty editor list to
fall back to the old connector binding; update the fetch body in
connect-secret.tsx so it always sends the normalized package list (e.g. add
allowedPackages: params.allowedPackages ?? [] to the JSON body) so an explicit
empty array clears bindings when users remove all packages.
packages/worker/src/app/handlers/connect-secret.ts (1)

258-279: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve an explicit empty package list when updating connector metadata.

The new UI lets users remove every package row, but this fallback reuses the previously stored packages whenever the normalized list is empty. That means the review screen can show “None” while the connector binding still keeps the old package list.

♻️ Suggested fix
-					const allowedPackages =
-						normalizedAllowedPackages.length > 0
-							? normalizedAllowedPackages
-							: resolved.allowedPackages
+					const allowedPackages = Object.hasOwn(body, 'allowedPackages')
+						? normalizedAllowedPackages
+						: resolved.allowedPackages
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/worker/src/app/handlers/connect-secret.ts` around lines 258 - 279,
The code currently falls back to resolved.allowedPackages whenever
normalizedAllowedPackages.length === 0, which overwrites an intentional "clear
all" action; update the allowedPackages assignment to treat an explicitly
provided empty array as a valid value (i.e., check for undefined/null rather
than length). Concretely, in the block that builds allowedPackages (and only
that variable), replace the ternary using normalizedAllowedPackages.length > 0
with a check like normalizedAllowedPackages !== undefined (or
normalizedAllowedPackages != null) so that an empty array from the UI is
preserved when calling saveValue for
buildConnectSecretConnectorBindingValueName(connector).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@packages/worker/client/routes/connect-secret.tsx`:
- Around line 266-279: The POST body currently omits allowedPackages which
causes an empty editor list to fall back to the old connector binding; update
the fetch body in connect-secret.tsx so it always sends the normalized package
list (e.g. add allowedPackages: params.allowedPackages ?? [] to the JSON body)
so an explicit empty array clears bindings when users remove all packages.

In `@packages/worker/src/app/handlers/connect-secret.ts`:
- Around line 258-279: The code currently falls back to resolved.allowedPackages
whenever normalizedAllowedPackages.length === 0, which overwrites an intentional
"clear all" action; update the allowedPackages assignment to treat an explicitly
provided empty array as a valid value (i.e., check for undefined/null rather
than length). Concretely, in the block that builds allowedPackages (and only
that variable), replace the ternary using normalizedAllowedPackages.length > 0
with a check like normalizedAllowedPackages !== undefined (or
normalizedAllowedPackages != null) so that an empty array from the UI is
preserved when calling saveValue for
buildConnectSecretConnectorBindingValueName(connector).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 55c99b16-b426-4a37-aa72-aeedda3384eb

📥 Commits

Reviewing files that changed from the base of the PR and between c9ed3b4 and b7d0bab.

📒 Files selected for processing (8)
  • docs/guides/connect-secret.md
  • e2e/connect-secret.spec.ts
  • packages/worker/client/routes/connect-secret.tsx
  • packages/worker/client/routes/secret-editor-fields.tsx
  • packages/worker/client/routes/secret-normalization.ts
  • packages/worker/src/app/handlers/connect-secret.node.test.ts
  • packages/worker/src/app/handlers/connect-secret.ts
  • packages/worker/src/mcp/generated-ui-api.ts

@cursor cursor 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.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b7d0bab. Configure here.

Comment thread packages/worker/src/app/handlers/connect-secret.node.test.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
packages/worker/src/app/handlers/connect-secret.node.test.ts (1)

121-123: ⚡ Quick win

Use the real package normalization behavior in this test setup.

The current mock returns the input unchanged, so these handler tests won’t catch regressions in trimming, deduping, or sorting allowedPackages. Add a case with whitespace or duplicate package names, or mirror the real normalizer here.

♻️ Proposed fix
 vi.mock('#mcp/secrets/allowed-packages.ts', () => ({
-	normalizeAllowedPackages: (packages: Array<string>) => packages,
+	normalizeAllowedPackages: (packages: Array<string>) =>
+		Array.from(
+			new Set(
+				packages.map((value) => value.trim()).filter((value) => value.length > 0),
+			),
+		).sort((left, right) => left.localeCompare(right)),
 }))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/worker/src/app/handlers/connect-secret.node.test.ts` around lines
121 - 123, The test currently mocks normalizeAllowedPackages to return inputs
verbatim, hiding regressions; update the mock for
'#mcp/secrets/allowed-packages.ts' so normalizeAllowedPackages mirrors the real
normalizer (trim entries, remove empty strings, deduplicate, and sort) or simply
import and re-export the real normalizeAllowedPackages implementation for use in
these tests; ensure test inputs include whitespace and duplicate package names
to validate trimming/deduping/sorting behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@packages/worker/src/app/handlers/connect-secret.node.test.ts`:
- Around line 121-123: The test currently mocks normalizeAllowedPackages to
return inputs verbatim, hiding regressions; update the mock for
'#mcp/secrets/allowed-packages.ts' so normalizeAllowedPackages mirrors the real
normalizer (trim entries, remove empty strings, deduplicate, and sort) or simply
import and re-export the real normalizeAllowedPackages implementation for use in
these tests; ensure test inputs include whitespace and duplicate package names
to validate trimming/deduping/sorting behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bc63025a-9d1c-4c44-8f6a-6c79b18b4da5

📥 Commits

Reviewing files that changed from the base of the PR and between b7d0bab and 804ea3b.

📒 Files selected for processing (2)
  • packages/worker/src/app/handlers/connect-secret.node.test.ts
  • packages/worker/src/app/handlers/connect-secret.ts

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit 194202d into main May 1, 2026
9 checks passed
@kentcdodds
kentcdodds deleted the cursor/connect-secret-approved-packages-f10b branch May 1, 2026 18:29
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