Chapter 39: Zero Trust Implementation — From Principle to Production¶
Overview¶
Zero Trust is not a product — it is an architecture and mindset built on the principle "never trust, always verify." This chapter moves beyond Zero Trust theory to practical implementation: identity-centric access controls, micro-segmentation, device health enforcement, continuous verification, and the organizational roadmap for ZT adoption. It covers NIST SP 800-207, CISA Zero Trust Maturity Model, and real-world deployment patterns for enterprises at various maturity stages.
Learning Objectives¶
- Map NIST SP 800-207 pillars to concrete technical controls
- Design a Zero Trust architecture for an enterprise using identity, device, network, and data pillars
- Implement ZTNA to replace legacy VPN with least-privilege application access
- Configure Conditional Access policies enforcing device health and risk signals
- Apply CISA Zero Trust Maturity Model to assess current state and plan roadmap
- Measure Zero Trust program effectiveness with quantitative metrics
Prerequisites¶
- Chapter 31 (Network Security Architecture)
- Chapter 33 (Identity and Access Security)
- Chapter 13 (Security Governance, Privacy and Risk)
- Familiarity with Azure AD/Entra ID or Okta, and basic networking concepts
Zero Trust Is Not Zero Risk
Organizations frequently mistake "deploying a ZTNA product" for "achieving Zero Trust." True Zero Trust requires continuous verification across all five pillars — identity, devices, networks, applications, and data. Partial implementation creates a false sense of security. The attacker who compromises a trusted device on a "Zero Trust network" still has significant capability if device health checks are not enforced.
39.1 NIST SP 800-207 — Zero Trust Architecture¶
NIST defines Zero Trust through seven tenets:
flowchart TD
subgraph Tenets["NIST ZT Tenets"]
T1["1. All data sources and\ncomputing services are resources"]
T2["2. All communication\nsecured regardless of location"]
T3["3. Access granted per-session\nto individual resources"]
T4["4. Access determined by\ndynamic policy"]
T5["5. Monitor and measure\nintegrity of all assets"]
T6["6. Authentication and\nauthorization dynamic and strict"]
T7["7. Collect data to improve\nsecurity posture"]
end
subgraph Core["Core ZT Components"]
PE[Policy Engine\nTrust evaluation]
PA[Policy Administrator\nSession token]
EP[Policy Enforcement\nPoint — PEP]
end
Subject -->|Request| PE
PE <--> PA
PA -->|Allow/Deny| EP
EP -->|Controlled access| Resource
style PE fill:#58a6ff22,stroke:#58a6ff
style PA fill:#d2a8ff22,stroke:#d2a8ff
style EP fill:#3fb95022,stroke:#3fb950 CISA Zero Trust Maturity Model — Five Pillars¶
| Pillar | Traditional | Initial | Advanced | Optimal |
|---|---|---|---|---|
| Identity | Static passwords; no MFA | MFA enforced | Phishing-resistant MFA; risk-based | Continuous authentication; passwordless |
| Devices | No device management | MDM enrolled | Compliance required for access | Real-time health scoring; behavioral |
| Networks | Perimeter firewall; flat LAN | VLANs; basic segmentation | Micro-segmentation; ZTNA | Software-defined; identity-tagged traffic |
| Applications | VPN then all access | SSO; basic RBAC | Attribute-based access; API security | Zero standing privilege; JIT access |
| Data | Unclassified; no DLP | Classification labels | DLP enforced; encryption | Rights management; autonomous protection |
39.2 Identity Pillar — The Foundation¶
Conditional Access — Microsoft Entra ID¶
Conditional Access is the Zero Trust Policy Engine in Microsoft's stack. Every access request is evaluated against conditions before a session token is granted.
{
"displayName": "ZT-PROD-01: Require compliant device for production apps",
"state": "enabled",
"conditions": {
"users": {
"includeGroups": ["prod-users", "admins"],
"excludeUsers": ["break-glass-admin@company.com"]
},
"applications": {
"includeApplications": ["prod-erp-app-id", "prod-crm-app-id"]
},
"platforms": {
"includePlatforms": ["windows", "macOS", "iOS", "android"]
},
"locations": {
"excludeLocations": ["trusted-office-IPs"]
},
"signInRiskLevels": ["high", "medium"],
"userRiskLevels": ["high", "medium"]
},
"grantControls": {
"operator": "AND",
"builtInControls": [
"mfa",
"compliantDevice",
"domainJoinedDevice"
]
},
"sessionControls": {
"signInFrequency": {
"value": 1,
"type": "hours",
"authenticationType": "primaryAndSecondaryAuthentication",
"frequencyInterval": "everyTime"
},
"cloudAppSecurity": {
"cloudAppSecurityType": "blockDownloads"
}
}
}
Risk-Based Authentication¶
# Conceptual risk signal aggregation for Zero Trust policy engine
from dataclasses import dataclass
from enum import Enum
import math
class RiskLevel(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
@dataclass
class AuthContext:
user: str
device_compliance: bool
device_risk_score: float # 0–1 from EDR
location_known: bool
ip_reputation: float # 0–1 (1 = clean)
sign_in_risk: float # 0–1 from Identity Protection
user_risk: float # 0–1 long-term user risk
time_of_day: int # 0–23 hour
mfa_method: str # "fido2" | "totp" | "sms" | "none"
previous_session_normal: bool
class ZeroTrustPolicyEngine:
MFA_STRENGTH = {"fido2": 1.0, "totp": 0.7, "push": 0.6, "sms": 0.3, "none": 0.0}
def evaluate(self, ctx: AuthContext) -> dict:
risk = self._calculate_risk(ctx)
mfa_strength = self.MFA_STRENGTH.get(ctx.mfa_method, 0)
decision = self._decide(risk, ctx, mfa_strength)
return {
"risk_score": round(risk, 2),
"risk_level": self._level(risk).value,
"mfa_strength": mfa_strength,
"decision": decision,
"required_controls": self._required_controls(risk, ctx)
}
def _calculate_risk(self, ctx: AuthContext) -> float:
score = 0.0
if not ctx.device_compliance: score += 0.30
if ctx.device_risk_score > 0.5: score += ctx.device_risk_score * 0.20
if not ctx.location_known: score += 0.15
if ctx.ip_reputation < 0.5: score += (1 - ctx.ip_reputation) * 0.20
score += ctx.sign_in_risk * 0.25
score += ctx.user_risk * 0.20
# After-hours penalty
if ctx.time_of_day < 6 or ctx.time_of_day > 22:
score += 0.05
if not ctx.previous_session_normal: score += 0.10
return min(score, 1.0)
def _decide(self, risk: float, ctx: AuthContext, mfa: float) -> str:
if risk > 0.80: return "BLOCK"
if risk > 0.60 and mfa < 0.7: return "REQUIRE_STRONG_MFA"
if risk > 0.40 and not ctx.device_compliance: return "BLOCK_DOWNLOADS"
if risk > 0.20: return "REQUIRE_MFA"
return "ALLOW"
def _level(self, score: float) -> RiskLevel:
if score > 0.75: return RiskLevel.CRITICAL
if score > 0.50: return RiskLevel.HIGH
if score > 0.25: return RiskLevel.MEDIUM
return RiskLevel.LOW
def _required_controls(self, risk: float, ctx: AuthContext) -> list:
controls = []
if risk > 0.20: controls.append("MFA")
if risk > 0.40: controls.append("Compliant device required")
if risk > 0.60: controls.append("Phishing-resistant MFA (FIDO2)")
if risk > 0.75: controls.append("Block all access; investigate")
return controls
39.3 Device Pillar — Endpoint Health Enforcement¶
Device Compliance Policy (Microsoft Intune)¶
{
"displayName": "ZT-DEVICE-PROD: Production Workstation Compliance",
"scheduledActionsForRule": [
{"ruleName": "NonCompliantRule", "scheduledActionConfigurations": [
{"actionType": "block", "gracePeriodHours": 0}
]}
],
"deviceCompliancePolicySettings": {
"osMinimumVersion": "10.0.22631",
"bitLockerEnabled": true,
"secureBootEnabled": true,
"codeIntegrityEnabled": true,
"storageRequireEncryption": true,
"activeFirewallRequired": true,
"defenderEnabled": true,
"defenderVersion": "4.18.2401",
"rtpEnabled": true,
"antivirusRequired": true,
"antiSpywareRequired": true,
"passwordRequired": true,
"passwordMinimumLength": 14,
"passwordExpirationDays": 365,
"passwordMinimumCharacterSetCount": 3,
"deviceThreatProtectionRequiredSecurityLevel": "medium"
}
}
Microsoft Defender for Endpoint — Device Risk Score Integration¶
import requests
class DeviceRiskIntegration:
"""
Pull MDE device risk scores for use in Zero Trust policy decisions.
Integrates with Conditional Access Named Locations or MCAS policies.
"""
def __init__(self, tenant_id: str, client_id: str, client_secret: str):
self.base_url = "https://api.securitycenter.microsoft.com/api"
self.token = self._get_token(tenant_id, client_id, client_secret)
def _get_token(self, tenant_id, client_id, client_secret) -> str:
resp = requests.post(
f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token",
data={"grant_type": "client_credentials",
"client_id": client_id,
"client_secret": client_secret,
"scope": "https://api.securitycenter.microsoft.com/.default"}
)
return resp.json()["access_token"]
def get_high_risk_devices(self) -> list:
"""Fetch all devices with HIGH or CRITICAL risk scores."""
resp = requests.get(
f"{self.base_url}/machines?$filter=riskScore in ('High','Critical')"
"&$select=id,computerDnsName,riskScore,healthStatus,lastSeen",
headers={"Authorization": f"Bearer {self.token}"}
)
return resp.json().get("value", [])
def isolate_device(self, machine_id: str, reason: str) -> dict:
"""Isolate a compromised device — removes from network."""
resp = requests.post(
f"{self.base_url}/machines/{machine_id}/isolate",
headers={"Authorization": f"Bearer {self.token}",
"Content-Type": "application/json"},
json={"Comment": reason, "IsolationType": "Selective"}
)
return resp.json()
39.4 Network Pillar — Micro-Segmentation and ZTNA¶
Software-Defined Micro-Segmentation¶
Traditional networks trust east-west traffic within VLANs. Micro-segmentation applies Zero Trust controls to lateral traffic.
# VMware NSX-T micro-segmentation policy (YAML representation)
# Denies all east-west traffic by default; only named flows permitted
security_policies:
- name: ZT-MICROSEG-APP-TIER
category: application
stateful: true
default_rule: DENY # Zero Trust default deny
rules:
- name: allow-web-to-app
source_groups: ["web-tier"]
destination_groups: ["app-tier"]
services: ["HTTPS", "HTTP"]
action: ALLOW
logging: true
- name: allow-app-to-db
source_groups: ["app-tier"]
destination_groups: ["db-tier"]
services: ["MySQL-3306", "MSSQL-1433"]
action: ALLOW
logging: true
- name: block-web-to-db
source_groups: ["web-tier"]
destination_groups: ["db-tier"]
services: ["ANY"]
action: DROP
logging: true
comment: "Web tier must not directly reach DB — enforce 3-tier separation"
- name: allow-monitoring
source_groups: ["monitoring-servers"]
destination_groups: ["ANY"]
services: ["SNMP", "WMI", "SSH"]
action: ALLOW
logging: false
ZTNA — Replace VPN with Identity-Aware Access¶
sequenceDiagram
participant U as User (Remote)
participant ZC as ZTNA Client
participant CP as Control Plane\n(Cloudflare/Zscaler)
participant DP as Data Plane
participant APP as Internal App
U->>ZC: Access request for app.corp.com
ZC->>CP: Auth: identity + device posture
CP->>CP: Evaluate policy:\n- Identity verified? ✓\n- Device compliant? ✓\n- MFA passed? ✓\n- Location allowed? ✓
CP->>DP: Grant: create ephemeral tunnel
DP->>APP: Forward request
APP->>DP: Response
DP->>U: Response via encrypted tunnel
Note over CP: Continuous re-evaluation\nevery 60 seconds
CP->>ZC: Session revoked\n(device became non-compliant)
ZC->>U: Access terminated Cloudflare Access policy (YAML):
# Cloudflare Zero Trust — Access Policy for production ERP
application:
name: "Production ERP"
domain: "erp.corp.example.com"
type: self_hosted
session_duration: "4h"
enable_binding_cookie: true
policies:
- name: "Employees with compliant devices"
decision: allow
precedence: 1
include:
- email_domain: "company.com"
- group:
- "erp-users"
require:
- device_posture:
- "windows-compliant"
- "macos-compliant"
- auth_method: "mfa"
- name: "Block risky sign-ins"
decision: block
precedence: 2
include:
- ip:
- "0.0.0.0/0"
require:
- identity_provider_risk: "high"
39.5 Data Pillar — Classification and Protection¶
Microsoft Purview Sensitivity Labels¶
# Deploy sensitivity labels for Zero Trust data protection
# Requires Microsoft 365 E3/E5
# Create label hierarchy
New-Label -DisplayName "Public" -Name "Public" `
-Tooltip "Information approved for public distribution"
New-Label -DisplayName "Internal" -Name "Internal" `
-Tooltip "Internal use only — no external sharing"
New-Label -DisplayName "Confidential" -Name "Confidential" `
-Tooltip "Business-sensitive — requires business justification to share"
New-Label -DisplayName "Highly Confidential" -Name "HighlyConfidential" `
-Tooltip "Restricted — minimal distribution, executive approval required"
# Configure auto-labeling for Confidential content
New-LabelPolicy -Name "ZT-AutoLabel-Confidential" `
-Labels "Confidential" `
-Settings @{
autoLabelingPolicyMode = "Auto"
sensitiveInfoTypes = @(
"Credit Card Number",
"U.S. Social Security Number",
"U.S. Bank Account Number",
"International Banking Account Number (IBAN)"
)
}
# Apply encryption and access restrictions for Highly Confidential
Set-Label -Identity "HighlyConfidential" `
-EncryptionEnabled $true `
-EncryptionProtectionType "UserDefined" `
-EncryptionOfflineAccessDays 0 `
-EncryptionContentExpiredOnDateInDaysOrNever "180" `
-SiteAndGroupProtectionEnabled $true `
-SiteAndGroupProtectionBlockAccess $false `
-SiteAndGroupProtectionAllowFullAccess $false
39.6 Zero Trust Implementation Roadmap¶
gantt
dateFormat YYYY-MM
axisFormat %b %Y
section Phase 1 — Identity (Months 1-3)
Enforce MFA for all users :p1a, 2026-04, 4w
Deploy phishing-resistant MFA :p1b, after p1a, 4w
Conditional Access baseline :p1c, after p1b, 6w
Privileged access workstations :p1d, after p1b, 4w
section Phase 2 — Devices (Months 4-6)
MDM enrollment all endpoints :p2a, 2026-07, 4w
Compliance policies deployed :p2b, after p2a, 3w
Device risk in Conditional Access :p2c, after p2b, 3w
EDR on all endpoints :p2d, 2026-07, 6w
section Phase 3 — Network (Months 7-9)
ZTNA pilot (50 users) :p3a, 2026-10, 4w
VPN phaseout plan :p3b, after p3a, 2w
Micro-segmentation critical apps :p3c, after p3a, 6w
DNS filtering deploy :p3d, 2026-10, 3w
section Phase 4 — Applications (Months 10-12)
SSO all applications :p4a, 2027-01, 6w
CASB for cloud apps :p4b, after p4a, 4w
Privileged access JIT :p4c, 2027-01, 4w
section Phase 5 — Data (Year 2)
Data classification rollout :p5a, 2027-04, 8w
DLP policies enforce :p5b, after p5a, 6w
Rights management sensitive data :p5c, after p5b, 8w Phased Controls Mapping¶
| Phase | Pillar | Key Controls | CISA Maturity Advance |
|---|---|---|---|
| 1 | Identity | MFA everywhere, FIDO2, risk-based CA | Traditional → Initial |
| 2 | Devices | MDM enrollment, compliance policies, EDR | Initial → Advanced |
| 3 | Networks | ZTNA pilot, micro-segmentation, DNS filter | Initial → Advanced |
| 4 | Applications | SSO consolidation, CASB, PAM/JIT | Advanced → Optimal |
| 5 | Data | Classification, DLP, rights management | Advanced → Optimal |
39.7 Zero Trust Metrics¶
ZT_METRICS = {
# Identity
"mfa_adoption_rate": {
"formula": "users_with_mfa / total_users * 100",
"target": 100,
"current_baseline": 67,
"unit": "%"
},
"phishing_resistant_mfa_rate": {
"formula": "users_with_fido2_or_cert / total_users * 100",
"target": 80,
"unit": "%"
},
"conditional_access_coverage": {
"formula": "apps_under_ca / total_apps * 100",
"target": 100,
"unit": "%"
},
# Devices
"device_compliance_rate": {
"formula": "compliant_devices / enrolled_devices * 100",
"target": 95,
"unit": "%"
},
"edr_coverage": {
"formula": "edr_installed / total_endpoints * 100",
"target": 99,
"unit": "%"
},
# Networks
"vpn_to_ztna_migration": {
"formula": "ztna_users / total_remote_users * 100",
"target": 100,
"unit": "%"
},
"east_west_segmented_flows": {
"formula": "microsegmented_flows / total_lateral_flows * 100",
"target": 85,
"unit": "%"
},
# Applications
"sso_adoption": {
"formula": "apps_in_sso / total_apps * 100",
"target": 95,
"unit": "%"
},
"privileged_standing_access": {
"formula": "priv_accounts_with_standing_access / total_priv_accounts",
"target": 0,
"note": "Lower is better — target zero standing privilege"
},
# Data
"classified_data_pct": {
"formula": "labeled_documents / total_documents * 100",
"target": 90,
"unit": "%"
},
"dlp_policy_coverage": {
"formula": "data_channels_with_dlp / total_channels * 100",
"target": 100,
"unit": "%"
}
}
def generate_zt_scorecard(current_values: dict) -> None:
print(f"\n{'Metric':<40} {'Current':>10} {'Target':>10} {'Status':>10}")
print("-" * 75)
for metric, config in ZT_METRICS.items():
current = current_values.get(metric, 0)
target = config.get("target", 100)
# For "lower is better" metrics
lower_better = config.get("note", "").startswith("Lower")
if lower_better:
ok = current <= target
else:
ok = current >= target * 0.9 # Within 10% of target = acceptable
status = "✓ OK" if ok else "✗ GAP"
print(f"{metric:<40} {str(current):>10} {str(target):>10} {status:>10}")
Exam Prep & Certifications¶
Relevant Certifications
The topics in this chapter align with the following certifications:
- CISSP — Domains: Security Architecture, Identity and Access Management
- CCSP — Domains: Cloud Security Architecture, Platform Security
- Forrester ZTX — Domains: Zero Trust Architecture, Micro-Segmentation, Identity-Centric Security
Nexus SecOps Benchmark Controls¶
| Control ID | Description | Validation |
|---|---|---|
| Nexus SecOps-ZT-01 | MFA enforced for all users; FIDO2/certificate for privileged | Conditional Access report; auth method breakdown |
| Nexus SecOps-ZT-02 | Device compliance required for production app access | Intune compliance policy; CA grant controls |
| Nexus SecOps-ZT-03 | ZTNA deployed for remote access; VPN retirement roadmap | ZTNA user adoption metric; VPN decommission plan |
| Nexus SecOps-ZT-04 | Micro-segmentation applied to all production application tiers | NSX/Illumio policy; lateral traffic blocked evidence |
| Nexus SecOps-ZT-05 | No standing privileged access — PAM JIT for all admin functions | Vault/CyberArk JIT audit log; zero permanent DA |
| Nexus SecOps-ZT-06 | Data classified and labeled; DLP enforced on all egress channels | Purview label report; DLP policy coverage |
Key Terms¶
Conditional Access — Microsoft's Zero Trust policy engine evaluating identity, device, location, and risk signals to grant or deny session tokens.
CISA Zero Trust Maturity Model — Five-pillar framework (Identity, Devices, Networks, Applications, Data) with Traditional → Initial → Advanced → Optimal maturity levels.
Device Compliance — Attestation that an endpoint meets defined security requirements (encryption, patch level, AV) before being granted access.
JIT (Just-in-Time) Access — Privileged access granted only when needed, for the minimum duration required, eliminating standing privilege.
Micro-segmentation — Applying network access controls at the workload level (not just VLAN), preventing lateral movement within a network segment.
NIST SP 800-207 — NIST's foundational Zero Trust Architecture publication defining seven tenets and the Policy Engine/Administrator/Enforcement Point model.
Policy Enforcement Point (PEP) — The component that grants or denies access to resources based on decisions from the Policy Engine.
Zero Standing Privilege — Security principle eliminating permanently-granted privileged accounts; all privilege is time-limited and context-specific.
ZTNA (Zero Trust Network Access) — Architecture providing application-specific remote access based on identity and device health, replacing VPN's network-level access.