| name | implementing-patch-management-for-ot-systems |
| description | This skill covers implementing a structured patch management program for OT/ICS environments where traditional IT patching approaches can cause process disruption or safety hazards. It addresses vendor compatibility testing, risk-based patch prioritization, staged deployment through test environments, maintenance window coordination, rollback procedures, and compensating controls when patches cannot be applied due to operational constraints or vendor restrictions.
|
| domain | cybersecurity |
| subdomain | ot-ics-security |
| tags | ["ot-security","ics","scada","industrial-control","iec62443","patch-management","vulnerability-management"] |
| version | 1.0.0 |
| author | mahipal |
| license | Apache-2.0 |
| nist_csf | ["PR.IR-01","DE.CM-01","ID.AM-05","GV.OC-02"] |
| mitre_attack | ["T1078","T1190","T1059","T0816","T0836"] |
| source | https://github.com/mukul975/Anthropic-Cybersecurity-Skills |
| source_commit | 04450304b12645cb2b974ab96d28c0664758a88d |
| note | Vendored verbatim from an external Apache-2.0 security-skill library, pinned by commit. Exceeds the internal 300-line skill guideline (agent-code-constraints.md) -- kept as-is because this is vendored reference material (forensics/threat-intel procedure), not Yana AI-authored content, and trimming would damage technical accuracy. |
Implementing Patch Management for OT Systems
When to Use
- When establishing a formal OT patch management program for the first time
- When responding to critical ICS-CERT advisories affecting deployed OT systems
- When preparing for NERC CIP-007-6 or IEC 62443 patch management compliance audits
- When planning patch deployment during limited maintenance windows in continuous operations
- When evaluating compensating controls for systems that cannot be patched
Do not use for IT-only patch management without OT considerations, for emergency patching during active cyber incidents (see performing-ot-incident-response), or for firmware upgrades that change PLC functionality (requires separate change management).
Prerequisites
- OT asset inventory with firmware/OS versions for all patchable systems
- Vendor patch notification subscriptions (Siemens ProductCERT, Rockwell, Schneider, etc.)
- Test/staging environment mirroring production OT systems for patch validation
- Maintenance window schedule aligned with process shutdowns and turnarounds
- Change management board approval process including operations and safety representatives
Workflow
Step 1: Establish OT Patch Management Program
Define the patch management lifecycle adapted for OT environments where availability and safety take priority over immediate vulnerability remediation.
"""OT Patch Management Program Manager.
Tracks patches for OT systems, manages risk-based prioritization,
coordinates testing and deployment, and documents compensating
controls for unpatchable systems.
"""
import json
import sys
from collections import defaultdict
from dataclasses import dataclass, field, asdict
from datetime import datetime, timedelta
from enum import Enum
class PatchStatus(str, Enum):
IDENTIFIED = "identified"
EVALUATING = "evaluating"
TESTING = "testing"
APPROVED =
SCHEDULED =
DEPLOYED =
DEFERRED =
NOT_APPLICABLE =
:
patch_id:
vendor:
product:
affected_versions:
cve_ids:
cvss_score:
ics_cert_advisory:
description:
status: = PatchStatus.IDENTIFIED
identified_date: =
evaluation_deadline: =
test_date: =
deployment_date: =
affected_assets: = field(default_factory=)
test_results: =
compensating_controls: =
risk_rating: =
maintenance_window: =
rollback_procedure: =
:
():
.patches = []
.assets = {}
.vendor_feeds = {}
():
patch.evaluation_deadline:
identified = datetime.fromisoformat(patch.identified_date)
patch.evaluation_deadline = (identified + timedelta(days=)).isoformat()
.patches.append(patch)
():
patch .patches:
patch.status (PatchStatus.DEPLOYED, PatchStatus.NOT_APPLICABLE):
score = patch.cvss_score
patch.ics_cert_advisory:
score +=
asset_id patch.affected_assets:
asset = .assets.get(asset_id, {})
asset.get():
score +=
asset.get() (, ):
score +=
score = (score, )
score >= :
patch.risk_rating =
score >= :
patch.risk_rating =
score >= :
patch.risk_rating =
:
patch.risk_rating =
():
now = datetime.now()
approaching = []
patch .patches:
patch.status == PatchStatus.IDENTIFIED:
deadline = datetime.fromisoformat(patch.evaluation_deadline)
days_remaining = (deadline - now).days
days_remaining <= :
approaching.append((patch, days_remaining))
(approaching, key= x: x[])
():
patch .patches:
patch.patch_id == patch_id:
patch.status = PatchStatus.DEFERRED
patch.compensating_controls = compensating_controls
patch.test_results =
():
.prioritize_patches()
report = []
report.append( * )
report.append()
report.append()
report.append( * )
status_counts = defaultdict()
p .patches:
status_counts[p.status] +=
report.append()
status, count status_counts.items():
report.append()
approaching = .get_patches_needing_evaluation()
approaching:
report.append()
patch, days approaching:
report.append()
urgent = [p p .patches
p.risk_rating (, )
p.status (PatchStatus.DEPLOYED, PatchStatus.NOT_APPLICABLE)]
urgent:
report.append()
p urgent:
report.append()
report.append()
report.append()
report.append()
deferred = [p p .patches p.status == PatchStatus.DEFERRED]
deferred:
report.append()
p deferred:
report.append()
report.append()
report.append()
.join(report)
__name__ == :
manager = OTPatchManager()
manager.add_patch(OTPatch(
patch_id=,
vendor=,
product=,
affected_versions=,
cve_ids=[],
cvss_score=,
ics_cert_advisory=,
description=,
identified_date=,
affected_assets=[, , ],
))
manager.add_patch(OTPatch(
patch_id=,
vendor=,
product=,
affected_versions=,
cve_ids=[],
cvss_score=,
ics_cert_advisory=,
description=,
identified_date=,
affected_assets=[, ],
))
(manager.generate_report())