from __future__ import annotations from typing import Any, Literal from pydantic import BaseModel, Field from .ai_security import Confidence, Severity RemediationPlanStatus = Literal['draft', 'reviewed', 'approved_for_manual_execution', 'dismissed'] RemediationSourceType = Literal['security_finding', 'security_recommendation', 'media_issue', 'inventory', 'connector', 'policy', 'secret', 'unknown'] RemediationStepType = Literal[ 'open_page', 'configure_secret', 'bind_connector', 'review_policy', 'request_approval', 'run_readonly_check', 'manual_external_change', 'blocked_action', 'documentation', ] DryRunStatus = Literal['pass', 'warning', 'blocked'] class RemediationEvidence(BaseModel): source: str label: str value: Any = None redacted: bool = False class RemediationApprovalRequirement(BaseModel): actionId: str target: str reason: str risk: str policyDecision: str class RemediationVerificationCheck(BaseModel): label: str endpoint: str expectedResult: str source: str readOnly: bool = True class RemediationStep(BaseModel): id: str label: str description: str type: RemediationStepType actionId: str | None = None target: str | None = None href: str | None = None policyDecision: str = 'allowed' risk: str = 'low' requiresApproval: bool = False canExecute: bool = False evidence: list[RemediationEvidence] = Field(default_factory=list) class RemediationPlan(BaseModel): id: str title: str description: str sourceType: RemediationSourceType sourceId: str severity: Severity confidence: Confidence status: RemediationPlanStatus = 'draft' affectedResources: list[str] = Field(default_factory=list) prerequisites: list[str] = Field(default_factory=list) steps: list[RemediationStep] = Field(default_factory=list) verificationChecks: list[RemediationVerificationCheck] = Field(default_factory=list) blockedActions: list[RemediationStep] = Field(default_factory=list) approvalRequirements: list[RemediationApprovalRequirement] = Field(default_factory=list) riskAssessment: str estimatedImpact: str rollbackNotes: str auditPreview: str createdAt: str updatedAt: str executable: bool = False class RemediationPlanCollection(BaseModel): status: str generatedAt: str total: int plans: list[RemediationPlan] class RemediationDryRunStepResult(BaseModel): stepId: str label: str actionId: str | None = None target: str | None = None policyDecision: str risk: str status: DryRunStatus reason: str canExecute: bool = False class RemediationDryRunResult(BaseModel): planId: str status: DryRunStatus executed: bool = False reasons: list[str] = Field(default_factory=list) prerequisites: list[str] = Field(default_factory=list) unresolvedBlockers: list[str] = Field(default_factory=list) blockedActions: list[RemediationApprovalRequirement] = Field(default_factory=list) approvalRequirements: list[RemediationApprovalRequirement] = Field(default_factory=list) verificationChecks: list[RemediationVerificationCheck] = Field(default_factory=list) stepResults: list[RemediationDryRunStepResult] = Field(default_factory=list) class RemediationApprovalProposal(BaseModel): planId: str created: bool executed: bool = False approvalId: str | None = None proposals: list[RemediationApprovalRequirement] = Field(default_factory=list) message: str