Describe the bug
The Okta authentication backend has two critical issues when handling MFA push notifications:
-
Only one push factor receives notifications: When a user has multiple registered Okta Verify Push devices, only the last one encountered during factor enumeration receives the push notification. Other registered push devices are ignored, even if they are active and available.
-
No factor status validation: The code does not check whether a factor's status is ACTIVE before attempting to use it. If the selected factor is suspended, inactive, or pending activation, authentication will fail even though the user may have other active factors available.
These issues stem from the factor selection logic in backend.go:
- The loop overwrites
pushFactor on each iteration rather than collecting all push factors
- The
mfaFactor struct lacks a Status field to validate factor state
- Only one
selectedFactor is chosen and verified
To Reproduce
Steps to reproduce the behavior:
- Configure Okta auth backend in Vault:
vault auth enable okta
vault write auth/okta/config \
org_name="your-org" \
api_token="your-token"
-
In Okta, register a user with multiple Okta Verify Push devices (e.g., mobile phone and tablet)
-
Attempt to authenticate via Vault:
vault login -method=okta username=testuser
# Enter password when prompted
- Observe that only one device receives the push notification (depending on API response order)
Alternative reproduction (suspended factor):
- Register a user with multiple push factors
- Suspend one of the factors in Okta admin console
- If the suspended factor happens to be selected, authentication fails despite having active factors
Expected behavior
Option 1 (Ideal): All active push factors should receive notifications simultaneously, and authentication should succeed when any one is approved. This provides the best user experience and redundancy.
Option 2 (Minimum):
- Only select factors with
status: "ACTIVE"
- If multiple active push factors exist, clearly document which one will be used (first, last, etc.)
- Provide a way for users to specify their preferred factor
Environment:
- Vault Server Version: (affects all versions with Okta auth)
- Vault CLI Version: (all versions)
- Server Operating System/Architecture: (all platforms)
Additional context
Code Analysis
The mfaFactor struct does not include the status field from Okta's API response:
type mfaFactor struct {
Id string `json:"id"`
Type string `json:"factorType"`
Provider string `json:"provider"`
// Missing: Status string `json:"status"`
Embedded struct {
Challenge struct {
CorrectAnswer *int `json:"correctAnswer"`
} `json:"challenge"`
} `json:"_embedded"`
}
The factor selection loop only retains one push factor:
for _, v := range result.Embedded.Factors {
// ...
switch v.Type {
case mfaTOTPMethod:
totpFactor = &v
case mfaPushMethod:
pushFactor = &v // Overwrites previous push factors!
}
}
Security & Usability Impact
- Reduced redundancy: Users cannot rely on backup devices if their primary device is unavailable
- Silent failures: No indication to user why a specific device was chosen or if others exist
- Suspended factor risk: Authentication fails unnecessarily when an inactive factor is selected while active factors are available
- Poor UX: Users with multiple devices cannot predict which will receive the push
Test Coverage Gap
The test file backend_test.go explicitly states: "This test does not exercise MFA however (which is an enterprise feature)" - there is zero test coverage for:
- Multiple push factors
- Factor status validation
- MFA push notification flows
- Factor selection logic
Recommended Fix
- Add
Status field to mfaFactor struct
- Filter factors to only include
status == "ACTIVE"
- Collect all active push factors (not just one)
- Either:
- Send push to all active factors and accept first approval (preferred), OR
- Provide a mechanism for users to select their preferred factor
- Add comprehensive test coverage for MFA scenarios
Describe the bug
The Okta authentication backend has two critical issues when handling MFA push notifications:
Only one push factor receives notifications: When a user has multiple registered Okta Verify Push devices, only the last one encountered during factor enumeration receives the push notification. Other registered push devices are ignored, even if they are active and available.
No factor status validation: The code does not check whether a factor's status is
ACTIVEbefore attempting to use it. If the selected factor is suspended, inactive, or pending activation, authentication will fail even though the user may have other active factors available.These issues stem from the factor selection logic in
backend.go:pushFactoron each iteration rather than collecting all push factorsmfaFactorstruct lacks aStatusfield to validate factor stateselectedFactoris chosen and verifiedTo Reproduce
Steps to reproduce the behavior:
In Okta, register a user with multiple Okta Verify Push devices (e.g., mobile phone and tablet)
Attempt to authenticate via Vault:
vault login -method=okta username=testuser # Enter password when promptedAlternative reproduction (suspended factor):
Expected behavior
Option 1 (Ideal): All active push factors should receive notifications simultaneously, and authentication should succeed when any one is approved. This provides the best user experience and redundancy.
Option 2 (Minimum):
status: "ACTIVE"Environment:
Additional context
Code Analysis
The
mfaFactorstruct does not include thestatusfield from Okta's API response:The factor selection loop only retains one push factor:
Security & Usability Impact
Test Coverage Gap
The test file
backend_test.goexplicitly states: "This test does not exercise MFA however (which is an enterprise feature)" - there is zero test coverage for:Recommended Fix
Statusfield tomfaFactorstructstatus == "ACTIVE"