mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-07-19 22:19:39 +03:00
Initial commit - 611 cybersecurity skills across all subdomains
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
# Implementing Identity Verification for Zero Trust
|
||||
|
||||
---
|
||||
domain: cybersecurity
|
||||
subdomain: zero-trust-architecture
|
||||
author: mahipal
|
||||
tags: [zero-trust, identity, authentication, mfa, identity-verification]
|
||||
difficulty: advanced
|
||||
estimated_time: 4-6 hours
|
||||
prerequisites:
|
||||
- Understanding of zero trust principles (NIST SP 800-207)
|
||||
- Familiarity with identity providers (Azure AD, Okta, Ping Identity)
|
||||
- Knowledge of authentication protocols (SAML 2.0, OIDC, FIDO2)
|
||||
- Understanding of MFA and passwordless authentication
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Identity is the foundational pillar of zero trust architecture. NIST SP 800-207 mandates that all resource authentication and authorization are dynamic and strictly enforced before access is allowed. Identity verification in zero trust goes beyond traditional username/password by implementing continuous, risk-adaptive authentication using multiple signals including device posture, behavioral biometrics, location, and network context.
|
||||
|
||||
This skill covers implementing phishing-resistant MFA, continuous identity verification, risk-based conditional access, and identity governance aligned with the CISA Zero Trust Maturity Model Identity Pillar.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Identity Verification Flow
|
||||
|
||||
```
|
||||
User Access Request
|
||||
│
|
||||
v
|
||||
┌───────────────────────┐
|
||||
│ Primary Authentication │
|
||||
│ - FIDO2/WebAuthn key │
|
||||
│ - Certificate-based │
|
||||
│ - Passwordless │
|
||||
└──────────┬────────────┘
|
||||
v
|
||||
┌───────────────────────┐
|
||||
│ Contextual Assessment │
|
||||
│ - Device posture │
|
||||
│ - Network location │
|
||||
│ - Geo-velocity check │
|
||||
│ - Time of access │
|
||||
│ - Behavioral baseline │
|
||||
└──────────┬────────────┘
|
||||
v
|
||||
┌───────────────────────┐
|
||||
│ Risk Scoring Engine │
|
||||
│ - Aggregate signals │
|
||||
│ - Calculate risk score │
|
||||
│ - Compare to threshold │
|
||||
└───┬──────────┬────────┘
|
||||
│ │
|
||||
Low Risk High Risk
|
||||
│ │
|
||||
v v
|
||||
┌────────┐ ┌──────────────┐
|
||||
│ Grant │ │ Step-up Auth │
|
||||
│ Access │ │ - Hardware key│
|
||||
│ │ │ - Biometric │
|
||||
│ │ │ - Manager OK │
|
||||
└────────┘ └──────────────┘
|
||||
```
|
||||
|
||||
### Identity Provider Architecture
|
||||
|
||||
1. **Primary IdP**: Azure AD / Okta / Ping Identity for centralized identity management
|
||||
2. **FIDO2 Authenticators**: Hardware security keys (YubiKey) or platform authenticators (Windows Hello, Touch ID)
|
||||
3. **Risk Engine**: Adaptive access using identity threat detection (Microsoft Entra ID Protection, Okta ThreatInsight)
|
||||
4. **Identity Governance**: Lifecycle management, access reviews, just-in-time provisioning
|
||||
5. **Privileged Identity**: Separate verification for elevated access (CyberArk, BeyondTrust)
|
||||
|
||||
## Key Concepts
|
||||
|
||||
### Phishing-Resistant MFA
|
||||
FIDO2/WebAuthn eliminates phishable credentials by binding authentication to the origin domain. Hardware security keys and platform authenticators provide cryptographic proof of identity without transmitting secrets.
|
||||
|
||||
### Continuous Identity Verification
|
||||
Rather than authenticating once at session start, zero trust requires ongoing verification through session token evaluation, behavioral analytics, and periodic re-authentication challenges based on risk signals.
|
||||
|
||||
### Risk-Based Conditional Access
|
||||
Conditional access policies evaluate multiple signals (user risk level, sign-in risk, device compliance, location) to dynamically adjust authentication requirements and access grants.
|
||||
|
||||
### Identity Threat Detection
|
||||
AI-driven analytics detect compromised identities through impossible travel detection, anomalous sign-in patterns, credential stuffing detection, and token replay attacks.
|
||||
|
||||
## Procedure
|
||||
|
||||
### Phase 1: Identity Infrastructure
|
||||
|
||||
1. **Consolidate Identity Providers**
|
||||
- Audit all identity sources across the organization
|
||||
- Federate to a single authoritative IdP using SAML 2.0 or OIDC
|
||||
- Configure SCIM for automated provisioning and deprovisioning
|
||||
- Eliminate local accounts and shared credentials
|
||||
|
||||
2. **Deploy Phishing-Resistant MFA**
|
||||
- Enroll all users in FIDO2/WebAuthn with hardware security keys
|
||||
- Configure platform authenticators (Windows Hello for Business, macOS Touch ID)
|
||||
- Disable SMS and voice call as MFA methods (phishable)
|
||||
- Create conditional access policy requiring phishing-resistant methods for all sign-ins
|
||||
|
||||
3. **Configure Conditional Access Policies**
|
||||
- Require compliant device for access to sensitive applications
|
||||
- Block legacy authentication protocols (basic auth, IMAP, POP3)
|
||||
- Require MFA for all users from untrusted locations
|
||||
- Enforce session time limits with re-authentication
|
||||
- Block or require additional verification for high-risk sign-ins
|
||||
|
||||
### Phase 2: Risk-Based Authentication
|
||||
|
||||
4. **Enable Identity Threat Detection**
|
||||
- Activate Microsoft Entra ID Protection or Okta ThreatInsight
|
||||
- Configure risk levels: low (allow), medium (require MFA), high (block and investigate)
|
||||
- Enable impossible travel detection and anomalous token alerts
|
||||
- Integrate identity risk signals with SIEM/SOAR
|
||||
|
||||
5. **Implement Step-Up Authentication**
|
||||
- For sensitive operations (privilege elevation, financial transactions), require additional verification
|
||||
- Configure step-up policies: re-authenticate with hardware key
|
||||
- Integrate with PAM for privileged session approval workflows
|
||||
- Log all step-up events for audit trail
|
||||
|
||||
### Phase 3: Continuous Verification
|
||||
|
||||
6. **Deploy Continuous Access Evaluation (CAE)**
|
||||
- Enable Continuous Access Evaluation Protocol (CAEP) for real-time token revocation
|
||||
- Configure critical event triggers: user disabled, password changed, location change
|
||||
- Test that token revocation occurs within minutes (not hours) of security event
|
||||
- Monitor CAE event logs for operational health
|
||||
|
||||
7. **Implement Session Controls**
|
||||
- Configure session duration limits based on application sensitivity
|
||||
- Enable sign-in frequency controls (re-authenticate every N hours)
|
||||
- Implement persistent browser session controls
|
||||
- Configure app-enforced restrictions for unmanaged devices
|
||||
|
||||
### Phase 4: Identity Governance
|
||||
|
||||
8. **Automate Identity Lifecycle**
|
||||
- Configure joiner-mover-leaver workflows with HR system integration
|
||||
- Automate access provisioning based on role and department
|
||||
- Enable just-in-time access for temporary elevated permissions
|
||||
- Configure automatic access expiration for contractors and guests
|
||||
|
||||
9. **Implement Access Reviews**
|
||||
- Schedule quarterly access certification campaigns
|
||||
- Configure automated reminders and escalation
|
||||
- Require manager approval for continued access
|
||||
- Auto-revoke access for unreviewed certifications
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
- [ ] Single authoritative IdP with all applications federated
|
||||
- [ ] FIDO2/WebAuthn enrolled for all users
|
||||
- [ ] SMS and voice MFA methods disabled
|
||||
- [ ] Legacy authentication protocols blocked
|
||||
- [ ] Conditional access policies enforced for all applications
|
||||
- [ ] Identity threat detection active with risk-based policies
|
||||
- [ ] Continuous Access Evaluation enabled and tested
|
||||
- [ ] Step-up authentication configured for sensitive operations
|
||||
- [ ] Identity lifecycle automated with HR integration
|
||||
- [ ] Quarterly access reviews scheduled and operational
|
||||
- [ ] Identity events streaming to SIEM
|
||||
|
||||
## References
|
||||
|
||||
- NIST SP 800-207: Zero Trust Architecture
|
||||
- NIST SP 800-63B: Digital Identity Guidelines - Authentication
|
||||
- CISA Zero Trust Maturity Model v2.0 - Identity Pillar
|
||||
- FIDO Alliance WebAuthn Specification
|
||||
- Microsoft Entra Conditional Access Documentation
|
||||
@@ -0,0 +1,104 @@
|
||||
# Identity Verification Implementation Plan Template
|
||||
|
||||
## Project Information
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| Project Name | |
|
||||
| Organization | |
|
||||
| Identity Provider | [Azure AD / Okta / Ping Identity] |
|
||||
| User Population | |
|
||||
| Target Completion | |
|
||||
|
||||
## Current State Assessment
|
||||
|
||||
### Identity Infrastructure
|
||||
- **Primary IdP**: |
|
||||
- **Secondary IdPs**: |
|
||||
- **Local Accounts**: [Count and locations] |
|
||||
- **Shared Accounts**: [Count - target for elimination] |
|
||||
|
||||
### Current MFA State
|
||||
| Method | Enabled | Users Enrolled | Phishing-Resistant |
|
||||
|---|---|---|---|
|
||||
| SMS OTP | | | No |
|
||||
| Voice Call | | | No |
|
||||
| TOTP App | | | No |
|
||||
| Push Notification | | | No |
|
||||
| FIDO2 Security Key | | | Yes |
|
||||
| Windows Hello | | | Yes |
|
||||
| Certificate/PIV | | | Yes |
|
||||
|
||||
### MFA Enrollment Target
|
||||
- Current enrollment rate: ___%
|
||||
- Target enrollment rate: 100%
|
||||
- Phishing-resistant target: 100%
|
||||
|
||||
## Phishing-Resistant MFA Rollout Plan
|
||||
|
||||
### Hardware Key Distribution
|
||||
|
||||
| User Group | Key Type | Quantity | Distribution Method | Timeline |
|
||||
|---|---|---|---|---|
|
||||
| Executive Leadership | YubiKey 5 NFC | | In-person | Week 1 |
|
||||
| IT Administrators | YubiKey 5C | | IT distribution | Week 2 |
|
||||
| All Employees | YubiKey Security Key | | Self-service + mail | Weeks 3-8 |
|
||||
|
||||
### Enrollment Campaign
|
||||
- [ ] Communication sent to all users
|
||||
- [ ] Self-service portal configured
|
||||
- [ ] Help desk trained on enrollment support
|
||||
- [ ] Enrollment deadline set: ____
|
||||
- [ ] Escalation path for non-compliant users
|
||||
|
||||
## Conditional Access Policies
|
||||
|
||||
| Policy Name | Users | Apps | Conditions | Grant Controls | Session Controls |
|
||||
|---|---|---|---|---|---|
|
||||
| Block Legacy Auth | All | All | Legacy clients | Block | N/A |
|
||||
| Require MFA | All | All | Any | Require MFA | Sign-in freq: 8hr |
|
||||
| Require Compliant Device | All | Sensitive Apps | Any | Compliant device | App enforced |
|
||||
| Block Risky Sign-In | All | All | High sign-in risk | Block | N/A |
|
||||
| Require FIDO2 for Admins | Admin roles | Admin portals | Any | FIDO2 only | 1hr frequency |
|
||||
|
||||
## Risk-Based Policies
|
||||
|
||||
| Risk Level | User Risk Response | Sign-In Risk Response |
|
||||
|---|---|---|
|
||||
| Low | Allow | Allow |
|
||||
| Medium | Require MFA step-up | Require MFA step-up |
|
||||
| High | Block + alert SOC | Block + alert SOC |
|
||||
|
||||
## Identity Governance
|
||||
|
||||
### Lifecycle Automation
|
||||
- [ ] HR system integrated for joiner/mover/leaver
|
||||
- [ ] Automatic provisioning on hire
|
||||
- [ ] Role change triggers access review
|
||||
- [ ] Automatic deprovisioning on termination
|
||||
- [ ] Contractor access expiration configured
|
||||
|
||||
### Access Reviews
|
||||
- Frequency: Quarterly
|
||||
- Scope: All application assignments
|
||||
- Reviewers: Direct managers
|
||||
- Auto-action on non-response: Revoke access
|
||||
|
||||
## Monitoring and Detection
|
||||
|
||||
| Capability | Tool | Status |
|
||||
|---|---|---|
|
||||
| Sign-in log analysis | SIEM (Splunk/Sentinel) | |
|
||||
| Identity threat detection | Entra ID Protection / ThreatInsight | |
|
||||
| Impossible travel detection | IdP + UEBA | |
|
||||
| Continuous Access Evaluation | CAE/CAEP | |
|
||||
| Behavioral analytics | UEBA platform | |
|
||||
|
||||
## Sign-Off
|
||||
|
||||
| Stakeholder | Role | Approval | Date |
|
||||
|---|---|---|---|
|
||||
| | CISO | | |
|
||||
| | Identity Team Lead | | |
|
||||
| | Help Desk Manager | | |
|
||||
| | HR Systems | | |
|
||||
@@ -0,0 +1,83 @@
|
||||
# Standards and Frameworks Reference
|
||||
|
||||
## NIST SP 800-207: Zero Trust Architecture - Identity
|
||||
|
||||
### Core Identity Tenets
|
||||
- All resource authentication and authorization are dynamic and strictly enforced before access is allowed
|
||||
- The enterprise collects as much information as possible about the current state of assets, network infrastructure, and communications and uses it to improve its security posture
|
||||
- Access decisions should consider behavioral attributes, environmental attributes, and the identity of the requester
|
||||
|
||||
### Policy Engine Identity Inputs
|
||||
The Policy Engine (PE) uses the following identity-related inputs:
|
||||
- User identity and attributes from the IdP
|
||||
- Device identity and posture from the endpoint management system
|
||||
- Behavioral attributes from user and entity behavior analytics (UEBA)
|
||||
- Environmental attributes (location, time, network)
|
||||
|
||||
## NIST SP 800-63B: Digital Identity Guidelines
|
||||
|
||||
### Authentication Assurance Levels (AAL)
|
||||
| AAL | Description | Methods | Zero Trust Mapping |
|
||||
|---|---|---|---|
|
||||
| AAL1 | Some assurance | Single-factor (password) | Insufficient for ZT |
|
||||
| AAL2 | High confidence | Multi-factor (push notification, OTP) | Minimum for ZT |
|
||||
| AAL3 | Very high confidence | Hardware-based (FIDO2, PIV card) | Target for ZT |
|
||||
|
||||
### Phishing-Resistant Authenticators
|
||||
- FIDO2/WebAuthn: Cryptographic authentication bound to origin domain
|
||||
- PIV/CAC smart cards: Certificate-based authentication
|
||||
- Not phishing-resistant: SMS OTP, voice calls, push notifications, TOTP
|
||||
|
||||
## CISA Zero Trust Maturity Model v2.0 - Identity Pillar
|
||||
|
||||
| Maturity Level | Authentication | Identity Store | Risk Assessment | Visibility |
|
||||
|---|---|---|---|---|
|
||||
| Traditional | Password + basic MFA | Multiple disconnected stores | None | Basic audit logs |
|
||||
| Initial | MFA for all users | Federated IdP | Static risk rules | Centralized auth logs |
|
||||
| Advanced | Phishing-resistant MFA | Single authoritative IdP with SCIM | Risk-based conditional access | Identity analytics |
|
||||
| Optimal | Continuous verification | Automated lifecycle governance | AI-driven threat detection | Real-time UEBA |
|
||||
|
||||
## FIDO Alliance Standards
|
||||
|
||||
### FIDO2 / WebAuthn
|
||||
- W3C Web Authentication specification for passwordless authentication
|
||||
- Public-key cryptography: private key never leaves the authenticator
|
||||
- Origin-bound: authentication is cryptographically tied to the service domain
|
||||
- Resistant to phishing, replay, and man-in-the-middle attacks
|
||||
|
||||
### Passkeys
|
||||
- Evolution of FIDO2 for consumer and enterprise use
|
||||
- Synced across devices via platform credential managers (iCloud Keychain, Google Password Manager)
|
||||
- Discoverable credentials eliminate need to remember usernames
|
||||
|
||||
## Microsoft Entra (Azure AD) Identity Protection
|
||||
|
||||
### Risk Detection Categories
|
||||
| Risk Type | Detection | Response |
|
||||
|---|---|---|
|
||||
| Anonymous IP | Sign-in from anonymous proxy/VPN | Require MFA |
|
||||
| Atypical travel | Impossible travel between sign-in locations | Block + investigate |
|
||||
| Malware-linked IP | Sign-in from known malicious IP | Block |
|
||||
| Unfamiliar sign-in | Unusual sign-in properties | Step-up auth |
|
||||
| Leaked credentials | Credentials found in dark web dumps | Force password reset |
|
||||
| Token anomaly | Unusual token characteristics | Revoke session |
|
||||
|
||||
### Continuous Access Evaluation Protocol (CAEP)
|
||||
- Real-time token revocation on security events
|
||||
- Critical events: user disabled, password changed, high risk detected
|
||||
- Reduces token lifetime gap from hours to near real-time
|
||||
- Supported by Microsoft 365, Exchange Online, SharePoint Online
|
||||
|
||||
## Okta Identity Security
|
||||
|
||||
### Okta ThreatInsight
|
||||
- Pre-authentication threat detection using IP reputation
|
||||
- Credential stuffing protection
|
||||
- Bot detection and rate limiting
|
||||
- Anomalous location and device detection
|
||||
|
||||
### Okta FastPass
|
||||
- Passwordless, phishing-resistant authentication
|
||||
- Device-bound biometric verification
|
||||
- Continuous device trust assessment
|
||||
- No shared secrets transmitted over network
|
||||
@@ -0,0 +1,173 @@
|
||||
# Identity Verification Workflows
|
||||
|
||||
## Workflow 1: Zero Trust Authentication Flow
|
||||
|
||||
```
|
||||
User Initiates Access
|
||||
│
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ 1. Pre-Authentication │
|
||||
│ - Check IP reputation │
|
||||
│ - Rate limit evaluation │
|
||||
│ - Bot detection │
|
||||
│ - Geo-blocking check │
|
||||
└──────────┬──────────────┘
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ 2. Primary Authentication│
|
||||
│ - FIDO2 key challenge │
|
||||
│ - Biometric verification │
|
||||
│ - Certificate validation │
|
||||
│ - Passwordless flow │
|
||||
└──────────┬──────────────┘
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ 3. Context Assessment │
|
||||
│ - Device compliance │
|
||||
│ - Network location │
|
||||
│ - Time of access │
|
||||
│ - Behavioral baseline │
|
||||
│ - Previous session state │
|
||||
└──────────┬──────────────┘
|
||||
v
|
||||
┌─────────────────────────┐
|
||||
│ 4. Risk Calculation │
|
||||
│ - User risk level │
|
||||
│ - Sign-in risk level │
|
||||
│ - Aggregate score │
|
||||
└───┬──────────┬──────┬───┘
|
||||
│ │ │
|
||||
LOW MED HIGH
|
||||
│ │ │
|
||||
v v v
|
||||
┌──────┐ ┌────────┐ ┌────────┐
|
||||
│Grant │ │Step-Up │ │Block + │
|
||||
│Token │ │ Auth │ │Alert │
|
||||
└──────┘ └────────┘ └────────┘
|
||||
```
|
||||
|
||||
## Workflow 2: Continuous Access Evaluation
|
||||
|
||||
```
|
||||
Active Session
|
||||
│
|
||||
v
|
||||
┌──────────────────────────────┐
|
||||
│ Continuous Monitoring Loop │
|
||||
│ │
|
||||
│ ┌─── Check every N minutes ──┐
|
||||
│ │ │
|
||||
│ │ ┌─────────────────────┐ │
|
||||
│ │ │ Signal Collection │ │
|
||||
│ │ │ - Device compliance │ │
|
||||
│ │ │ - User risk change │ │
|
||||
│ │ │ - Location shift │ │
|
||||
│ │ │ - Behavior anomaly │ │
|
||||
│ │ └──────────┬──────────┘ │
|
||||
│ │ v │
|
||||
│ │ ┌─────────────────────┐ │
|
||||
│ │ │ Critical Events │ │
|
||||
│ │ │ - Account disabled │ │
|
||||
│ │ │ - Password changed │ │
|
||||
│ │ │ - MFA registration │ │
|
||||
│ │ │ - Admin revocation │ │
|
||||
│ │ └──────────┬──────────┘ │
|
||||
│ │ v │
|
||||
│ │ ┌─────────────────────┐ │
|
||||
│ │ │ Re-Evaluate Access │ │
|
||||
│ │ │ - Recalculate risk │ │
|
||||
│ │ │ - Apply policy │ │
|
||||
│ │ └───┬─────────┬───────┘ │
|
||||
│ │ │ │ │
|
||||
│ │ Continue Revoke │
|
||||
│ │ Session Token │
|
||||
│ └──────┘ │ │
|
||||
│ v │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ Force Re-Auth│ │
|
||||
│ │ or Terminate │ │
|
||||
│ └──────────────┘ │
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
## Workflow 3: FIDO2 Enrollment
|
||||
|
||||
```
|
||||
Admin Initiates Enrollment Campaign
|
||||
│
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 1. User Notification │
|
||||
│ - Email with instructions │
|
||||
│ - Self-service portal URL │
|
||||
│ - Deadline for enrollment │
|
||||
└──────────┬───────────────┘
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 2. User Self-Service │
|
||||
│ - Authenticate with │
|
||||
│ existing credentials │
|
||||
│ - Register security key │
|
||||
│ (YubiKey, Titan key) │
|
||||
│ - Register platform auth │
|
||||
│ (Windows Hello, TouchID)│
|
||||
│ - Register backup method │
|
||||
└──────────┬───────────────┘
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 3. Verification │
|
||||
│ - Test sign-in with FIDO2 │
|
||||
│ - Confirm backup works │
|
||||
│ - Record key serial/ID │
|
||||
└──────────┬───────────────┘
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 4. Policy Enforcement │
|
||||
│ - Enable phishing-resist │
|
||||
│ conditional access │
|
||||
│ - Disable legacy MFA │
|
||||
│ - Monitor compliance rate │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
|
||||
## Workflow 4: Compromised Identity Response
|
||||
|
||||
```
|
||||
Identity Threat Detected
|
||||
│
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 1. Detection Signal │
|
||||
│ - Impossible travel │
|
||||
│ - Leaked credentials │
|
||||
│ - Token anomaly │
|
||||
│ - Behavioral deviation │
|
||||
└──────────┬───────────────┘
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 2. Automated Response │
|
||||
│ - Revoke all sessions │
|
||||
│ - Disable account │
|
||||
│ - Trigger SOAR playbook │
|
||||
│ - Notify SOC analyst │
|
||||
└──────────┬───────────────┘
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 3. Investigation │
|
||||
│ - Review sign-in logs │
|
||||
│ - Check accessed resources│
|
||||
│ - Correlate with EDR data │
|
||||
│ - Interview user │
|
||||
└──────────┬───────────────┘
|
||||
v
|
||||
┌──────────────────────────┐
|
||||
│ 4. Remediation │
|
||||
│ - Reset all credentials │
|
||||
│ - Re-enroll FIDO2 keys │
|
||||
│ - Review and restrict │
|
||||
│ access permissions │
|
||||
│ - Re-enable account │
|
||||
│ - Update detection rules │
|
||||
└──────────────────────────┘
|
||||
```
|
||||
@@ -0,0 +1,392 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Identity Verification Assessment Tool for Zero Trust
|
||||
|
||||
Analyzes identity configurations, evaluates MFA strength, assesses
|
||||
conditional access policies, and generates identity maturity reports.
|
||||
"""
|
||||
|
||||
import json
|
||||
import csv
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
from collections import defaultdict
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def assess_mfa_strength(mfa_config: dict) -> dict:
|
||||
"""Evaluate MFA configuration against zero trust requirements."""
|
||||
findings = []
|
||||
score = 100
|
||||
|
||||
methods = mfa_config.get("enabled_methods", [])
|
||||
phishing_resistant = {"fido2", "webauthn", "certificate", "windows_hello", "platform_authenticator"}
|
||||
phishable = {"sms", "voice", "email_otp"}
|
||||
moderate = {"totp", "push_notification", "authenticator_app"}
|
||||
|
||||
enabled_phishing_resistant = set(methods) & phishing_resistant
|
||||
enabled_phishable = set(methods) & phishable
|
||||
|
||||
if not enabled_phishing_resistant:
|
||||
findings.append({
|
||||
"severity": "critical",
|
||||
"finding": "No phishing-resistant MFA methods enabled",
|
||||
"recommendation": "Deploy FIDO2 security keys or platform authenticators",
|
||||
"reference": "NIST SP 800-63B AAL3, CISA ZT Identity Pillar (Advanced)"
|
||||
})
|
||||
score -= 40
|
||||
|
||||
if enabled_phishable:
|
||||
findings.append({
|
||||
"severity": "high",
|
||||
"finding": f"Phishable MFA methods still enabled: {', '.join(enabled_phishable)}",
|
||||
"recommendation": "Disable SMS, voice, and email OTP methods",
|
||||
"reference": "CISA Phishing-Resistant MFA Guidance"
|
||||
})
|
||||
score -= 20
|
||||
|
||||
if not mfa_config.get("enforced_for_all_users"):
|
||||
findings.append({
|
||||
"severity": "critical",
|
||||
"finding": "MFA not enforced for all users",
|
||||
"recommendation": "Enable MFA requirement for all user accounts",
|
||||
"reference": "CISA ZT Identity Pillar (Initial)"
|
||||
})
|
||||
score -= 30
|
||||
|
||||
if not mfa_config.get("number_matching_enabled") and "push_notification" in methods:
|
||||
findings.append({
|
||||
"severity": "high",
|
||||
"finding": "Push notification MFA without number matching",
|
||||
"recommendation": "Enable number matching to prevent MFA fatigue attacks",
|
||||
"reference": "Microsoft MFA fatigue defense guidance"
|
||||
})
|
||||
score -= 10
|
||||
|
||||
enrollment_rate = mfa_config.get("enrollment_rate_percent", 0)
|
||||
if enrollment_rate < 95:
|
||||
findings.append({
|
||||
"severity": "warning",
|
||||
"finding": f"MFA enrollment rate is {enrollment_rate}% (target: 95%+)",
|
||||
"recommendation": "Launch enrollment campaign for remaining users",
|
||||
"reference": "CISA ZT Identity Pillar (Advanced)"
|
||||
})
|
||||
score -= 10
|
||||
|
||||
return {
|
||||
"mfa_score": max(score, 0),
|
||||
"phishing_resistant_methods": list(enabled_phishing_resistant),
|
||||
"phishable_methods": list(enabled_phishable),
|
||||
"findings": findings,
|
||||
"maturity_level": (
|
||||
"optimal" if score >= 90 else
|
||||
"advanced" if score >= 70 else
|
||||
"initial" if score >= 50 else
|
||||
"traditional"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
def assess_conditional_access(policies: list) -> dict:
|
||||
"""Evaluate conditional access policies for zero trust alignment."""
|
||||
findings = []
|
||||
coverage = {
|
||||
"legacy_auth_blocked": False,
|
||||
"mfa_required_all": False,
|
||||
"device_compliance_required": False,
|
||||
"location_restrictions": False,
|
||||
"session_controls": False,
|
||||
"risk_based_policies": False,
|
||||
"privileged_access_secured": False,
|
||||
}
|
||||
|
||||
for policy in policies:
|
||||
conditions = policy.get("conditions", {})
|
||||
grant_controls = policy.get("grant_controls", {})
|
||||
session_controls = policy.get("session_controls", {})
|
||||
|
||||
if policy.get("blocks_legacy_auth"):
|
||||
coverage["legacy_auth_blocked"] = True
|
||||
|
||||
if grant_controls.get("require_mfa") and conditions.get("users") == "all":
|
||||
coverage["mfa_required_all"] = True
|
||||
|
||||
if grant_controls.get("require_compliant_device"):
|
||||
coverage["device_compliance_required"] = True
|
||||
|
||||
if conditions.get("locations") and conditions["locations"].get("excluded_trusted"):
|
||||
coverage["location_restrictions"] = True
|
||||
|
||||
if session_controls.get("sign_in_frequency") or session_controls.get("persistent_browser"):
|
||||
coverage["session_controls"] = True
|
||||
|
||||
if conditions.get("user_risk") or conditions.get("sign_in_risk"):
|
||||
coverage["risk_based_policies"] = True
|
||||
|
||||
if conditions.get("roles") and "privileged" in str(conditions.get("roles", [])).lower():
|
||||
coverage["privileged_access_secured"] = True
|
||||
|
||||
if not coverage["legacy_auth_blocked"]:
|
||||
findings.append({
|
||||
"severity": "critical",
|
||||
"finding": "Legacy authentication protocols not blocked",
|
||||
"recommendation": "Create policy blocking basic auth, IMAP, POP3, SMTP AUTH",
|
||||
})
|
||||
|
||||
if not coverage["mfa_required_all"]:
|
||||
findings.append({
|
||||
"severity": "critical",
|
||||
"finding": "MFA not required for all users",
|
||||
"recommendation": "Create policy requiring MFA for all user sign-ins",
|
||||
})
|
||||
|
||||
if not coverage["device_compliance_required"]:
|
||||
findings.append({
|
||||
"severity": "high",
|
||||
"finding": "Device compliance not required for access",
|
||||
"recommendation": "Require managed and compliant devices for sensitive apps",
|
||||
})
|
||||
|
||||
if not coverage["risk_based_policies"]:
|
||||
findings.append({
|
||||
"severity": "high",
|
||||
"finding": "No risk-based conditional access policies",
|
||||
"recommendation": "Enable user risk and sign-in risk based policies",
|
||||
})
|
||||
|
||||
if not coverage["session_controls"]:
|
||||
findings.append({
|
||||
"severity": "warning",
|
||||
"finding": "No session lifetime controls configured",
|
||||
"recommendation": "Configure sign-in frequency and browser session persistence",
|
||||
})
|
||||
|
||||
covered = sum(1 for v in coverage.values() if v)
|
||||
total = len(coverage)
|
||||
|
||||
return {
|
||||
"coverage": coverage,
|
||||
"coverage_score": round((covered / total) * 100),
|
||||
"policies_evaluated": len(policies),
|
||||
"findings": findings,
|
||||
}
|
||||
|
||||
|
||||
def analyze_sign_in_logs(logs: list) -> dict:
|
||||
"""Analyze sign-in logs for identity security insights."""
|
||||
stats = {
|
||||
"total_sign_ins": len(logs),
|
||||
"successful": 0,
|
||||
"failed": 0,
|
||||
"mfa_challenged": 0,
|
||||
"risk_events": [],
|
||||
"locations": defaultdict(int),
|
||||
"devices": defaultdict(int),
|
||||
"applications": defaultdict(int),
|
||||
"auth_methods": defaultdict(int),
|
||||
"risky_sign_ins": [],
|
||||
}
|
||||
|
||||
for log in logs:
|
||||
if log.get("status") == "success":
|
||||
stats["successful"] += 1
|
||||
else:
|
||||
stats["failed"] += 1
|
||||
|
||||
if log.get("mfa_required"):
|
||||
stats["mfa_challenged"] += 1
|
||||
|
||||
location = log.get("location", {}).get("country", "unknown")
|
||||
stats["locations"][location] += 1
|
||||
|
||||
device = log.get("device", {}).get("os", "unknown")
|
||||
stats["devices"][device] += 1
|
||||
|
||||
app = log.get("application", "unknown")
|
||||
stats["applications"][app] += 1
|
||||
|
||||
method = log.get("auth_method", "password")
|
||||
stats["auth_methods"][method] += 1
|
||||
|
||||
risk_level = log.get("risk_level", "none")
|
||||
if risk_level in ("medium", "high"):
|
||||
stats["risky_sign_ins"].append({
|
||||
"user": log.get("user", "unknown"),
|
||||
"risk_level": risk_level,
|
||||
"risk_detail": log.get("risk_detail", ""),
|
||||
"location": location,
|
||||
"timestamp": log.get("timestamp", ""),
|
||||
"application": app,
|
||||
})
|
||||
|
||||
stats["locations"] = dict(stats["locations"])
|
||||
stats["devices"] = dict(stats["devices"])
|
||||
stats["applications"] = dict(stats["applications"])
|
||||
stats["auth_methods"] = dict(stats["auth_methods"])
|
||||
stats["mfa_coverage_percent"] = round(
|
||||
(stats["mfa_challenged"] / max(stats["total_sign_ins"], 1)) * 100, 1
|
||||
)
|
||||
|
||||
return stats
|
||||
|
||||
|
||||
def detect_impossible_travel(sign_ins: list, max_speed_kmh: int = 900) -> list:
|
||||
"""Detect impossible travel scenarios from sign-in logs."""
|
||||
alerts = []
|
||||
user_logins = defaultdict(list)
|
||||
|
||||
for si in sign_ins:
|
||||
user = si.get("user", "")
|
||||
if user and si.get("location", {}).get("latitude"):
|
||||
user_logins[user].append(si)
|
||||
|
||||
for user, logins in user_logins.items():
|
||||
sorted_logins = sorted(logins, key=lambda x: x.get("timestamp", ""))
|
||||
|
||||
for i in range(1, len(sorted_logins)):
|
||||
prev = sorted_logins[i - 1]
|
||||
curr = sorted_logins[i]
|
||||
|
||||
lat1 = prev["location"].get("latitude", 0)
|
||||
lon1 = prev["location"].get("longitude", 0)
|
||||
lat2 = curr["location"].get("latitude", 0)
|
||||
lon2 = curr["location"].get("longitude", 0)
|
||||
|
||||
import math
|
||||
R = 6371
|
||||
dlat = math.radians(lat2 - lat1)
|
||||
dlon = math.radians(lon2 - lon1)
|
||||
a = (math.sin(dlat / 2) ** 2 +
|
||||
math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *
|
||||
math.sin(dlon / 2) ** 2)
|
||||
c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
|
||||
distance_km = R * c
|
||||
|
||||
try:
|
||||
t1 = datetime.fromisoformat(prev.get("timestamp", "").replace("Z", "+00:00"))
|
||||
t2 = datetime.fromisoformat(curr.get("timestamp", "").replace("Z", "+00:00"))
|
||||
time_diff_hours = (t2 - t1).total_seconds() / 3600
|
||||
except (ValueError, TypeError):
|
||||
continue
|
||||
|
||||
if time_diff_hours > 0:
|
||||
required_speed = distance_km / time_diff_hours
|
||||
if required_speed > max_speed_kmh and distance_km > 100:
|
||||
alerts.append({
|
||||
"user": user,
|
||||
"severity": "high",
|
||||
"type": "impossible_travel",
|
||||
"from_location": prev["location"],
|
||||
"to_location": curr["location"],
|
||||
"distance_km": round(distance_km),
|
||||
"time_diff_hours": round(time_diff_hours, 2),
|
||||
"required_speed_kmh": round(required_speed),
|
||||
"from_time": prev.get("timestamp"),
|
||||
"to_time": curr.get("timestamp"),
|
||||
})
|
||||
|
||||
return alerts
|
||||
|
||||
|
||||
def generate_identity_maturity_report(config: dict) -> dict:
|
||||
"""Generate a comprehensive identity maturity assessment."""
|
||||
report = {
|
||||
"generated": datetime.now().isoformat(),
|
||||
"overall_maturity": "traditional",
|
||||
"pillars": {},
|
||||
}
|
||||
|
||||
mfa_assessment = assess_mfa_strength(config.get("mfa", {}))
|
||||
report["pillars"]["mfa"] = mfa_assessment
|
||||
|
||||
ca_assessment = assess_conditional_access(config.get("conditional_access_policies", []))
|
||||
report["pillars"]["conditional_access"] = ca_assessment
|
||||
|
||||
governance = config.get("governance", {})
|
||||
gov_score = 0
|
||||
if governance.get("automated_provisioning"): gov_score += 25
|
||||
if governance.get("access_reviews_enabled"): gov_score += 25
|
||||
if governance.get("jit_access_enabled"): gov_score += 25
|
||||
if governance.get("lifecycle_automation"): gov_score += 25
|
||||
report["pillars"]["governance"] = {"score": gov_score}
|
||||
|
||||
monitoring = config.get("monitoring", {})
|
||||
mon_score = 0
|
||||
if monitoring.get("siem_integration"): mon_score += 25
|
||||
if monitoring.get("ueba_enabled"): mon_score += 25
|
||||
if monitoring.get("identity_threat_detection"): mon_score += 25
|
||||
if monitoring.get("cae_enabled"): mon_score += 25
|
||||
report["pillars"]["monitoring"] = {"score": mon_score}
|
||||
|
||||
avg_score = (
|
||||
mfa_assessment["mfa_score"] +
|
||||
ca_assessment["coverage_score"] +
|
||||
gov_score +
|
||||
mon_score
|
||||
) / 4
|
||||
|
||||
report["overall_score"] = round(avg_score)
|
||||
report["overall_maturity"] = (
|
||||
"optimal" if avg_score >= 90 else
|
||||
"advanced" if avg_score >= 70 else
|
||||
"initial" if avg_score >= 50 else
|
||||
"traditional"
|
||||
)
|
||||
|
||||
return report
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(description="Identity Verification Assessment Tool")
|
||||
parser.add_argument("--config", type=str, help="Path to identity configuration JSON")
|
||||
parser.add_argument("--logs", type=str, help="Path to sign-in logs JSON")
|
||||
parser.add_argument("--action", choices=["assess", "analyze-logs", "detect-travel", "report"],
|
||||
default="report")
|
||||
parser.add_argument("--output", type=str, default="identity_report.json")
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.action == "assess" and args.config:
|
||||
with open(args.config) as f:
|
||||
config = json.load(f)
|
||||
mfa_result = assess_mfa_strength(config.get("mfa", {}))
|
||||
ca_result = assess_conditional_access(config.get("conditional_access_policies", []))
|
||||
result = {"mfa": mfa_result, "conditional_access": ca_result}
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(result, f, indent=2)
|
||||
print(f"MFA Score: {mfa_result['mfa_score']}, CA Coverage: {ca_result['coverage_score']}%")
|
||||
|
||||
elif args.action == "analyze-logs" and args.logs:
|
||||
with open(args.logs) as f:
|
||||
logs = json.load(f)
|
||||
stats = analyze_sign_in_logs(logs)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(stats, f, indent=2)
|
||||
print(f"Analyzed {stats['total_sign_ins']} sign-ins, {len(stats['risky_sign_ins'])} risky")
|
||||
|
||||
elif args.action == "detect-travel" and args.logs:
|
||||
with open(args.logs) as f:
|
||||
logs = json.load(f)
|
||||
alerts = detect_impossible_travel(logs)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(alerts, f, indent=2)
|
||||
print(f"Detected {len(alerts)} impossible travel events")
|
||||
|
||||
elif args.action == "report" and args.config:
|
||||
with open(args.config) as f:
|
||||
config = json.load(f)
|
||||
report = generate_identity_maturity_report(config)
|
||||
with open(args.output, "w") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
print(f"Identity Maturity: {report['overall_maturity']} (Score: {report['overall_score']})")
|
||||
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
if args.output and Path(args.output).exists():
|
||||
print(f"Output saved to {args.output}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user