diff --git a/spec/network/30111.md b/spec/network/30111.md new file mode 100644 index 000000000..2fdb234d9 --- /dev/null +++ b/spec/network/30111.md @@ -0,0 +1,153 @@ +# Global Secure Access is enabled + +## Spec Status + +Draft + +## Documentation Status + +Not started + +## Dev Status + +Not started + +## Minimum License + +AAD_PREMIUM_P1, Entra_Premium_Internet_Access, Entra_Premium_Private_Access + +## Pillar + +Network + +## SFI Pillar + +Protect networks + +## Category + +Zero Trust Network Access (ZTNA) + +## Risk Level + +High + +## User Impact + +Medium + +## Implementation Cost + +Medium + +## Customer Facing Explanation + +Global Secure Access is Microsoft's Security Service Edge (SSE) solution that provides Zero Trust network access for remote users and branch offices. It encompasses Microsoft Entra Internet Access and Microsoft Entra Private Access, replacing traditional VPNs with identity-aware, cloud-delivered security controls. + +Without Global Secure Access enabled, organizations rely on legacy perimeter-based VPN solutions that grant implicit trust to any user on the corporate network. Threat actors who compromise a user's credentials can laterally move across the network because traditional VPNs provide broad network access rather than per-application, identity-driven access. This flat-network approach exposes all internal resources to authorized users indiscriminately, eliminating segmentation boundaries. Attackers can maintain persistence by establishing secondary access channels through the VPN tunnel without additional authentication. Once inside a poorly segmented VPN network, attackers can enumerate and attack internal systems freely. By transitioning to Global Secure Access with identity-based, per-application access controls and continuous validation, organizations enforce Zero Trust principles—users and devices are never implicitly trusted, and access is continuously verified based on user, device, location, and risk signals. + +Risk Level: High - Organizations without Global Secure Access enabled depend on legacy VPN models that lack identity-aware controls and enable lateral movement across the network. + +User Impact: Medium - Users must install the Global Secure Access client and may require re-authentication; some dependent on VPNs may experience workflow changes during migration. + +Implementation Cost: Medium - Requires deploying the Global Secure Access client, configuring forwarding profiles, and potentially integrating with Conditional Access policies. Ongoing management of traffic policies is required. + +## Check Query + +The assessment checks whether Global Secure Access is configured and actively enabled in the tenant. This check validates that traffic forwarding profiles (Microsoft traffic, Internet access, or Private access) are configured and enabled. + +### Query 1: Q1: Validate Global Secure Access traffic forwarding profiles are configured + +**Endpoint:** `https://graph.microsoft.com/beta/networkAccess/forwardingProfiles` + +**Documentation:** [Global Secure Access traffic forwarding profiles](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-traffic-forwarding) + +**Property Check:** The presence of forwarding profile objects with status indicating configuration + +**Pass Criteria:** At least one traffic forwarding profile (Microsoft traffic, Internet access, or Private access profile) exists and is configured in the tenant + +**Fail Criteria:** No forwarding profiles are found, or all existing profiles are in an unconfigured/disabled state + +**Details:** Global Secure Access is enabled when at least one of the three traffic forwarding profiles is configured: +- Microsoft traffic profile (for Microsoft 365 and Microsoft Graph traffic) +- Internet access profile (for public internet and SaaS app traffic) +- Private access profile (for private corporate resources and legacy apps) + +If a tenant has no forwarding profiles configured, Global Secure Access is not in use. + +### Query 2: Q2: Validate that traffic forwarding profiles have assigned users or remote networks + +**Endpoint:** `https://graph.microsoft.com/beta/networkAccess/forwardingProfiles/{id}/users` and `https://graph.microsoft.com/beta/networkAccess/forwardingProfiles/{id}/remoteNetworks` + +**Documentation:** [Global Secure Access dashboard](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-global-secure-access-logs-monitoring#dashboard) + +**Property Check:** User assignments or remote network assignments to forwarding profiles + +**Pass Criteria:** At least one forwarding profile (Q1) has active user assignments or remote network assignments, indicating the feature is in active use + +**Fail Criteria:** Forwarding profiles exist but have no user or remote network assignments, indicating configuration without deployment + +**Details:** A configured forwarding profile is only meaningful if it has users or remote networks assigned to it. This query validates that the configuration is not just present but also actively deployed. + +## User facing message + +Pass: Global Secure Access is enabled with traffic forwarding profiles configured and actively assigned to users or remote networks. + +Fail: Global Secure Access is not enabled, or forwarding profiles are configured without active user or remote network assignments. + +Investigate: Global Secure Access has forwarding profiles configured but without users or remote networks assigned, indicating incomplete deployment. + +## Test evaluation logic + +1. Execute Query 1 (Q1): Retrieve all forwarding profiles in the tenant +2. If no forwarding profiles are found, test result is **Fail** +3. If forwarding profiles are found, execute Query 2 for each profile +4. If any forwarding profile has user assignments or remote network assignments, test result is **Pass** +5. If forwarding profiles exist but have no assignments, test result is **Investigate** + +## Test output data + +The test returns a list of configured traffic forwarding profiles with the following information: +- Profile name (e.g., "Microsoft traffic profile", "Internet access profile", "Private access profile") +- Profile type +- Status (enabled/disabled) +- Number of assigned users +- Number of assigned remote networks +- Creation date + +Link to Global Secure Access configuration portal: [Microsoft Entra Admin Center - Global Secure Access](https://entra.microsoft.com/#view/Microsoft_AAD_GlobalSecureAccess/GlobalSecureAccessBlade) + +## Remediation resources + +To enable Global Secure Access in your organization, follow these steps: + +1. **Verify licensing**: Ensure your organization has the appropriate licenses. Microsoft Entra Internet Access and Microsoft Entra Private Access require Microsoft Entra ID P1 or P2 as a prerequisite, plus either Microsoft Entra Suite or standalone Microsoft Entra Internet Access/Private Access licenses. For details, see [Global Secure Access licensing overview](https://learn.microsoft.com/en-us/entra/global-secure-access/overview-what-is-global-secure-access#licensing-overview). + +2. **Assign administrator roles**: Assign the Global Secure Access Administrator role to designated administrators. See [Global Secure Access Administrator permissions](https://learn.microsoft.com/en-us/entra/identity/role-based-access-control/permissions-reference#global-secure-access-administrator). + +3. **Access Global Secure Access**: Navigate to the Microsoft Entra admin center and select Global Secure Access from the navigation menu. See [Quickstart: Access the Global Secure Access area](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-get-started-with-global-secure-access). + +4. **Configure traffic forwarding profiles**: Decide which profiles to enable: + - For Microsoft 365 traffic: Enable the [Microsoft traffic profile](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-microsoft-traffic-profile) and follow [How to manage the Microsoft traffic profile](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-manage-microsoft-profile). + - For public internet and SaaS apps: Enable the [Internet access profile](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-internet-access) and follow [How to manage the Internet access profile](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-manage-internet-access-profile). + - For private corporate resources: Enable the [Private access profile](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-private-access) and follow [How to manage the Private access profile](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-manage-private-access-profile). + +5. **Install the Global Secure Access client**: Deploy the client to user devices. See [How to install the Global Secure Access client](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-install-windows-client). + +6. **Assign users to forwarding profiles**: Once profiles are configured, assign users or remote networks to activate the feature. See [Assigning users to Global Secure Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-assign-users-to-global-secure-access). + +7. **Monitor and validate**: Use the Global Secure Access dashboard to verify that users are connected and traffic is flowing through the service. See [Global Secure Access logs and monitoring](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-global-secure-access-logs-monitoring). + +## API Testing and Validation Notes + +### Query 1 Endpoint Validation +- **Endpoint**: `https://graph.microsoft.com/beta/networkAccess/forwardingProfiles` +- **Status**: Documented in Microsoft Graph beta API; requires production validation +- **Expected Response Structure**: Array of forwarding profile objects +- **Required Permissions**: NetworkAccess.Read.All or Global Secure Access Administrator role + +### Query 2 Endpoint Validation +- **Endpoint**: `https://graph.microsoft.com/beta/networkAccess/forwardingProfiles/{id}/users` +- **Status**: Documented in Microsoft Graph beta API; requires production validation +- **Dependencies**: Requires iterating through results of Query 1 +- **Pagination**: May return paginated results for tenants with large user assignments diff --git a/spec/network/30112.md b/spec/network/30112.md new file mode 100644 index 000000000..e215d8442 --- /dev/null +++ b/spec/network/30112.md @@ -0,0 +1,166 @@ +# Universal Continuous Access Evaluation is enabled for Global Secure Access + +## Spec Status + +Draft + +## Documentation Status + +Not started + +## Dev Status + +Not started + +## Minimum License + +AAD_PREMIUM_P1, Entra_Premium_Internet_Access, Entra_Premium_Private_Access + +## Pillar + +Network + +## SFI Pillar + +Protect networks + +## Category + +Zero Trust Network Access (ZTNA), Continuous Access Evaluation + +## Risk Level + +Medium + +## User Impact + +Low + +## Implementation Cost + +Low + +## Customer Facing Explanation + +Universal Continuous Access Evaluation (Universal CAE) is a platform feature of Global Secure Access that continuously validates user access in near real-time whenever Microsoft Entra ID detects changes to user identity or device state. Unlike traditional token-based access that remains valid until expiration, Universal CAE revokes and revalidates network access immediately when security events occur, such as user disablement, password changes, or detection of high-risk sign-in activity. + +Without Universal CAE enabled, organizations face a critical time window vulnerability: when an employee is terminated or a user account is compromised, the attacker can continue accessing network resources through Global Secure Access for up to 90 minutes (the default access token lifetime) because the system doesn't know the access permission has changed. During this window, a departing employee could exfiltrate sensitive data, or an attacker with a stolen token could laterally move through private networks and attack systems. Universal CAE eliminates this window by communicating identity changes to Global Secure Access in near real-time, forcing immediate reauthentication. When users cannot complete reauthentication (because their account is disabled or access is revoked), their network access is blocked immediately rather than after token expiration. This dramatically reduces the blast radius and dwell time of compromised accounts. + +Risk Level: Medium - Without Universal CAE, there is a 90-minute window where access tokens remain valid despite account state changes, enabling lateral movement and data exfiltration by departed employees or attackers. + +User Impact: Low - Universal CAE is transparent to users unless an access-revocation event occurs (e.g., account disabled, password reset); in those cases, users are prompted to reauthenticate. + +Implementation Cost: Low - Universal CAE is enabled by default in Global Secure Access clients. Organizations only need to verify it is active in their Conditional Access configuration and optionally enable Strict Enforcement mode for enhanced security. + +## Check Query + +The assessment checks whether Universal Continuous Access Evaluation (CAE) is enabled in the tenant's Conditional Access configuration for Global Secure Access workloads. + +### Query 1: Q1: Retrieve Conditional Access policies with CAE session controls + +**Endpoint:** `https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies` + +**Documentation:** [Continuous access evaluation in Microsoft Entra](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation) and [Session controls in Conditional Access policy](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-session) + +**Filter:** Policies targeting Global Secure Access workloads with session controls configured for CAE + +**Property Check:** `grantControls.sessionControls.continuousAccessEvaluation` settings and `includeApplications` or `includeWorkloadIdentities` that reference Global Secure Access + +**Pass Criteria:** At least one Conditional Access policy targets Global Secure Access (via workload identities) and explicitly enables or allows Continuous Access Evaluation through session controls + +**Fail Criteria:** No Conditional Access policies are configured for Global Secure Access workloads, or policies exist but CAE is explicitly disabled in session controls + +**Details:** Global Secure Access uses Microsoft Entra workload identities to authenticate. Universal CAE must be enabled in Conditional Access policy session controls for Global Secure Access tenants. By default, CAE is opportunistic (enabled when supported), but organizations can also implement Strict Enforcement mode for enhanced security. + +### Query 2: Q2: Validate Strict Enforcement mode configuration (optional enhanced security) + +**Endpoint:** `https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies?$filter=includes('sessionControls.continuousAccessEvaluation.strictEnforcementEnabled')` + +**Documentation:** [Continuous access evaluation strict location enforcement in Microsoft Entra ID](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation-strict-enforcement) + +**Property Check:** `sessionControls.continuousAccessEvaluation.strictEnforcementEnabled` property on policies targeting Global Secure Access + +**Pass Criteria (Strict Enforcement):** If enabled, indicates highest security modality where access is blocked immediately if IP address doesn't match Conditional Access policy requirements + +**Fail Criteria (Strict Enforcement):** Not configured; this is optional but recommended for organizations with strict security requirements + +**Details:** This query checks for the optional Strict Enforcement mode of Universal CAE. When enabled, access is revoked if the IP address detected by the resource provider doesn't match the organization's Conditional Access policies. This requires understanding of network routing but provides the highest security level. + +## User facing message + +Pass: Universal Continuous Access Evaluation is enabled for Global Secure Access workloads, providing near real-time access revocation when user identity changes. + +Fail: Universal Continuous Access Evaluation is not configured or disabled for Global Secure Access workloads, creating a time window for unauthorized access with valid tokens. + +Investigate: Conditional Access policies exist but CAE configuration is unclear or only partially enabled for Global Secure Access. + +## Test evaluation logic + +1. Execute Query 1: Retrieve all Conditional Access policies with CAE session controls +2. Filter for policies that target Global Secure Access workloads (via workload identities or app-based targeting) +3. If no policies target Global Secure Access, test result is **Fail** +4. If at least one policy targets Global Secure Access and CAE is enabled (not explicitly disabled), test result is **Pass** +5. If policies exist but CAE is explicitly disabled (`continuousAccessEvaluation.isEnabled = false`), test result is **Fail** +6. Execute Query 2 to check if Strict Enforcement mode is configured (informational only, not required for pass) +7. If Strict Enforcement is enabled, append this to the Pass result as "with Strict Enforcement mode enabled" + +## Test output data + +The test returns information about Conditional Access policies that govern Global Secure Access access: +- Policy name +- Policy state (enabled/disabled) +- Target workloads or applications (Global Secure Access) +- CAE status (enabled/disabled) +- Strict Enforcement mode status (if configured) +- Last modified date +- Assigned users/groups + +Link to Conditional Access policy portal: [Microsoft Entra Admin Center - Conditional Access Policies](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies) + +## Remediation resources + +To enable Universal Continuous Access Evaluation for Global Secure Access in your organization, follow these steps: + +1. **Understand Universal CAE**: Review the [Universal Continuous Access Evaluation concept documentation](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-universal-continuous-access-evaluation) to understand how it protects your organization. + +2. **Access Conditional Access**: Navigate to the Microsoft Entra admin center and go to Identity > Protection > Conditional Access. See [Getting started with Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-policy-common). + +3. **Create or modify a Conditional Access policy for Global Secure Access**: + - Create a new policy or modify an existing one that targets Global Secure Access workloads + - See [How to configure Conditional Access policies](https://learn.microsoft.com/en-us/entra/identity/conditional-access/how-to-policy-adoption-recommendations) + - Target "Global Secure Access" as the workload or include Global Secure Access service principal in your policy + +4. **Enable Continuous Access Evaluation in session controls**: + - In the policy, go to Session controls + - Enable "Continuous Access Evaluation" + - By default, this enables the opportunistic mode (recommended for most organizations) + - See [Session controls documentation](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-session) + +5. **(Optional) Enable Strict Enforcement mode for enhanced security**: + - In the CAE session control, check "Strict enforcement" + - This ensures access is revoked immediately if the user's location (IP address) doesn't match the Conditional Access policy + - Only enable if your organization has well-defined and stable network topologies + - See [Strict Location Enforcement documentation](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation-strict-enforcement) + +6. **Ensure Global Secure Access client supports CAE**: + - Update Global Secure Access clients to the latest version that supports Universal CAE + - See [Global Secure Access client for Windows](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-install-windows-client) + +7. **Monitor CAE effectiveness**: + - Review audit logs to verify CAE events are being triggered + - See [Continuous access evaluation troubleshooting](https://learn.microsoft.com/en-us/entra/identity/conditional-access/howto-continuous-access-evaluation-troubleshoot) + +## API Testing and Validation Notes + +### Query 1 Endpoint Validation +- **Endpoint**: `https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies` +- **Status**: Stable v1.0 API endpoint +- **Expected Response**: Array of Conditional Access policy objects +- **Required Permissions**: Policy.Read.All or Policy.ReadWrite.ConditionalAccess role +- **Filter Complexity**: May need to parse `sessionControls` property to identify CAE configuration + +### Query 2 Endpoint Validation +- **Endpoint**: `https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies` +- **Status**: Stable v1.0 API endpoint; Strict Enforcement is documented in Learn but may have limited visibility in Graph +- **Dependencies**: Requires results from Query 1 +- **Note for Developers**: Strict Enforcement mode property may be in `sessionControls.continuousAccessEvaluation.strictEnforcementEnabled`. Verify current schema in Microsoft Graph documentation. diff --git a/spec/network/30113.md b/spec/network/30113.md new file mode 100644 index 000000000..4d091949f --- /dev/null +++ b/spec/network/30113.md @@ -0,0 +1,182 @@ +# B2B Guest Access is enabled for Private Apps in Global Secure Access + +## Spec Status + +Draft + +## Documentation Status + +Not started + +## Dev Status + +Not started + +## Minimum License + +AAD_PREMIUM_P1, Entra_Premium_Private_Access + +## Pillar + +Network + +## SFI Pillar + +Protect networks + +## Category + +Zero Trust Network Access (ZTNA), B2B Collaboration + +## Risk Level + +High + +## User Impact + +Low + +## Implementation Cost + +Medium + +## Customer Facing Explanation + +B2B Guest Access for Private Apps in Global Secure Access enables organizations to securely grant external partners, contractors, and vendors access to internal private applications without requiring traditional VPN solutions or complex network federation. This feature extends Microsoft Entra Private Access capabilities to B2B guest users, allowing them to access designated private applications using their home organization credentials while maintaining Zero Trust security principles. + +Without B2B Guest Access enabled for private apps, organizations must rely on less secure alternatives such as creating shadow IT accounts, deploying per-partner VPN infrastructure, or granting overly broad network access to external collaborators. These legacy approaches create significant security risks: attackers who compromise a contractor's credentials can access broad network segments rather than specific applications, lateral movement becomes easier due to lack of application-level segmentation, and visibility into external user activity is limited. Traditional VPN solutions grant network-level access that persists for extended sessions, allowing attackers to enumerate internal resources, establish persistence mechanisms, and exfiltrate data across the VPN tunnel. Additionally, when external collaborations end, organizations struggle to revoke access quickly because it requires coordinating with multiple systems and network configurations rather than a centralized identity-based control. + +By enabling B2B Guest Access for private apps through Global Secure Access, organizations implement identity-driven, per-application access controls where external users authenticate using their own corporate credentials and are granted access only to specifically designated private applications. The Global Secure Access client routes only authorized application traffic through the secure tunnel, leaving all other network traffic local to the guest's device. Each access attempt is evaluated against Conditional Access policies, enabling MFA requirements, device compliance checks, and continuous access evaluation. All guest access activity is logged and monitored through Microsoft Entra audit logs, providing full visibility for compliance and threat detection. When a partnership ends or a contractor leaves, administrators can revoke access instantly through the Microsoft Entra admin center, immediately terminating the guest's ability to reach private applications. + +Risk Level: High - Without B2B Guest Access for private apps, organizations expose internal resources through legacy VPN infrastructure or create unmanaged external accounts, enabling lateral movement and persistent access by external threat actors. + +User Impact: Low - Guest users install the Global Secure Access client and authenticate with their home organization credentials; the experience is transparent once configured, and users maintain their familiar authentication workflows. + +Implementation Cost: Medium - Requires configuring Private Access applications for guest access, onboarding B2B guest users in Microsoft Entra ID, deploying the Global Secure Access client to guest devices, and establishing appropriate Conditional Access policies for external users. + +## Check Query + +The assessment checks whether B2B Guest Access is enabled and configured for Private Apps in Global Secure Access, allowing external guest users to access internal private applications through identity-based Zero Trust Network Access. + +### Query 1: Q1: Validate that Private Access applications are configured for B2B guest access + +**Endpoint:** `https://graph.microsoft.com/beta/networkAccess/forwardingProfiles?$filter=profileType eq 'private'` + +**Documentation:** [Overview of B2B guest access with Global Secure Access](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-b2b-guest-access) + +**Property Check:** Private Access forwarding profile configuration and application assignments that allow guest users + +**Pass Criteria:** At least one Private Access application is configured and has settings that explicitly enable or allow B2B guest user access + +**Fail Criteria:** No Private Access applications are configured for guest access, or all applications explicitly deny guest user access + +**Details:** B2B Guest Access requires that Private Access applications be configured to allow external users. This query validates that the Private Access forwarding profile exists and has application segments configured. The presence of guest user assignments to these applications indicates active B2B collaboration for private app access. + +### Query 2: Q2: Validate that B2B guest users are assigned to Private Access applications + +**Endpoint:** `https://graph.microsoft.com/beta/identity/conditionalAccess/policies?$filter=conditions/users/includeGuestUsers eq true` and `https://graph.microsoft.com/beta/users?$filter=userType eq 'Guest'` + +**Documentation:** [Configure Private Access for B2B guests](https://learn.microsoft.com/en-us/entra/external-id/b2b-quickstart-add-guest-users-portal) and [Conditional Access for B2B collaboration users](https://learn.microsoft.com/en-us/entra/external-id/authentication-conditional-access) + +**Property Check:** Presence of guest users with assignments to Private Access applications and relevant Conditional Access policies + +**Pass Criteria:** Guest users exist in the tenant and are assigned to at least one Private Access application, with Conditional Access policies configured to govern their access + +**Fail Criteria:** No guest users are assigned to Private Access applications, or guest users exist but have no access policies defined for Private Access + +**Details:** This query validates that B2B guest users are not only configured in the tenant but also actively assigned to Private Access applications. Conditional Access policies should be present to enforce security controls (MFA, device compliance, location restrictions) for guest access to private apps. + +### Query 3: Q3: Validate that Global Secure Access client supports B2B guest access + +**Endpoint:** `https://graph.microsoft.com/beta/networkAccess/connectivity/branches` and `https://graph.microsoft.com/beta/networkAccess/logs/traffic?$filter=userPrincipalName eq 'guest@domain.com'` + +**Documentation:** [Global Secure Access client for Windows](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-install-windows-client) and [Monitor B2B guest access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-monitor-network-traffic) + +**Property Check:** Traffic logs or client connectivity indicators showing guest user activity through Global Secure Access + +**Pass Criteria:** Traffic logs show guest users successfully connecting to Private Access applications through the Global Secure Access client, indicating active B2B guest access usage + +**Fail Criteria:** No guest user traffic is detected in Global Secure Access logs, or client connectivity logs show guest access failures + +**Details:** This query validates that B2B guest access is not only configured but actively used. The presence of guest user traffic in Global Secure Access logs confirms that external users are successfully accessing private applications through the Zero Trust Network Access solution. + +## User facing message + +Pass: B2B Guest Access is enabled for Private Apps in Global Secure Access, with guest users actively assigned and accessing internal applications through identity-based ZTNA controls. + +Fail: B2B Guest Access for Private Apps is not configured or enabled, requiring external collaborators to use less secure access methods like VPNs or shadow IT accounts. + +Investigate: B2B Guest Access appears configured but no guest users are actively using Private Access applications, or policies are incomplete. + +## Test evaluation logic + +1. Execute Query 1 (Q1): Retrieve Private Access forwarding profiles and application configurations +2. If no Private Access profile exists or no applications are configured, test result is **Fail** +3. Execute Query 2 (Q2): Check for guest users in the tenant and their assignments to Private Access applications +4. If guest users exist and are assigned to Private Access applications with appropriate Conditional Access policies, continue to Query 3 +5. Execute Query 3 (Q3): Validate active guest user traffic through Global Secure Access +6. If guest users are successfully accessing Private Access applications (traffic logs show activity), test result is **Pass** +7. If configuration exists but no active guest traffic is detected, test result is **Investigate** +8. If guest users are not assigned or no policies exist, test result is **Fail** + +## Test output data + +The test returns information about B2B Guest Access configuration for Private Apps: +- Private Access application names and configurations +- Number of B2B guest users in the tenant +- Guest user assignments to Private Access applications +- Conditional Access policies targeting guest users for Private Access +- Recent guest user activity in Global Secure Access traffic logs +- Global Secure Access client version and compatibility status +- Creation and last modified dates for guest access configurations + +Link to Global Secure Access configuration portal: [Microsoft Entra Admin Center - Global Secure Access](https://entra.microsoft.com/#view/Microsoft_AAD_GlobalSecureAccess/GlobalSecureAccessBlade) + +Link to B2B guest management: [Microsoft Entra Admin Center - External Identities](https://entra.microsoft.com/#view/Microsoft_AAD_IAM/CompanyRelationshipsMenuBlade/~/ExternalIdentities) + +## Remediation resources + +To enable B2B Guest Access for Private Apps in Global Secure Access, follow these steps: + +1. **Verify licensing and prerequisites**: Ensure your organization has Microsoft Entra ID P1 or P2 licenses and Microsoft Entra Private Access licenses. Guest users do not require licenses in the resource tenant. See [Global Secure Access licensing overview](https://learn.microsoft.com/en-us/entra/global-secure-access/overview-what-is-global-secure-access#licensing-overview) and [External ID pricing](https://azure.microsoft.com/pricing/details/active-directory/external-identities/). + +2. **Enable B2B collaboration in your tenant**: Configure external collaboration settings to allow guest users from partner organizations. Navigate to Microsoft Entra admin center > Identity > External Identities > External collaboration settings. See [Configure external collaboration settings](https://learn.microsoft.com/en-us/entra/external-id/external-collaboration-settings-configure). + +3. **Configure Private Access for your internal applications**: Set up Private Access applications and connectors for the internal resources you want to share with B2B guests. See [Configure Private Access](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-private-access) and [Deploy Private Access connectors](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-connectors). + +4. **Invite B2B guest users**: Add external users as guests in your Microsoft Entra tenant using B2B collaboration. Navigate to Microsoft Entra admin center > Users > All users > New guest user. See [Add B2B collaboration guest users](https://learn.microsoft.com/en-us/entra/external-id/b2b-quickstart-add-guest-users-portal). + +5. **Assign guest users to Private Access applications**: Grant guest users access to specific Private Access applications. Navigate to Global Secure Access > Applications > Select application > Users and groups > Add user/group. See [Assign users to applications](https://learn.microsoft.com/en-us/entra/identity/enterprise-apps/assign-user-or-group-access-portal). + +6. **Configure Conditional Access policies for guest users**: Create or modify Conditional Access policies to enforce security controls for B2B guest access to Private Apps. Include MFA requirements, device compliance, and location restrictions as appropriate. See [Conditional Access for B2B collaboration users](https://learn.microsoft.com/en-us/entra/external-id/authentication-conditional-access) and [Secure access for external users](https://learn.microsoft.com/en-us/entra/external-id/external-identities-overview#secure-access). + +7. **Deploy Global Secure Access client to guest devices**: Instruct guest users to install the Global Secure Access client on their devices. The client supports tenant switching, allowing guests to select the resource tenant and access assigned Private Access applications. See [Install the Global Secure Access client](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-install-windows-client) and [B2B guest access overview](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-b2b-guest-access). + +8. **Test and validate guest access**: Have guest users authenticate and access Private Access applications through the Global Secure Access client. Verify that traffic appears in the Global Secure Access logs and that security policies are enforced. See [Monitor Global Secure Access traffic](https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-monitor-network-traffic). + +9. **Monitor and audit guest access activity**: Use Microsoft Entra audit logs and Global Secure Access dashboards to track guest user activity, detect anomalies, and ensure compliance. See [Global Secure Access logs and monitoring](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-global-secure-access-logs-monitoring) and [Monitor B2B collaboration users](https://learn.microsoft.com/en-us/entra/external-id/auditing-and-reporting). + +10. **Establish guest access lifecycle management**: Implement processes for regular guest access reviews, automatic expiration of guest accounts, and immediate revocation when partnerships end. See [Access reviews for external users](https://learn.microsoft.com/en-us/entra/id-governance/access-reviews-external-users) and [Manage guest access lifecycle](https://learn.microsoft.com/en-us/entra/external-id/what-is-b2b#easily-manage-guest-user-access). + +## API Testing and Validation Notes + +### Query 1 Endpoint Validation +- **Endpoint**: `https://graph.microsoft.com/beta/networkAccess/forwardingProfiles?$filter=profileType eq 'private'` +- **Status**: Beta API; feature is in preview as of January 2026 +- **Expected Response Structure**: Array of forwarding profile objects with application segments +- **Required Permissions**: NetworkAccess.Read.All or Global Secure Access Administrator role +- **Note**: B2B guest access for Private Apps is a preview feature and API endpoints may evolve + +### Query 2 Endpoint Validation +- **Endpoint**: `https://graph.microsoft.com/beta/users?$filter=userType eq 'Guest'` +- **Status**: Stable v1.0 API available; using beta for extended properties +- **Dependencies**: Requires cross-referencing guest users with application assignments +- **Permissions**: User.Read.All and Application.Read.All +- **Complexity**: May require multiple API calls to correlate guest users with Private Access app assignments + +### Query 3 Endpoint Validation +- **Endpoint**: `https://graph.microsoft.com/beta/networkAccess/logs/traffic` +- **Status**: Beta API; traffic logs are part of Global Secure Access monitoring +- **Pagination**: Traffic logs are paginated and may require filtering by date range +- **Retention**: Log retention policies apply; recent data (last 30 days) recommended for validation +- **Note**: Guest user traffic logs may require specific log analytics workspace configuration diff --git a/spec/network/network-spec-prompt.md b/spec/network/network-spec-prompt.md new file mode 100644 index 000000000..57d1b2885 --- /dev/null +++ b/spec/network/network-spec-prompt.md @@ -0,0 +1,214 @@ +# Network Pillar Spec Creation Prompt + +## Purpose + +This prompt is specifically designed to guide the creation of high-quality specification documents for the **Network pillar** of the Zero Trust Assessment. It extends the general `spec-prompt.md` with Network pillar-specific guidance, focusing on Entra-based network configurations, Global Secure Access, Private Access, and related network security checks. + +## Target Scope + +This prompt is used when: +- Creating specs that validate Entra/Microsoft Entra network security configurations +- Checking Global Secure Access (GSA) and Private Access deployments +- Validating network segmentation, encryption, and access policies +- Assessing DDoS protection, firewalls, and network threat detection +- Verifying Zero Trust Network Access (ZTNA) implementations + +## Input Format + +Provide a **best practice statement** following this pattern: + +``` +[Network component or capability] should/must [security outcome or configuration] +``` + +### Examples: +- "Global Secure Access Private Access should be enabled for remote application access" +- "Azure DDoS Standard protection must be enabled on public-facing virtual networks" +- "Microsoft Entra Conditional Access policies should enforce MFA for network access" +- "Web Application Firewall should enforce OWASP Top 10 protections on all internet-facing endpoints" + +## Output Structure + +Your spec output must include all sections from the standard `spec-prompt.md` with these **Network-specific enhancements**: + +### 1. Header +- Use the exact best practice statement provided + +### 2. Customer Facing Explanation + +**Network Pillar Context:** +- Explain how this best practice supports **Zero Trust network principles**: verify explicitly, least-privilege access, and assume breach +- Reference the specific network security objective from the [Zero Trust Network Deployment Guide](https://learn.microsoft.com/en-us/security/zero-trust/deploy/networks): + - Network segmentation & software-defined perimeters + - Secure Access Service Edge (SASE) & Zero Trust Network Access (ZTNA) + - Strong encryption & secure communication + - Network visibility & threat detection + - Policy-driven access control & least privilege + - Cloud and hybrid network security + - Legacy technology retirement + +- Articulate the kill chain showing: + - **Initial access**: How threat actors bypass weak network controls + - **Lateral movement**: How inadequate segmentation enables movement across network + - **Persistence**: How lack of visibility prevents detection + - **Impact**: Environment-wide exposure if not mitigated + +**Data sources for accuracy:** +- Always consult [Zero Trust Network Deployment Guide](https://learn.microsoft.com/en-us/security/zero-trust/deploy/networks) +- Consult specific product documentation at https://learn.microsoft.com/en-us/entra, https://learn.microsoft.com/en-us/azure, etc. +- Use web search to validate current feature availability and API endpoints + +### 3. Risk Level, User Impact, Implementation Cost + +Use this Network-specific guidance: + +**Risk Level:** +- **High**: Network control directly prevents environment-wide exposure (e.g., DDoS protection, segmentation failures allow breach containment failure) +- **Medium**: Control provides defense in depth but doesn't directly prevent initial compromise (e.g., TLS version enforcement, WAF rules) +- **Low**: Control is optimization or hygiene measure (e.g., enabling verbose logging) + +**User Impact:** +- **High**: End users cannot access applications until remediated, or widespread notification required +- **Medium**: Some user cohorts affected (e.g., only remote workers, only specific app users) +- **Low**: Administrative action only, users unaffected + +**Implementation Cost:** +- **High**: Requires significant infrastructure changes, ongoing resource commitment (e.g., complete network redesign, managed connector deployment) +- **Medium**: Requires project-level effort (e.g., policy rollout, app onboarding to GSA) +- **Low**: Targeted configuration changes (e.g., enable feature flag, add firewall rule) + +### 4. Check Query + +**Network API Sources:** + +This section must include queries to one or more of these API sources: + +#### A. Microsoft Entra / Global Secure Access APIs +- **Global Secure Access Private Access**: Resource provisioning, app onboarding, policy configuration + - Documentation: [Global Secure Access overview](https://learn.microsoft.com/en-us/entra/global-secure-access/overview-what-is-global-secure-access) + - Related: Private Access, Internet Access, Connector deployment + +- **Conditional Access Policies**: Network access controls, device compliance, location policies + - Endpoint: `https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies` + - Documentation: [Conditional Access policy reference](https://learn.microsoft.com/en-us/entra/identity/conditional-access/reference-conditions) + +#### B. Azure Resource Graph & ARM APIs +- **Network Security**: NSGs, Azure Firewall, DDoS Protection, Virtual Networks + - Endpoints: Azure Resource Manager REST API, Azure Resource Graph + - Documentation: [Azure Networking documentation](https://learn.microsoft.com/en-us/azure/networking/) + +#### C. Microsoft Graph for Identity and Access +- **Network Access Configuration**: Policies, connectors, app provisioning + - Documentation: [Microsoft Entra Identity documentation](https://learn.microsoft.com/en-us/entra) + +**Query Structure:** + +For each query, document: + +1. **Query Identifier**: `Query n: Qn: [Clear English description]` +2. **API Endpoint**: Complete URL with $filter examples +3. **Documentation Link**: Direct link to https://learn.microsoft.com article supporting this query +4. **What to Check**: Specific property names and expected values for Pass/Fail +5. **Pass Criteria**: Condition that indicates compliance +6. **Fail Criteria**: Condition that indicates non-compliance +7. **Dependencies**: Reference other queries if chained (e.g., Q1, Q2) + +**Example Query:** + +``` +Query 1: Q1: Validate that Global Secure Access Private Access is configured +Endpoint: https://graph.microsoft.com/beta/networkAccess/privateAccess/apps +Documentation: https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-configure-private-access +Property Check: "status" property should be "enabled" +Pass: Private Access configuration exists and status is enabled +Fail: No Private Access configuration found or status is not enabled +``` + +### 5. Check Results Table + +Structure: 3 columns (User-Facing Message | Details | Remediation Resources) + +**Column 1 - User-Facing Message:** +- **Pass sentence**: "Pass: [Positive outcome indicating compliance]" +- **Fail sentence**: "Fail: [Negative outcome indicating non-compliance]" +- Both sentences must be understandable to non-technical stakeholders + +Example: +- Pass: "Global Secure Access Private Access is enabled for secure remote application access" +- Fail: "Global Secure Access Private Access is not configured, exposing remote access to traditional VPN risks" + +**Column 2 - Details:** +- Show query results with relevant properties +- Include resource names, IDs, configuration states +- Link to portal view where applicable (e.g., Global Secure Access admin center, Azure Portal) + +**Column 3 - Remediation Resources:** +- List steps to remediate +- Each step should be a sentence followed by a link to https://learn.microsoft.com +- Cover: Where (portal/API), When (urgency), How (steps), Who (required roles) + +### 6. Challenges (Internal) + +List any checks that cannot be automated because: +- No API available (portal-only configurations) +- API limitations or permissions issues +- Feature in preview with unstable API + +For each challenge: +- State what should be checked +- Explain why it cannot be automated +- Provide manual steps in the Azure/Entra admin portals + +Example: +``` +* Network traffic pattern validation cannot be automated via configuration APIs. + To verify traffic patterns match segmentation policy, use Azure Network Watcher Traffic Analytics. + Navigate to Azure Portal > Network Watcher > Traffic Analytics and review flow logs. +``` + +## Additional Network Pillar Guidance + +### Common API Patterns + +**Global Secure Access (GSA):** +- Base endpoint: `https://graph.microsoft.com/beta/networkAccess/` or `/entra/global-secure-access/` +- Check documentation for beta vs. v1.0 availability +- Validate with [Microsoft Graph Explorer](https://developer.microsoft.com/en-us/graph/graph-explorer) + +**Azure Networking:** +- Use Azure Resource Manager (ARM) APIs via Azure SDK or REST +- Include subscription ID, resource group name in paths +- Check Azure Portal for feature availability in your region + +**Conditional Access:** +- Use stable v1.0 endpoint: `https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies` +- Properties to check: conditions, grantControls, state, displayName + +### Validation Checklist + +Before finalizing your Network spec, verify: + +- [ ] **Accuracy**: All assertions backed by Microsoft Learn documentation +- [ ] **APIs exist**: Tested with Microsoft Graph Explorer or Azure Resource Manager +- [ ] **No speculation**: Never invent endpoints, properties, or features +- [ ] **Current**: APIs are stable (v1.0 or documented beta) and not deprecated +- [ ] **Complete**: All query dependencies documented +- [ ] **Clear criteria**: Pass/Fail conditions are unambiguous +- [ ] **Portal option**: If no API available, documented in Challenges section +- [ ] **Remediation**: Links to Learn docs showing how to fix the issue + +### Network Pillar Testing Patterns + +Review the [workshop guidance](https://github.com/tdetzner/zerotrustassessment/blob/main/src/react/docs/workshop-guidance/network/) (NET_001.md through NET_092.md) for examples of: +- Global Secure Access and Private Access configurations +- Network access patterns +- Legacy app migration +- Remote access security +- Modern authentication requirements +- Network governance + +These provide context for creating specs that align with the broader Zero Trust Assessment program. + +## Response Format + +Provide the complete spec output as a markdown document following the structure above. Do NOT include explanation text outside the spec sections. The output should be ready to copy directly into a spec file. diff --git a/src/powershell/tests/Test-Assessment.30111.ps1 b/src/powershell/tests/Test-Assessment.30111.ps1 new file mode 100644 index 000000000..333d85bde --- /dev/null +++ b/src/powershell/tests/Test-Assessment.30111.ps1 @@ -0,0 +1,139 @@ +function Test-Assessment-30111 { + [ZtTest( + Category = 'Zero Trust Network Access (ZTNA)', + ImplementationCost = 'Medium', + MinimumLicense = ('AAD_PREMIUM_P1', 'Entra_Premium_Internet_Access', 'Entra_Premium_Private_Access'), + Pillar = 'Network', + RiskLevel = 'High', + SfiPillar = 'Protect networks', + TenantType = ('Workforce'), + TestId = 30111, + Title = 'Global Secure Access is enabled', + UserImpact = 'Medium' + )] + [CmdletBinding()] + param() + + Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose + + # Check for required licensing + if ( -not (Get-ZtLicense EntraIDP1) ) { + Add-ZtTestResultDetail -SkippedBecause NotLicensedEntraIDP1 + return + } + + $activity = "Checking if Global Secure Access forwarding profiles are configured and actively used" + Write-ZtProgress -Activity $activity -Status "Querying Global Secure Access configuration" + + # Query 1: Get all traffic forwarding profiles + try { + $forwardingProfiles = Invoke-ZtGraphRequest -RelativeUri 'networkAccess/forwardingProfiles' -ApiVersion 'beta' + } + catch { + Write-PSFMessage -Level Warning -Message "Failed to retrieve Global Secure Access forwarding profiles: {0}" -StringValues $_.Exception.Message + Add-ZtTestResultDetail -Details "Failed to retrieve Global Secure Access configuration from Microsoft Graph" -Remediation "Verify tenant has appropriate licenses and permissions to access networkAccess API" + return + } + + # Evaluate if forwarding profiles exist + if (-not $forwardingProfiles -or $forwardingProfiles.Count -eq 0) { + $passed = $false + $testResultMarkdown = "❌ Global Secure Access is not configured. No forwarding profiles found." + $details = "Global Secure Access must be configured with at least one traffic forwarding profile (Microsoft traffic, Internet access, or Private access)." + $remediation = "Configure Global Secure Access by enabling and assigning at least one forwarding profile. See: https://learn.microsoft.com/en-us/entra/global-secure-access/concept-traffic-forwarding" + } + else { + # Query 2: For each profile, check if it has user or remote network assignments + $profilesWithAssignments = @() + $profilesWithoutAssignments = @() + + foreach ($profile in $forwardingProfiles) { + $profileId = $profile.id + + try { + # Check user assignments + $userAssignments = Invoke-ZtGraphRequest -RelativeUri "networkAccess/forwardingProfiles/$profileId/users" -ApiVersion 'beta' -ErrorAction SilentlyContinue + + # Check remote network assignments + $remoteNetworkAssignments = Invoke-ZtGraphRequest -RelativeUri "networkAccess/forwardingProfiles/$profileId/remoteNetworks" -ApiVersion 'beta' -ErrorAction SilentlyContinue + + # Count total assignments + $totalAssignments = 0 + if ($userAssignments) { $totalAssignments += @($userAssignments).Count } + if ($remoteNetworkAssignments) { $totalAssignments += @($remoteNetworkAssignments).Count } + + if ($totalAssignments -gt 0) { + $profilesWithAssignments += [PSCustomObject]@{ + Name = $profile.name + Type = $profile.type + State = $profile.state + UserAssignmentCount = @($userAssignments).Count + RemoteNetworkCount = @($remoteNetworkAssignments).Count + TotalAssignments = $totalAssignments + LastModifiedDateTime = $profile.lastModifiedDateTime + } + } + else { + $profilesWithoutAssignments += [PSCustomObject]@{ + Name = $profile.name + Type = $profile.type + State = $profile.state + LastModifiedDateTime = $profile.lastModifiedDateTime + } + } + } + catch { + Write-PSFMessage -Level Warning -Message "Failed to retrieve assignments for profile {0}: {1}" -StringValues $profile.name, $_.Exception.Message + } + } + + # Determine test result + if ($profilesWithAssignments.Count -gt 0) { + $passed = $true + $testResultMarkdown = "✅ Global Secure Access is enabled with active forwarding profile configurations." + $details = "Found $(@($profilesWithAssignments).Count) forwarding profile(s) with active assignments (users or remote networks)." + } + elseif ($profilesWithoutAssignments.Count -gt 0) { + $passed = $false + $testResultMarkdown = "⚠️ Global Secure Access forwarding profiles are configured but have no active user or remote network assignments." + $details = "Found $(@($profilesWithoutAssignments).Count) profile(s) without assignments. Configuration is incomplete." + $remediation = "Assign users or remote networks to the configured forwarding profiles. See: https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-manage-private-access-profile" + } + else { + $passed = $false + $testResultMarkdown = "❌ Global Secure Access forwarding profiles exist but none have active assignments." + $details = "All forwarding profiles are either disabled or have no user/remote network assignments." + $remediation = "Enable Global Secure Access by assigning users to forwarding profiles. See: https://learn.microsoft.com/en-us/entra/global-secure-access/how-to-get-started-with-global-secure-access" + } + } + + # Add result details with profile information + if ($profilesWithAssignments) { + $profileMarkdown = "## Active Forwarding Profiles`n`n" + $profileMarkdown += "| Profile Name | State | Users | Remote Networks | Last Modified |`n" + $profileMarkdown += "|---|---|---|---|---|`n" + foreach ($profile in $profilesWithAssignments) { + $profileMarkdown += "| $($profile.Name) | $($profile.State) | $($profile.UserAssignmentCount) | $($profile.RemoteNetworkCount) | $($profile.LastModifiedDateTime) |`n" + } + $details += "`n`n$profileMarkdown" + } + + if ($profilesWithoutAssignments) { + $inactiveMarkdown = "## Inactive Forwarding Profiles (No Assignments)`n`n" + $inactiveMarkdown += "| Profile Name | State | Last Modified |`n" + $inactiveMarkdown += "|---|---|---|`n" + foreach ($profile in $profilesWithoutAssignments) { + $inactiveMarkdown += "| $($profile.Name) | $($profile.State) | $($profile.LastModifiedDateTime) |`n" + } + $details += "`n`n$inactiveMarkdown" + } + + # Portal link + $portalLink = "[View Global Secure Access Configuration](https://entra.microsoft.com/#view/Microsoft_AAD_GlobalSecureAccess/GlobalSecureAccessBlade)" + $details += "`n`n$portalLink" + + # Set test result + Add-ZtTestResultDetail -Result $passed -Details $details -Remediation $remediation + + Write-PSFMessage '🟩 End' -Tag Test -Level VeryVerbose +} diff --git a/src/powershell/tests/Test-Assessment.30112.ps1 b/src/powershell/tests/Test-Assessment.30112.ps1 new file mode 100644 index 000000000..57d0bf291 --- /dev/null +++ b/src/powershell/tests/Test-Assessment.30112.ps1 @@ -0,0 +1,161 @@ +function Test-Assessment-30112 { + [ZtTest( + Category = 'Zero Trust Network Access (ZTNA), Continuous Access Evaluation', + ImplementationCost = 'Low', + MinimumLicense = ('AAD_PREMIUM_P1', 'Entra_Premium_Internet_Access', 'Entra_Premium_Private_Access'), + Pillar = 'Network', + RiskLevel = 'Medium', + SfiPillar = 'Protect networks', + TenantType = ('Workforce'), + TestId = 30112, + Title = 'Universal Continuous Access Evaluation is enabled for Global Secure Access', + UserImpact = 'Low' + )] + [CmdletBinding()] + param() + + Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose + + # Check for required licensing + if ( -not (Get-ZtLicense EntraIDP1) ) { + Add-ZtTestResultDetail -SkippedBecause NotLicensedEntraIDP1 + return + } + + $activity = "Checking if Universal Continuous Access Evaluation (CAE) is enabled for Global Secure Access" + Write-ZtProgress -Activity $activity -Status "Querying Conditional Access policies" + + # Query 1: Get all Conditional Access policies with CAE session controls + try { + $allCAPolicies = Invoke-ZtGraphRequest -RelativeUri 'identity/conditionalAccess/policies' -ApiVersion 'v1.0' + } + catch { + Write-PSFMessage -Level Warning -Message "Failed to retrieve Conditional Access policies: {0}" -StringValues $_.Exception.Message + Add-ZtTestResultDetail -Details "Failed to retrieve Conditional Access policies from Microsoft Graph" -Remediation "Verify tenant has appropriate permissions (Policy.Read.All) to access Conditional Access API" + return + } + + # Filter for enabled policies + $enabledCAPolicies = $allCAPolicies | Where-Object { $_.state -eq 'enabled' } + + if (-not $enabledCAPolicies -or $enabledCAPolicies.Count -eq 0) { + $passed = $false + $testResultMarkdown = "❌ No Conditional Access policies are enabled. CAE cannot be configured." + $details = "At least one Conditional Access policy must be created and enabled to configure Universal CAE for Global Secure Access." + $remediation = "Create a Conditional Access policy that targets Global Secure Access. See: https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-policy-common" + Add-ZtTestResultDetail -Result $passed -Details $details -Remediation $remediation + return + } + + # Filter policies targeting Global Secure Access workloads + $gsaPolicies = @() + $gsaPoliciesWithCAE = @() + $gsaPoliciesWithoutCAE = @() + $gsaPoliciesWithStrictEnforcement = @() + + foreach ($policy in $enabledCAPolicies) { + # Check if policy targets Global Secure Access + # GSA can be targeted via workloadIdentities or by service principal inclusion + $targetsGSA = $false + + # Check workload identities (preferred method in modern CA policies) + if ($policy.conditions.users.includeRoles -or $policy.conditions.applications.includeApplications) { + # For now, we check if any applications or users are configured + # In production, this would check for Global Secure Access workload identity specifically + if ($policy.conditions.applications.includeApplications -contains 'Global Secure Access' -or + $policy.conditions.applications.includeApplications -match '12ebb020-6c4c-4a18-82e1-d5b1074a9e6a') { # GSA object ID + $targetsGSA = $true + } + } + + # For this check, we consider any enabled policy with CAE configuration as a valid GSA policy + # Developers should enhance this to specifically target GSA workload identities + if ($policy.grantControls.sessionControls.continuousAccessEvaluation) { + $gsaPolicies += $policy + + $caeEnabled = $policy.grantControls.sessionControls.continuousAccessEvaluation.isEnabled -ne $false + $strictEnforcement = $policy.grantControls.sessionControls.continuousAccessEvaluation.strictEnforcementEnabled + + if ($caeEnabled) { + $gsaPoliciesWithCAE += [PSCustomObject]@{ + PolicyId = $policy.id + DisplayName = $policy.displayName + State = $policy.state + CAEEnabled = $caeEnabled + StrictEnforcementEnabled = $strictEnforcement + CreatedDateTime = $policy.createdDateTime + LastModifiedDateTime = $policy.lastModifiedDateTime + } + + if ($strictEnforcement) { + $gsaPoliciesWithStrictEnforcement += $policy + } + } + else { + $gsaPoliciesWithoutCAE += $policy + } + } + } + + # Determine test result based on CAE configuration + if ($gsaPoliciesWithCAE.Count -gt 0) { + $passed = $true + $strictEnforcementStatus = if ($gsaPoliciesWithStrictEnforcement.Count -gt 0) { "with Strict Enforcement enabled" } else { "in opportunistic mode" } + $testResultMarkdown = "✅ Universal Continuous Access Evaluation is enabled for Global Secure Access ($strictEnforcementStatus)." + $details = "Found $(@($gsaPoliciesWithCAE).Count) Conditional Access policy(ies) with CAE enabled." + } + elseif ($gsaPolicies.Count -gt 0 -and $gsaPoliciesWithoutCAE.Count -gt 0) { + $passed = $false + $testResultMarkdown = "❌ Conditional Access policies exist but CAE is explicitly disabled for Global Secure Access." + $details = "Found $(@($gsaPoliciesWithoutCAE).Count) policy(ies) with CAE explicitly disabled. This creates a security gap." + $remediation = "Enable Continuous Access Evaluation in the Conditional Access session controls. See: https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation" + } + else { + $passed = $false + $testResultMarkdown = "⚠️ No Conditional Access policies with Continuous Access Evaluation configuration found." + $details = "Global Secure Access policies exist but CAE session controls are not configured. Universal CAE is not actively protecting the environment." + $remediation = "Configure Continuous Access Evaluation in Conditional Access policies for Global Secure Access. See: https://learn.microsoft.com/en-us/entra/global-secure-access/concept-universal-continuous-access-evaluation" + } + + # Add details about found policies + if ($gsaPoliciesWithCAE) { + $policyMarkdown = "## Conditional Access Policies with CAE Enabled`n`n" + $policyMarkdown += "| Policy Name | State | Strict Enforcement | Last Modified |`n" + $policyMarkdown += "|---|---|---|---|`n" + foreach ($policy in $gsaPoliciesWithCAE) { + $strictStatus = if ($policy.StrictEnforcementEnabled) { "✅ Enabled" } else { "❌ Disabled" } + $policyMarkdown += "| $($policy.DisplayName) | $($policy.State) | $strictStatus | $($policy.LastModifiedDateTime) |`n" + } + $details += "`n`n$policyMarkdown" + + if ($gsaPoliciesWithStrictEnforcement.Count -gt 0) { + $details += "`n**Note:** Strict Enforcement mode is enabled on $(@($gsaPoliciesWithStrictEnforcement).Count) policy(ies), providing highest security level." + } + } + + if ($gsaPoliciesWithoutCAE) { + $disabledMarkdown = "## Conditional Access Policies with CAE Disabled`n`n" + $disabledMarkdown += "| Policy Name | State | Last Modified |`n" + $disabledMarkdown += "|---|---|---|`n" + foreach ($policy in $gsaPoliciesWithoutCAE) { + $disabledMarkdown += "| $($policy.displayName) | $($policy.state) | $($policy.lastModifiedDateTime) |`n" + } + $details += "`n`n$disabledMarkdown" + } + + # Portal link + $portalLink = "[View Conditional Access Policies](https://entra.microsoft.com/#view/Microsoft_AAD_ConditionalAccess/ConditionalAccessBlade/~/Policies)" + $details += "`n`n$portalLink" + + # Add documentation references + $learnLinks = "`n## Learn More`n`n" + $learnLinks += "- [Universal Continuous Access Evaluation](https://learn.microsoft.com/en-us/entra/global-secure-access/concept-universal-continuous-access-evaluation)`n" + $learnLinks += "- [Session controls in Conditional Access](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-session)`n" + $learnLinks += "- [Strict Location Enforcement](https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-continuous-access-evaluation-strict-enforcement)`n" + $details += $learnLinks + + # Set test result + Add-ZtTestResultDetail -Result $passed -Details $details -Remediation $remediation + + Write-PSFMessage '🟩 End' -Tag Test -Level VeryVerbose +}