Skip to content

Enforce role-based access for KIS endpoints#147

Open
robin-watcha wants to merge 1 commit intomainfrom
codex/add-rolebased-access-to-kisoverse
Open

Enforce role-based access for KIS endpoints#147
robin-watcha wants to merge 1 commit intomainfrom
codex/add-rolebased-access-to-kisoverse

Conversation

@robin-watcha
Copy link
Collaborator

Summary

  • tighten viewer/trader/admin gating across the KIS domestic/overseas routers and dependency helpers
  • verify Celery triggers and tasks propagate the authenticated current_user.id while preserving the MCP fallback
  • clean up unused _effective_user_id helpers, keep the nav menu split by role, and expand router/task tests to cover new scenarios

Testing

  • Not run (not requested)

@coderabbitai
Copy link

coderabbitai bot commented Feb 14, 2026

Warning

Rate limit exceeded

@robin-watcha has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 26 minutes and 47 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/add-rolebased-access-to-kisoverse

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.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
30.6% Duplication on New Code (required ≤ 3%)
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@claude
Copy link

claude bot commented Feb 14, 2026

Pull Request Review: Enforce role-based access for KIS endpoints

Summary

This PR successfully implements role-based access control (RBAC) for KIS (Korea Investment & Securities) trading endpoints, restricting domestic and overseas trading functionality to users with trader or admin roles while blocking viewer access. The implementation is clean, well-tested, and properly propagates user context through Celery tasks.


✅ Strengths

1. Excellent Architecture

  • The require_min_role_user factory pattern in app/routers/dependencies.py:29-58 is elegant and reusable
  • Pre-configured require_trader_user dependency (:58) provides a convenient shorthand
  • Proper separation of concerns: authentication → role checking → business logic

2. Comprehensive Test Coverage (+416 lines)

The test suite covers all critical scenarios:

  • Role hierarchy: viewer blocked, trader/admin allowed
  • Unauthenticated users: 401 propagation
  • User ID propagation: Celery tasks receive correct user_id
  • Fallback behavior: MCP tasks default to user_id=1 when not authenticated
  • Both markets: Domestic and overseas endpoints tested

Tests in tests/test_routers.py:872-1083 and tests/test_kis_tasks.py:2661-2858 demonstrate thorough coverage.

3. Consistent Implementation

  • All 12 router endpoints (6 domestic + 6 overseas) updated uniformly
  • All 12 Celery task definitions now accept user_id parameter
  • Nav menu properly hides KIS links from viewers (app/templates/nav.html:640-648)

4. Backward Compatibility

  • Celery tasks default to user_id=1 when not provided, preserving MCP/scheduled task behavior
  • effective_user_id = user_id if user_id is not None else 1 pattern consistently applied

🔍 Code Quality Observations

Minor Issues

1. Missing Type Annotation (app/routers/dependencies.py:35)

Current: def require_min_role_user(min_role: UserRole) -> Callable

Should be more specific for better type checking.

Impact: Low - Type checkers may not catch signature mismatches.

2. Import Style

from collections.abc import Callable is correct for Python 3.13+ per CLAUDE.md requirements.

Best Practices Applied

Security: 403 Forbidden for authorization, 401 Unauthorized for authentication
User experience: Korean error messages for end users
Testing: Mocking, parametrized tests, and async test patterns
Documentation: Docstrings explain factory pattern and usage


🔐 Security Analysis

Strong Points

  1. Defense in depth: Both router-level (Depends(require_trader_user)) and UI-level (nav menu) protection
  2. No role escalation: Uses has_min_role hierarchy checking from app/auth/role_hierarchy.py:23-30
  3. Task isolation: Each user's user_id propagates through async tasks, preventing cross-user data leakage

Potential Concerns (Low Risk)

Task Status Endpoint Authorization

/api/analyze-task/{task_id} requires trader role but doesn't verify the task_id belongs to the requesting user.

Scenario: Trader A could potentially query Trader B's task status if they know the task ID.

Risk: Low - task IDs are UUIDs, hard to guess, and only reveal task status/result, not modify data.

Recommendation (optional enhancement):

  • Store task metadata in Redis/DB with user_id
  • Verify in get_analyze_task_status that task belongs to requesting user
  • Allow admins to view any task

📊 Performance Considerations

No performance regressions:

  • Dependency injection runs once per request
  • has_min_role is O(1) enum comparison
  • No additional database queries introduced

Celery task overhead: Passing user_id adds negligible serialization cost (~8 bytes).


🧪 Test Coverage Assessment

What's Tested

  • ✅ Role-based access (viewer/trader/admin)
  • ✅ User ID propagation to Celery tasks
  • ✅ Fallback to user_id=1 for MCP/scheduled tasks
  • ✅ Both domestic and overseas endpoints

What Could Be Added (Optional)

  • Edge case: Invalid/null user_id passed to tasks
  • Integration test: End-to-end request → Celery → DB with role checking
  • Template test: Verify nav menu renders correctly for each role

Current coverage is sufficient for PR approval.


📝 Code Style

Follows CLAUDE.md guidelines:

  • Async/await patterns consistent with codebase
  • Korean comments/messages for user-facing strings
  • Type hints on public functions
  • Docstrings on complex functions

🚀 Deployment Notes

Pre-Deployment Checklist

  1. ✅ Run migrations (no schema changes needed)
  2. ✅ Verify existing users have roles assigned in users table
  3. ⚠️ IMPORTANT: Ensure MCP/scheduled Celery tasks still work with default user_id=1
  4. ✅ Test with each role (viewer/trader/admin) in staging

Rollback Plan

If issues arise, revert to main branch. No database changes required.


✅ Recommendation

APPROVE with optional follow-ups.

This is a well-implemented security enhancement that:

  • ✅ Properly restricts sensitive trading endpoints
  • ✅ Maintains backward compatibility for automated tasks
  • ✅ Has comprehensive test coverage
  • ✅ Follows project conventions and best practices

Optional Post-Merge Enhancements

  1. Add task ownership verification for /api/analyze-task/{task_id}
  2. Add integration test for full request lifecycle with roles
  3. Consider rate limiting per user for trading endpoints

Great work on this security-focused PR! 🎉


Questions for the Author

  1. Have you tested this with viewer/trader/admin users in a development environment?
  2. Are there any scheduled Celery tasks (cron jobs, etc.) that trigger these KIS tasks? If so, ensure they still work with the user_id=1 fallback.
  3. Should the task status endpoint (/api/analyze-task/{task_id}) verify task ownership?

Reviewed by: Claude Code (Sonnet 4.5)
Review Date: 2026-02-14

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant