65 lines
1.9 KiB
Python
65 lines
1.9 KiB
Python
from enum import Enum
|
|
import re
|
|
|
|
|
|
class RiskLevel(Enum):
|
|
SAFE = 0
|
|
LOW = 1
|
|
MEDIUM = 2
|
|
HIGH = 3
|
|
CRITICAL = 4
|
|
|
|
|
|
RISK_PATTERNS: list = [
|
|
(RiskLevel.CRITICAL, [
|
|
r"rm\s+-rf", r"DROP\s+TABLE", r"DELETE\s+FROM", r"truncate",
|
|
r"gcloud\s+(iam|secrets)\s+delete", r"kubectl\s+delete\s+namespace",
|
|
]),
|
|
(RiskLevel.HIGH, [
|
|
r"gcloud\s+run\s+deploy", r"terraform\s+apply", r"gcloud\s+dns",
|
|
r"gcloud\s+compute\s+forwarding-rules", r"gcloud\s+sql\s+instances\s+delete",
|
|
]),
|
|
(RiskLevel.MEDIUM, [
|
|
r"pip\s+install", r"gcloud\s+compute\s+(delete|stop|reset)",
|
|
r"kubectl\s+delete", r"docker\s+rm",
|
|
]),
|
|
(RiskLevel.LOW, [
|
|
r"git\s+(push|commit|merge)", r"gcloud\s+run\s+describe",
|
|
]),
|
|
]
|
|
|
|
|
|
class EmmaGuardrails:
|
|
"""
|
|
5-nivå risikosjekk.
|
|
Guardrails kan IKKE deaktiveres av Emma selv — kun Chris kan kalle grant_go().
|
|
"""
|
|
|
|
def __init__(self):
|
|
self._go_granted: bool = False
|
|
|
|
def check(self, command: str) -> RiskLevel:
|
|
for level, patterns in RISK_PATTERNS:
|
|
if any(re.search(p, command, re.IGNORECASE) for p in patterns):
|
|
return level
|
|
return RiskLevel.SAFE
|
|
|
|
def can_execute(self, command: str, confirmed_by_chris: bool = False) -> tuple:
|
|
level = self.check(command)
|
|
if level == RiskLevel.CRITICAL:
|
|
return False, "CRITICAL: Alltid blokkert"
|
|
if level == RiskLevel.HIGH:
|
|
if confirmed_by_chris or self._go_granted:
|
|
return True, "HIGH: GO fra Chris"
|
|
return False, "HIGH: Krever eksplisitt GO fra Chris"
|
|
if level == RiskLevel.MEDIUM:
|
|
return False, "MEDIUM: Emma må be om bekreftelse"
|
|
return True, f"{level.name}: Tillatt"
|
|
|
|
def grant_go(self):
|
|
"""Kun Chris kaller denne."""
|
|
self._go_granted = True
|
|
|
|
def revoke_go(self):
|
|
self._go_granted = False
|