Skip to content

Add JWT signing capability - #283

Merged
kentcdodds merged 2 commits into
mainfrom
cursor/add-jwt-sign-primitive-b67c
Apr 30, 2026
Merged

kentcdodds merged 2 commits into
mainfrom
cursor/add-jwt-sign-primitive-b67c

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Apr 30, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add a generic jwt_sign capability under the secrets domain for signing caller-provided JWT header/claims with a private key stored in a saved secret.
  • Support RS256 and optional JSON-field extraction for service-account-style secret JSON.
  • Document JWT signing in the end-user secrets guide, including the { jwt, algorithm } return shape.

Testing

  • npm run test -- --run packages/worker/src/mcp/capabilities/secrets/jwt-sign.node.test.ts
  • npm run typecheck
  • npx oxfmt --check packages/worker/src/mcp/capabilities/secrets/jwt-sign.ts packages/worker/src/mcp/capabilities/secrets/jwt-signing.ts packages/worker/src/mcp/capabilities/secrets/jwt-sign.node.test.ts packages/worker/src/mcp/capabilities/secrets/domain.ts docs/use/secrets-and-values.md
  • npm run test

Notes

  • npm run lint reports only existing warnings outside this change.
  • Addressed AI review feedback by correcting the documented return shape and using user as the approval URL fallback scope.
Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Added JWT signing capability that returns a compact JWT and the algorithm used, never exposing private key material; requires explicit capability approval to use and surfaces clear errors for missing or access‑denied secrets.
  • Documentation

    • Updated docs with usage examples, header/claims input, algorithm behavior, and options to map service-account JSON fields for private keys.
  • Tests

    • Added unit tests verifying signing, signature verification, secret resolution, approval checks, error cases, and JSON-field extraction.

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

coderabbitai Bot commented Apr 30, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: baf447b4-b94d-4d2c-9dd0-a8c64b38ec99

📥 Commits

Reviewing files that changed from the base of the PR and between cc8cdd8 and 33deabc.

📒 Files selected for processing (3)
  • docs/use/secrets-and-values.md
  • packages/worker/src/mcp/capabilities/secrets/jwt-sign.node.test.ts
  • packages/worker/src/mcp/capabilities/secrets/jwt-sign.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • docs/use/secrets-and-values.md
  • packages/worker/src/mcp/capabilities/secrets/jwt-sign.ts
  • packages/worker/src/mcp/capabilities/secrets/jwt-sign.node.test.ts

📝 Walkthrough

Walkthrough

Adds a new read-only MCP secrets capability jwt_sign to sign JWTs (RS256) using private keys stored in secrets, with input validation, capability-based authorization, optional JSON-field key extraction, and tests; docs updated to show codemode.jwt_sign(...) usage.

Changes

Cohort / File(s) Summary
Documentation
docs/use/secrets-and-values.md
Documents codemode.jwt_sign(...) usage, return shape ({ jwt, algorithm }), capability approval requirement, and JSON-field mapping option for service-account secrets.
Secrets Domain Registration
packages/worker/src/mcp/capabilities/secrets/domain.ts
Registers the new jwtSignCapability in the secrets domain capabilities list.
Capability Handler
packages/worker/src/mcp/capabilities/secrets/jwt-sign.ts
Implements jwt_sign capability: Zod input/output schemas, caller auth & storage context build, secret resolution, capability grant check (access-denied includes approval URL), private-key extraction, and response { jwt, algorithm }.
Signing Core
packages/worker/src/mcp/capabilities/secrets/jwt-signing.ts
Adds signJwt supporting RS256 (PEM import via WebCrypto, header/claims base64url encoding, signing) and extractPrivateKeyPem for JSON-field extraction and validation; exports jwtAlgorithmSchema/JwtAlgorithm.
Tests
packages/worker/src/mcp/capabilities/secrets/jwt-sign.node.test.ts
Adds node tests: RSA keypair generation, successful signing + signature verification, JSON-field extraction errors, missing-secret and capability-denied scenarios, and approval-URL behavior.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as Caller/Client
    participant Handler as jwt_sign Handler
    participant SecretSvc as Secret Service
    participant Crypto as WebCrypto

    Caller->>Handler: jwt_sign(request: secretName, claims, header?, algorithm?, jsonField?)
    Handler->>Handler: Validate input (Zod) & authenticate caller
    Handler->>SecretSvc: resolveSecret(name, scope, storageContext)
    SecretSvc-->>Handler: secretValue (string) + metadata (allowedCapabilities, scope)
    Handler->>Handler: Check allowedCapabilities for "jwt_sign"
    alt Not Approved
        Handler-->>Caller: AccessDenied error with approval URL
    else Approved
        Handler->>Handler: extractPrivateKeyPem(secretValue, jsonField?)
        Handler->>Crypto: importKey(PKCS#8 PEM)
        Crypto-->>Handler: CryptoKey
        Handler->>Handler: encode header & claims (base64url)
        Handler->>Crypto: sign(header.payload, CryptoKey)
        Crypto-->>Handler: signature
        Handler-->>Caller: { jwt: header.payload.signature, algorithm }
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰
In burrows deep where secrets sleep, I hop and hum with glee,
I sign a JWT with RS256, no private key set free.
Capabilities give the nod, an approval trail to see,
A tidy token, three-dot bright — from floppy ear to key. 🥕✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add JWT signing capability' directly and concisely summarizes the main change across the PR, which adds a jwt_sign capability for signing JWTs using secrets.
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.

✏️ 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/add-jwt-sign-primitive-b67c

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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

@kentcdodds
kentcdodds marked this pull request as ready for review April 30, 2026 01:34
@github-actions

github-actions Bot commented Apr 30, 2026 •

Copy link
Copy Markdown
Contributor

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

Worker: kody-pr-283
D1: kody-pr-283-db
KV: kody-pr-283-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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/use/secrets-and-values.md`:
- Around line 33-43: The docs incorrectly state that codemode.jwt_sign(...)
returns a bare JWT string; update the text around "Signing JWTs with saved
private keys" to document the actual return shape as an object { jwt, algorithm
} and clarify that callers should use result.jwt for the compact JWT and
result.algorithm for the signing algorithm; also update any inline examples to
access result.jwt (not treat the function return as a string) and note that the
private key material is never returned and jwt_sign still requires the saved
secret to approve the jwt_sign capability.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d6c63557-f7a8-419b-a609-3edd3124cda0

📥 Commits

Reviewing files that changed from the base of the PR and between 0ef0525 and cc8cdd8.

📒 Files selected for processing (5)
  • docs/use/secrets-and-values.md
  • packages/worker/src/mcp/capabilities/secrets/domain.ts
  • packages/worker/src/mcp/capabilities/secrets/jwt-sign.node.test.ts
  • packages/worker/src/mcp/capabilities/secrets/jwt-sign.ts
  • packages/worker/src/mcp/capabilities/secrets/jwt-signing.ts

Comment thread docs/use/secrets-and-values.md

@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 cc8cdd8. Configure here.

Comment thread packages/worker/src/mcp/capabilities/secrets/jwt-sign.ts Outdated
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit dbbbf60 into main Apr 30, 2026
9 checks passed
@kentcdodds
kentcdodds deleted the cursor/add-jwt-sign-primitive-b67c branch April 30, 2026 01:54
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