Step-up auth: Add global enforcement following 2FA pattern
What does this MR do and why?
Implement global step-up authentication enforcement that blocks users from accessing any page until they complete step-up auth, similar to how 2FA enforcement works.
Problem
The current step-up authentication implementation only enforces step-up auth when users directly access protected group or project pages. Users who are members of a step-up auth protected group can still freely browse other parts of GitLab (dashboard, other groups, profile settings, global search, etc.) without completing step-up authentication first.
This creates security concerns:
- Information leakage via dashboard views: Users can see content from protected groups on their dashboard without completing step-up authentication
- Information leakage via global search: Users can discover content from protected groups through search results
- Delayed enforcement: Step-up auth is only triggered when visiting the protected resource, not immediately
Solution
Follow the established 2FA enforcement pattern by:
-
Create
StepUpAuthRequiringGroupsFinder- Finder to retrieve groups requiring step-up auth for a user -
Create
EnforcesStepUpAuthGlobalconcern - Global enforcement concern withbefore_actionthat redirects users to complete step-up auth before accessing any page -
Include concern in
ApplicationController- Enables global enforcement -
Add
skip_before_actionto essential controllers - Allow logout, help pages, terms acceptance, leave group action, and the step-up auth flow itself - Add profile step-up auth controller - Fallback page when user has multiple groups requiring authentication
- Handle GraphQL requests - Return proper error response instead of redirect
Current vs. New Behavior
Current behavior:
User logs in → User can browse freely → User visits protected group → Step-up auth required
(User can still browse other content while step-up auth is pending)
New behavior (aligned with 2FA):
User logs in → User visits ANY page → Step-up auth check
→ Required + Not completed → REDIRECT to step-up auth
→ User LOCKED until step-up auth completed
→ User can now access ALL pages
References
- Related epic: &16818
- Related issue: #587948
- Addresses: #581316 (Dashboard views protection)
- Addresses: #581317 (Global search protection)
- Related: #556943 (Step-up auth group protection epic)
Screenshots or screen recordings
N/A - Backend-only changes affecting redirect behavior
| Before | After |
|---|---|
| Users can browse GitLab freely while step-up auth is pending | Users are redirected to step-up auth before accessing any page |
How to set up and validate locally
- Enable the
openid_connectprovider in your OmniAuth configuration - Create a group and configure step-up auth requirement:
group = Group.find_by_path('your-group') group.update!(step_up_auth_required_oauth_provider: 'openid_connect') - Add a test user as a member of this group
- Log in as the test user
- Navigate to the dashboard or any other page
- Verify you are redirected to the step-up auth page
- Verify you can still:
- Log out (via the sign out link)
- Access help pages
- Leave the group (escape hatch)
- Accept terms (if applicable)
- Complete the step-up auth flow
- Verify you can now access all pages normally
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
MR Checklist (@gerardo-navarro)
- Changelog entry added, if necessary
- Documentation created/updated via this MR
- Documentation reviewed by technical writer or follow-up review issue created
- Tests added for this feature/bug
- Tested in all supported browsers
- Conforms to the code review guidelines
- Conforms to the style guides
- Conforms to the javascript style guides
- Conforms to the database guides
- Conforms to the merge request performance guidelines
- Security review: Verified skip_before_action placements follow 2FA enforcement pattern