Replace inventory-counting risk with bounded workload scoring and separate confidence

This commit is contained in:
2026-10-30 12:34:39 -07:00
parent f65ade9fff
commit 57e716b710
26 changed files with 10351 additions and 87 deletions

View File

@@ -0,0 +1,55 @@
"""Data-only scoring policy. No executable expressions or arbitrary regex rules."""
import copy
import hashlib
import json
from pathlib import Path
DEFAULT_POLICY = Path(__file__).resolve().parents[1] / 'assets' / 'scoring_policy.json'
RULES = {'installed_workload_role', 'running_application_service', 'attributed_application_listener',
'observed_application_clients', 'configured_business_share', 'observed_smb_transport',
'observed_business_share_clients', 'configured_custom_schedule', 'verified_domain_controller'}
def load_policy(source=None):
if source is not None and not isinstance(source,(dict,str,Path)):
raise ValueError('A scoring policy must be a JSON object or file path.')
if isinstance(source, dict):
policy = copy.deepcopy(source)
else:
path = Path(source) if source is not None else DEFAULT_POLICY
try:
if path.stat().st_size > 65536:
raise ValueError('Scoring policy exceeds 64 KiB.')
policy = json.loads(path.read_text(encoding='utf-8'))
except (OSError, UnicodeError, json.JSONDecodeError, RecursionError):
raise ValueError('Unable to read a valid UTF-8 scoring policy JSON file.') from None
try:
limits, weights = policy['thresholds'], policy['coverage_weights']
valid = (
set(policy) == {'model_version','name','scores','thresholds','coverage_weights','partial_check_credit'}
and policy['model_version'] == '2.0' and isinstance(policy['name'],str) and 0<len(policy['name'])<=120
and set(policy['scores']) == RULES
and all(type(value) is int and 0<=value<=100 for value in policy['scores'].values())
and set(limits) == {'low','medium','high','critical'}
and all(type(value) is int for value in limits.values())
and 1 == limits['low'] < limits['medium'] < limits['high'] < limits['critical'] <= 100
and set(weights) == {'system','roles','services','network','tasks','software','storage','shares','certificates'}
and all(type(weight) is int and 1<=weight<=10 for weight in weights.values())
and type(policy['partial_check_credit']) in (int,float) and 0<=policy['partial_check_credit']<1
)
except (KeyError,TypeError,AttributeError):
valid = False
if not valid:
raise ValueError('Invalid scoring policy. Use the bundled v2 policy structure, integer scores 0–100, ordered thresholds and positive coverage weights.')
return policy
def policy_id(policy):
return hashlib.sha256(json.dumps(policy, sort_keys=True).encode('utf-8')).hexdigest()
def risk_level(score, policy):
for name in ('critical','high','medium','low'):
if score >= policy['thresholds'][name]:
return name
return 'informational'