Back to Checks
Prowlerprowler-provider-okta
Default Global Session Policy applies a Network Zone condition aligned with the Access Control Policy
signon_global_session_policy_network_zone_enforced
Service: signonSeverity: medium
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:NotDefined
Every active Okta Global Session Policy must apply the IF User's IP is condition, mapped to a Network Zone, on its Priority 1 active rule.
Unlike the idle / lifetime / cookie STIGs, this control does not exclude the built-in Default Rule. Okta evaluates policies by group assignment. Aligns with DISA STIG V-279691.
Risk
When the Global Session Policy does not restrict access by Network Zone, every authenticated entity establishes a session regardless of source IP.
- Stolen credentials reach the Okta dashboard from any internet-routable address
- Out-of-band sessions bypass the organization's Access Control Policy
- Network anomalies cannot become deny decisions at sign-on
Run this check with Prowler
Run in Prowler CloudRun
prowler okta --checks signon_global_session_policy_network_zone_enforcedRecommendation
Configure the Priority 1 active rule in each Global Session Policy so it:
- Maps the IF User's IP is condition to a Network Zone aligned with the organization's Access Control Policy
- Uses
In zonefor allow-list zones andNot in zonefor deny-list zones - Is enabled (
ACTIVE) and evaluated before the built-inDefault Rule, or is theDefault Ruleitself
Review group assignments to confirm the rule actually governs the intended users.
Remediation
Terraform
resource "okta_policy_rule_signon" "<example_resource_name>" {
policy_id = okta_policy_signon.default.id
name = "<example_resource_name>"
status = "ACTIVE"
priority = 1 # Critical: rule must sit at Priority 1
network_connection = "ZONE" # Critical: bind the rule to a Network Zone
network_includes = [okta_network_zone.allowed.id] # Critical: zones that reflect the Access Control Policy
}Other
1Sign in to the **Okta Admin Console** as a *Super Admin*.
2Navigate to **Security** > **Networks** and define the **Network Zones** (allow / deny) that match the organization's Access Control Policy.
3Navigate to **Security** > **Global Session Policy**.
4Open the **Default Policy** (and repeat for every other active policy).
5Edit the rule that sits at **Priority 1**, or add a new one and move it to **Priority 1**.
6Under *Conditions*, set *IF User's IP is* to `In zone` (allow) or `Not in zone` (deny) and select the **Network Zone**.
7Save the rule.
Check Code
from prowler.lib.check.models import Check, CheckReportOkta
from prowler.providers.okta.services.signon.lib.signon_helpers import (
active_policies,
missing_policy_scope_finding,
no_active_policies_finding,
policy_label,
priority_one_active_rule,
)
from prowler.providers.okta.services.signon.signon_client import signon_client
from prowler.providers.okta.services.signon.signon_service import GlobalSessionPolicy
class signon_global_session_policy_network_zone_enforced(Check):
"""STIG V-279691 / OKTA-APP-003242.
Every active Global Session Policy must apply an "IF User's IP is"
condition mapped to a Network Zone on its Priority 1 active rule so
access can be allowed or denied per the organization's Access
Control Policy.
Unlike the idle / lifetime / persistent-cookie STIGs, V-279691 does
not exclude the built-in Default Rule, so a zone condition on the
Default Rule is still effective when no non-default rule sits at
Priority 1.
The check emits one finding per active policy because Okta evaluates
sign-on policies in priority order based on group assignments, and a
permissive custom policy can govern a user's session even when the
Default Policy is strict.
"""
def execute(self) -> list[CheckReportOkta]:
org_domain = signon_client.provider.identity.org_domain
missing_scope = signon_client.missing_scope.get("global_session_policies")
if missing_scope:
return [
missing_policy_scope_finding(self.metadata(), org_domain, missing_scope)
]
policies = active_policies(signon_client.global_session_policies)
if not policies:
return [
no_active_policies_finding(
self.metadata(),
org_domain,
"No active Okta Global Session Policies were returned by the API. "
"STIG V-279691 requires the policy that governs each user to map "
"User's IP to a Network Zone on its Priority 1 active rule.",
)
]
findings: list[CheckReportOkta] = []
for policy in policies:
report = CheckReportOkta(
metadata=self.metadata(), resource=policy, org_domain=org_domain
)
status, status_extended = _evaluate_policy(policy)
report.status = status
report.status_extended = status_extended
findings.append(report)
return findings
def _evaluate_policy(policy: GlobalSessionPolicy) -> tuple[str, str]:
label = policy_label(policy)
rule = priority_one_active_rule(policy)
if rule is None:
return (
"FAIL",
f"{label} has no Priority 1 active rule. STIG V-279691 requires "
"the policy to apply an IP-based Network Zone condition on its "
"Priority 1 active rule.",
)
rule_kind = (
"built-in Default Rule"
if rule.is_default or rule.name == "Default Rule"
else "non-default rule"
)
has_zones = bool(rule.network_zones_include or rule.network_zones_exclude)
if has_zones:
return (
"PASS",
f"Priority 1 active {rule_kind} '{rule.name}' in {label} maps "
"User's IP to a Network Zone.",
)
return (
"FAIL",
f"Priority 1 active {rule_kind} '{rule.name}' in {label} does not "
"map User's IP to a Network Zone. The policy cannot allow or deny "
"access based on the organization's Access Control Policy.",
)