Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Implementing device posture assessment as a zero trust access control by integrating endpoint health signals from CrowdStrike ZTA, Microsoft Intune, and Jamf into conditional access policies that enforce compliance before granting resource access.
.claude/skills/implementing-device-posture-assessment-in-zero-trust/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-03 | ✗→✓ | ▲ Improved | — | — |
| case-22 | ✗→✓ | ▲ Improved | — | — |
Do not use for IoT or headless devices that cannot run posture agents, as a standalone security control without identity verification, or when real-time posture data is unavailable and stale compliance data would create false trust.
Establish minimum security requirements for each device category.
powershell# Microsoft Intune: Create device compliance policy via Graph API Connect-MgGraph -Scopes "DeviceManagementConfiguration.ReadWrite.All" # Windows 10/11 Compliance Policy $compliancePolicy = @{ "@odata.type" = "#microsoft.graph.windows10CompliancePolicy" displayName = "Zero Trust - Windows Compliance" description = "Minimum device requirements for zero trust access" osMinimumVersion = "10.0.19045" bitLockerEnabled = $true secureBootEnabled = $true codeIntegrityEnabled = $true tpmRequired = $true antivirusRequired = $true antiSpywareRequired = $true defenderEnabled = $true firewallEnabled = $true passwordRequired = $true passwordMinimumLength = 12 passwordRequiredType = "alphanumeric" storageRequireEncryption = $true scheduledActionsForRule = @( @{ ruleName = "PasswordRequired" scheduledActionConfigurations = @( @{ actionType = "block" gracePeriodHours = 24 notificationTemplateId = "" notificationMessageCCList = @() } ) } ) } New-MgDeviceManagementDeviceCompliancePolicy -BodyParameter $compliancePolicy # macOS Compliance Policy via Jamf Pro API curl -X POST "https://jamf.company.com/api/v1/compliance-policies" \ -H "Authorization: Bearer ${JAMF_TOKEN}" \ -H "Content-Type: application/json" \ --data '{ "name": "Zero Trust - macOS Compliance", "rules": [ {"type": "os_version", "operator": ">=", "value": "14.0"}, {"type": "filevault_enabled", "value": true}, {"type": "firewall_enabled", "value": true}, {"type": "gatekeeper_enabled", "value": true}, {"type": "sip_enabled", "value": true}, {"type": "auto_update_enabled", "value": true}, {"type": "screen_lock_timeout", "operator": "<=", "value": 300}, {"type": "falcon_sensor_running", "value": true} ] }'
Enable ZTA scoring and configure score thresholds for access tiers.
bash# CrowdStrike Falcon API: Query ZTA scores for all endpoints curl -X GET "https://api.crowdstrike.com/zero-trust-assessment/entities/assessments/v1?ids=${DEVICE_AID}" \ -H "Authorization: Bearer ${CS_TOKEN}" \ -H "Content-Type: application/json" # Response includes: # { # "aid": "device-agent-id", # "assessment": { # "overall": 82, # "os": 90, # "sensor_config": 85, # "version": "7.14.16703" # }, # "assessment_items": { # "os_signals": [ # {"signal_id": "firmware_protection", "meets_criteria": "yes"}, # {"signal_id": "disk_encryption", "meets_criteria": "yes"}, # {"signal_id": "kernel_protection", "meets_criteria": "yes"} # ], # "sensor_signals": [ # {"signal_id": "sensor_version", "meets_criteria": "yes"}, # {"signal_id": "prevention_policies", "meets_criteria": "yes"} # ] # } # } # Define ZTA score thresholds for access tiers # Tier 1 (Basic Access): ZTA >= 50 # Tier 2 (Standard Access): ZTA >= 65 # Tier 3 (Sensitive Access): ZTA >= 80 # Tier 4 (Critical Access): ZTA >= 90 # Query devices below minimum threshold curl -X GET "https://api.crowdstrike.com/zero-trust-assessment/queries/assessments/v1?filter=assessment.overall:<50" \ -H "Authorization: Bearer ${CS_TOKEN}" # CrowdStrike ZTA signals evaluated: # - OS patch level and version # - Disk encryption (BitLocker/FileVault) # - Sensor version and configuration # - Prevention policy enforcement # - Firmware protection (Secure Boot) # - Kernel protection (SIP, Code Integrity) # - Firewall status
Create conditional access policies that require compliant devices.
powershell# Create Conditional Access policy requiring compliant device Connect-MgGraph -Scopes "Policy.ReadWrite.ConditionalAccess" $caPolicy = @{ displayName = "Zero Trust - Require Compliant Device" state = "enabled" conditions = @{ applications = @{ includeApplications = @("All") } users = @{ includeUsers = @("All") excludeGroups = @("BreakGlass-Admins-Group-ID") } platforms = @{ includePlatforms = @("all") } clientAppTypes = @("browser", "mobileAppsAndDesktopClients") } grantControls = @{ operator = "AND" builtInControls = @("mfa", "compliantDevice") } sessionControls = @{ signInFrequency = @{ value = 4 type = "hours" isEnabled = $true authenticationType = "primaryAndSecondaryAuthentication" frequencyInterval = "timeBased" } persistentBrowser = @{ mode = "never" isEnabled = $true } } } New-MgIdentityConditionalAccessPolicy -BodyParameter $caPolicy # Create risk-based policy using device compliance + sign-in risk $riskPolicy = @{ displayName = "Zero Trust - Block High Risk Sign-Ins on Non-Compliant Devices" state = "enabled" conditions = @{ applications = @{ includeApplications = @("All") } users = @{ includeUsers = @("All") } signInRiskLevels = @("high", "medium") devices = @{ deviceFilter = @{ mode = "include" rule = "device.isCompliant -ne True" } } } grantControls = @{ operator = "OR" builtInControls = @("block") } } New-MgIdentityConditionalAccessPolicy -BodyParameter $riskPolicy
Set up Okta device trust policies using CrowdStrike posture signals.
bash# Okta: Configure CrowdStrike device trust integration # Admin Console > Security > Device Integrations > Add Integration # Okta API: Create device assurance policy curl -X POST "https://company.okta.com/api/v1/device-assurances" \ -H "Authorization: SSWS ${OKTA_API_TOKEN}" \ -H "Content-Type: application/json" \ --data '{ "name": "Corporate Device Assurance", "platform": "WINDOWS", "osVersion": { "minimum": "10.0.19045" }, "diskEncryptionType": { "include": ["ALL_INTERNAL_VOLUMES"] }, "screenLockType": { "include": ["BIOMETRIC", "PASSCODE"] }, "secureHardwarePresent": true, "thirdPartySignalProviders": { "dtc": { "browserVersion": { "minimum": "120.0" }, "builtInDnsClientEnabled": true, "chromeRemoteDesktopAppBlocked": true, "crowdStrikeCustomerId": "CS_CUSTOMER_ID", "crowdStrikeAgentId": "REQUIRED", "crowdStrikeVerifiedState": { "include": ["RUNNING"] } } } }' # Create Okta authentication policy with device assurance curl -X POST "https://company.okta.com/api/v1/policies" \ -H "Authorization: SSWS ${OKTA_API_TOKEN}" \ -H "Content-Type: application/json" \ --data '{ "name": "Zero Trust Application Policy", "type": "ACCESS_POLICY", "conditions": null, "rules": [ { "name": "Managed Device Access", "conditions": { "device": { "assurance": { "include": ["DEVICE_ASSURANCE_POLICY_ID"] }, "managed": true, "registered": true }, "people": { "groups": {"include": ["EMPLOYEES_GROUP_ID"]} } }, "actions": { "appSignOn": { "access": "ALLOW", "verificationMethod": { "factorMode": "1FA", "type": "ASSURANCE" } } } }, { "name": "Unmanaged Device - Block", "conditions": { "device": { "managed": false } }, "actions": { "appSignOn": { "access": "DENY" } } } ] }'
Set up real-time monitoring of device compliance state changes.
python#!/usr/bin/env python3 """Monitor device posture compliance drift in real-time.""" import requests import time import json from datetime import datetime, timezone CROWDSTRIKE_BASE = "https://api.crowdstrike.com" INTUNE_BASE = "https://graph.microsoft.com/v1.0" def get_cs_token(client_id: str, client_secret: str) -> str: resp = requests.post(f"{CROWDSTRIKE_BASE}/oauth2/token", data={ "client_id": client_id, "client_secret": client_secret }) return resp.json()["access_token"] def get_low_zta_devices(token: str, threshold: int = 50) -> list: resp = requests.get( f"{CROWDSTRIKE_BASE}/zero-trust-assessment/queries/assessments/v1", headers={"Authorization": f"Bearer {token}"}, params={"filter": f"assessment.overall:<{threshold}", "limit": 100} ) return resp.json().get("resources", []) def get_intune_noncompliant(token: str) -> list: resp = requests.get( f"{INTUNE_BASE}/deviceManagement/managedDevices", headers={"Authorization": f"Bearer {token}"}, params={ "$filter": "complianceState eq 'noncompliant'", "$select": "id,deviceName,userPrincipalName,complianceState,lastSyncDateTime,operatingSystem" } ) return resp.json().get("value", []) def check_posture_drift(cs_token: str, intune_token: str): print(f"\n[{datetime.now(timezone.utc).isoformat()}] Device Posture Check") print("=" * 60) low_zta = get_low_zta_devices(cs_token, threshold=50) print(f"CrowdStrike ZTA < 50: {len(low_zta)} devices") noncompliant = get_intune_noncompliant(intune_token) print(f"Intune Non-Compliant: {len(noncompliant)} devices") for device in noncompliant[:10]: print(f" - {device['deviceName']} ({device['userPrincipalName']}): " f"{device['complianceState']} | Last sync: {device['lastSyncDateTime']}") return {"low_zta_count": len(low_zta), "noncompliant_count": len(noncompliant)}
| Term | Definition | |------|------------| | Device Posture | Collection of endpoint security attributes (OS version, encryption, EDR status, patch level) evaluated before granting access | | CrowdStrike ZTA Score | Numerical score (1-100) calculated by CrowdStrike Falcon assessing endpoint security posture based on OS signals and sensor configuration | | Device Compliance Policy | MDM-defined rules specifying minimum security requirements (encryption, PIN, OS version) that devices must meet | | Conditional Access | Policy engine (Entra ID, Okta) that evaluates user identity, device compliance, location, and risk before allowing access | | Device Trust | Verification that an endpoint is managed, enrolled, and meets security baselines before treating it as trusted | | Posture Drift | Degradation of device security posture over time (expired patches, disabled encryption) that should trigger access revocation |
Context: A healthcare company with 2,000 endpoints (70% Windows, 30% macOS) must enforce HIPAA-compliant device posture before allowing access to patient data systems. Devices are managed by Intune (Windows) and Jamf (macOS) with CrowdStrike Falcon deployed on all endpoints.
Approach:
Pitfalls: Grace periods must be long enough for IT to remediate but short enough to limit risk exposure. CrowdStrike ZTA scores can fluctuate with sensor updates; avoid setting thresholds too aggressively initially. BYOD devices may lack MDM enrollment; provide a separate Browser Access path with reduced functionality for unmanaged devices.
Device Posture Assessment Report
==================================================
Organization: HealthCorp
Report Date: 2026-02-23
Total Managed Devices: 2,000
COMPLIANCE BY PLATFORM:
Windows (1,400 devices):
Compliant: 1,302 (93.0%)
Non-compliant: 98 (7.0%)
Top Issue: Missing patches (45), BitLocker disabled (23)
macOS (600 devices):
Compliant: 567 (94.5%)
Non-compliant: 33 (5.5%)
Top Issue: OS outdated (18), FileVault disabled (8)
CROWDSTRIKE ZTA SCORES:
Average Score: 78.4
Devices >= 85 (Critical): 1,456 (72.8%)
Devices >= 70 (Standard): 1,812 (90.6%)
Devices < 50 (Blocked): 34 (1.7%)
CONDITIONAL ACCESS IMPACT (last 7 days):
Total sign-in attempts: 45,678
Blocked by posture: 312 (0.7%)
Remediated within 24h: 289 (92.6%)
Still non-compliant: 23
POSTURE DRIFT ALERTS:
Encryption disabled: 5
EDR sensor stopped: 3
OS downgraded: 1| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +27 percentage points is the difference between those two pass rates over the 22 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.