feat(api/auth): split write into per-resource permissions (closes #660)#891
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
#660) RI exchanges are financially irreversible once submitted to AWS. Keeping execute:ri-exchange disjoint from execute:purchases ensures a user who can initiate regular purchases cannot inadvertently (or intentionally) trigger an RI exchange without an explicit additional grant. Changes: - Add ResourceRIExchange = "ri-exchange" constant to internal/auth/types.go - Update executeExchange handler to require execute:ri-exchange (was execute:purchases) - Update TestExecuteExchange_PermissionGate to assert the new permission verb; add isolation sub-test proving execute:purchases does not grant ri-exchange access - Add /api/ri-exchange/* routes to openapi.yaml with 403 responses and permission documentation on the execute endpoint - Add 'ri-exchange' to the frontend Resource closed-union type and extend canAccess tests: admin true, user false (no default grant); add isolation sub-tests proving execute:purchases does not imply execute:ri-exchange (and vice versa) on the frontend gating mirror Rebased onto feat/multicloud-web-frontend post #922 (effectivePermissions migration). The conflict in frontend/src/__tests__/permissions.test.ts was resolved by re-expressing the user-default-deny invariant in the new effective-permissions model: a non-admin holding execute:purchases is still denied execute:ri-exchange. Em-dashes scrubbed from added prose. No DB migration needed: role defaults are computed at runtime from Go constants; no DB table stores the permission set. No conflict with PR #884 (fix/476): that PR adds 403 to plans/purchases routes; this PR adds a new ri-exchange section that #884 does not touch.
|
Rebased on Permission-bypass review (per the issue brief):
Em-dashes scrubbed from the six PR-introduced occurrences across the touched files (style-only fix that landed alongside the conflict resolution). Tests passing locally:
@coderabbitai review |
|
🧠 Learnings used✅ Actions performedReview triggered.
|
Summary
ResourceRIExchange = "ri-exchange"constant to separate RI exchange permissions from purchase permissionsexecuteExchangehandler to requireexecute:ri-exchangeinstead ofexecute:purchases— RI exchanges are financially irreversible once submitted to AWS; disjoint permissions prevent accidental elevation/api/ri-exchange/*routes toopenapi.yamlwith 403 responses and explicit permission documentation on the execute endpointResourceclosed-union type with'ri-exchange'and tests thatexecute:ri-exchangeis admin-only by defaultBackward compatibility
No breaking change. The PR-A commits (already on this branch) flipped mutating-route router gates from
AuthAdmintoAuthUser+ handler-levelrequirePermission. Existing admin users retain full access via theadmin:*wildcard. Non-admin users who previously couldn't reach these routes now hit the handler-level gate — no access is loosened.execute:ri-exchangehas no default user-role grant — same as before (RI exchange execute was admin-only before this PR). Non-admin roles must be explicitly grantedexecute:ri-exchangevia a custom group.No DB migration needed
Role defaults are computed at runtime from Go constants (
DefaultAdminPermissions/DefaultUserPermissions/DefaultReadOnlyPermissions). No DB table stores the permission set; no migration is needed.Coordination with PR #884
PR #884 (
fix/476) adds 403 responses to plans/purchases routes inopenapi.yaml. This PR adds a new# ---- RI Exchange ----section that #884 does not touch — no conflict.Test plan
go test ./internal/auth/...— 497 passedgo test ./internal/api/...— 1302 passed, including:TestExecuteExchange_PermissionGate— assertsexecute:ri-exchangerequired, notexecute:purchasesexecute:purchasesis rejected (403) for RI exchangeTestRouter_MutatingRoutes_RequireAuth— unauthenticated callers get 401 for/api/ri-exchange/executenpm test(frontend) — 1989 passed, including:execute:ri-exchange(admin:* short-circuit)execute:ri-exchange(no default grant)