I received a request from a customer. They use Citrix XenApp, with some applications used for operations under PCI DSS. These applications are already separated and accessible only to some users.
They donβt use MFA for access to Citrix “normal applications” but, due to the PCI DSS regulation, they must implement the MFA for all PCI DSS applications.
Their initial request was to use the Okta MFA Credential Provider for Windows1, with the idea to install it only on the PCI DSS Citrix server. However, I will explain in this article why it’s not possible and what native Okta and Citrix options we have.
A special thanks to my colleague Ivan Rodriguez (former Citrix SE) for the help on this topic.
Note about Okta MFA Credential Provider for Windows#
The Okta MFA Credential Provider for Windows is not compatible with Citrix sessions based on the ICA/HDX protocol.
This agent is specifically designed to intercept the Windows login process that occurs via Remote Desktop Protocol (RDP). It functions as a Credential Provider that activates on the Windows server’s interactive login screen.
The Citrix ICA/HDX protocol, on the other hand, uses a completely different authentication mechanism. When a user authenticates to Citrix StoreFront, they receive a token. This token is then passed directly to the Citrix server to start the session, completely bypassing the operating system’s interactive login screen. Since the Okta agent hooks into a screen that is never presented during a Citrix session launch, it has no opportunity to intervene and request MFA.
ℹ️ Documentation: Okta - MFA Credential Provider for Windows, which exclusively mentions its use with RDP.
The supported solution to have MFA is via StoreFront or ADC (NetScaler).
Solution #1: Okta Groups and Authentication Policies#
Okta checks at login time if the user belongs to a group that requires access to sensitive data (e.g., “PCI-Users”). If the user is in the group, they are immediately prompted for MFA. If not, they access without MFA. In this model, however, PCI users will always receive an MFA prompt (even if they access the Citrix portal for non-PCI applications).
Diagram#
--- config: layout: elk --- flowchart TD U["π€ User"] --> SF["πͺ Citrix StoreFront"] SF --> Okta["π Okta IdP"] Okta --> Decision{"π‘οΈ Authentication Policies"} Decision -- "User in PCI-Users group" --> MFA["π MFA Challenge"] Decision -- "User not in PCI-Users group" --> LIST["π± All Apps (PCI + non-PCI)"] MFA --> LIST LIST --> LAUNCH["π Launch App"] U:::userNode SF:::authNode Okta:::authNode Decision:::decisionNode MFA:::authNode LIST:::appNode LAUNCH:::appNode classDef userNode fill:#e1f5fe classDef authNode fill:#fff3e0 classDef appNode fill:#e8f5e8 classDef decisionNode fill:#fce4ec
Solution #2: Dual-StoreFront Architecture#
Citrix StoreFront alone does not natively support “step-up MFA” logic for individual applications2. Authentication policies are applied at the entire “Store” level, not per application. Once the user is authenticated to the Store, they have access to all published resources without further MFA prompts from StoreFront.
Proposed Workaround: To meet the security requirement for PCI DSS applications without a Citrix ADC, the architectural approach is to create two distinct and isolated access paths:
- Standard Store (No MFA): A dedicated portal for non-PCI applications. Authentication will be handled via a specific SAML application3 in Okta with a policy that does not require MFA.
- PCI Store (with MFA): A second, completely separate portal that will exclusively publish PCI DSS applications. Authentication will be managed by a second SAML application3 in Okta, whose authentication policy will require MFA.
This solution implies that users will have two separate URLs and dashboards: one for standard activities and one for high-security activities. To mitigate this impact and offer a unified access point, you can configure the Okta user dashboard to include “bookmarks” for the Citrix applications. This way, the user will always start from a single point (their Okta dashboard) to access both types of resources.
Diagram#
--- config: layout: elk --- flowchart TD U["π€ User"] --> SF_STD["πͺ Standard StoreFront"] & SF_PCI["πͺ PCI StoreFront"] SF_STD --> Okta_STD["π Okta IdP - App #1 - No MFA"] Okta_STD --> LIST_STD["π± Non-PCI Apps"] LIST_STD --> LAUNCH_STD["π Launch Standard App"] SF_PCI --> Okta_PCI["π Okta IdP - App #2 - MFA Required"] Okta_PCI --> MFA["π MFA Challenge"] MFA --> LIST_PCI["π PCI Apps"] LIST_PCI --> LAUNCH_PCI["π Launch PCI App"] U:::userNode SF_STD:::standardPath SF_PCI:::pciPath Okta_STD:::standardPath LIST_STD:::standardPath LAUNCH_STD:::standardPath Okta_PCI:::pciPath MFA:::pciPath LIST_PCI:::pciPath LAUNCH_PCI:::pciPath classDef userNode fill:#e1f5fe classDef standardPath fill:#e8f5e8 classDef pciPath fill:#ffebee
Solution #3 - Single Portal and Contextual MFA for Applications#
The introduction of a Citrix ADC (formerly known as NetScaler) into the architecture allows for achieving the goal of a single portal securely, using its nFactor Authentication4 functionality.
However, it’s important to understand how the architecture works and what the user experience will be. There are two main models.
It is possible to configure the ADC to require MFA only when a specific application is launched. In this scenario, two Citrix Gateway Virtual Servers are configured on the ADC, but a single StoreFront portal is used:
- Standard Gateway (VS1) β configured with basic authentication only.
- PCI Gateway (VS2) β configured with nFactor authentication that enforces MFA.
- StoreFront: Uses a feature called Optimal Gateway Routing (OGR). This rule routes launch requests for PCI applications to the “PCI Gateway " and all others to the “Standard Gateway .”
- The user connects to the portal and authenticates against the Standard Gateway (no MFA).
- StoreFront displays all applications (PCI and non-PCI).
- If the user launches a non-PCI app, OGR routes it to the Standard Gateway, and the app launches immediately.
- If the user launches a PCI app, OGR routes the request to the PCI Gateway. At this point, the ADC enforces MFA via Okta.
- Once MFA succeeds, the PCI app launches.
This creates a real step-up MFA experience: users authenticate without MFA initially, and are only challenged for MFA when launching a sensitive PCI application.
Diagram#
--- config: layout: elk --- flowchart TD U["π€ User"] --> ADC["π Citrix ADC"] ADC --> VS1["β‘ Virtual Server #1 - Standard Gateway"] VS1 --> Auth["π Basic Auth - (Okta/LDAP/AD)"] Auth --> LIST["πͺ StoreFront - All Apps (PCI + non-PCI)"] LIST --> OGR{"π― OGR Routing - Decision"} OGR -- Standard App --> LAUNCH_STD["π Launch Standard App"] OGR -- PCI App --> VS2["π Virtual Server #2 - PCI Gateway"] VS2 --> MFA["π MFA Challenge"] MFA --> LAUNCH_PCI["π Launch PCI App"] U:::userNode ADC:::standardFlow VS1:::standardFlow Auth:::standardFlow LIST:::standardFlow OGR:::mfaNode LAUNCH_STD:::standardFlow VS2:::pciFlow LAUNCH_PCI:::pciFlow MFA:::pciFlow classDef userNode fill:#e1f5fe classDef standardFlow fill:#e8f5e8 classDef pciFlow fill:#ffebee classDef mfaNode fill:#f3e5f5
For the “PCI Gateway” that requires MFA, integration with Okta can be done in two ways:
- RADIUS5: The ADC sends an authentication request to an on-premises Okta RADIUS Agent, which contacts Okta for MFA validation. There are some limitations about which MFA can be used6 (i.e., FIDO2 and FastPass are not compatible with RADIUS).
- SAML3: This is a more modern alternative that allows for a better user experience, including the ability to use Okta FastPass for passwordless access. The ADC redirects the user’s browser directly to Okta. This architecture mandatorily requires the implementation of the Citrix Federated Authentication Service (FAS)7 to ensure Single Sign-On (SSO) to applications.
Final Note#
I hope this information is useful. Due to the complexity of the configuration, I warmly suggest to involve Okta PS (Professional Services) or a certified Okta Partner, who can provide the necessary expertise and support for your production environment.