fix(approvals): validate request_credential payload at creation#44
Conversation
The base createApprovalSchema only checks that payload is an object, so an agent could persist a malformed request_credential (e.g. `key` instead of `envKey`, no reason or howToObtain). Such a request renders degraded in the board UI and cannot be completed, because provide-credential re-parses the payload and would throw. Validate the payload against requestCredentialSchema at creation time so a malformed request is rejected up front with a clear validation error the requesting agent can read and self-correct.
|
Warning Review limit reached
Next review available in: 53 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe approval creation route gains a per-type validation step that parses the payload with Changesrequest_credential Payload Validation
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~5 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@server/src/__tests__/approval-routes-idempotency.test.ts`:
- Around line 434-435: The test assertion in approval-routes-idempotency should
be tightened to match the create contract: update the status check in the
approval route test so it expects only 201 instead of allowing 200 or 201. Use
the existing res.status assertion near mockApprovalService.create to verify the
successful creation response remains fixed at 201 and cannot regress to 200.
In `@server/src/routes/approvals.ts`:
- Around line 157-165: The `request_credential` payload is validated on create
but not on resubmit, so malformed data can still slip through `POST
/approvals/:id/resubmit`. Update the resubmit handler in `approvals` to re-parse
`approvalInput.payload` with `requestCredentialSchema` whenever `existing.type
=== "request_credential"`, mirroring the create-path check so both
`createApprovalSchema` and `resubmit` enforce the same contract.
🪄 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
Run ID: 8685f1a4-24a2-479a-8ddb-d30b22d93137
📒 Files selected for processing (2)
server/src/__tests__/approval-routes-idempotency.test.tsserver/src/routes/approvals.ts
Address review: the resubmit path replaces the payload but never re-parsed it, so a malformed request_credential could still be persisted through resubmit. Validate it there too, and assert the creation test on 201 (the route's actual success status) instead of 200 | 201.
Problem
The base
createApprovalSchemaonly checks thatpayloadis an object (z.record(z.string(), z.unknown())), so per-type validation never runs at creation. An agent can therefore persist a malformedrequest_credential(e.g.keyinstead ofenvKey, free-formnote/purposeinstead ofreason, nohowToObtain/browserAgentPrompt).Such a request:
Env varshows—, placeholder is$ENV, no how-to section), since the credential renderer reads the exactenvKey/reason/howToObtainfields;provide-credentialre-parses the payload withrequestCredentialSchemaand would throw on the missingenvKey.So the documented capability-request schema was only a suggestion, not enforced.
Fix
Validate the payload against
requestCredentialSchemaat creation time inPOST /companies/:id/approvals. A malformedrequest_credentialis now rejected up front with a400 Validation error(with details) that the requesting agent can read and self-correct. The check is scoped torequest_credentialonly, so other approval types keep their free-form payloads.Tests
request_credentialpayload -> 400,createnot called;Approvals route suite green (13/13), server typecheck clean.
Summary by CodeRabbit