Autonomous security loop controller. Requires an active EngagementSession before any method can run. All exploit and remediation operations are gated through guardrails.
| 136 | |
| 137 | class RedBlueOrchestrator: |
| 138 | """ |
| 139 | Autonomous security loop controller. |
| 140 | |
| 141 | Requires an active EngagementSession before any method can run. |
| 142 | All exploit and remediation operations are gated through guardrails. |
| 143 | """ |
| 144 | |
| 145 | def __init__( |
| 146 | self, |
| 147 | msf_host: str = "127.0.0.1", |
| 148 | msf_port: int = 55553, |
| 149 | msf_password: str = "", |
| 150 | ollama_host: str = "http://localhost:11434", |
| 151 | ollama_model: str = "llama3.1:latest", |
| 152 | output_dir: str = "/tmp/secsuite-loop", |
| 153 | ) -> None: |
| 154 | self._exploit_runner = ExploitRunner( |
| 155 | msf_host=msf_host, msf_port=msf_port, msf_password=msf_password, |
| 156 | ) |
| 157 | self._remediation_ai = RemediationAI(model=ollama_model, ollama_host=ollama_host) |
| 158 | self._hardener = AutoHardener(snapshot_dir=f"{output_dir}/snapshots") |
| 159 | self._output_dir = output_dir |
| 160 | os.makedirs(output_dir, exist_ok=True) |
| 161 | |
| 162 | async def run( |
| 163 | self, |
| 164 | target: str, |
| 165 | mode: str = "confirm_only", |
| 166 | scan_profile: str = "normal", |
| 167 | os_hint: str = "Linux", |
| 168 | max_exploit_concurrent: int = 5, |
| 169 | ) -> LoopReport: |
| 170 | """ |
| 171 | Execute the red-blue loop against a target. |
| 172 | |
| 173 | Args: |
| 174 | target: IP, CIDR, hostname, or range |
| 175 | mode: recon_only | confirm_only | confirm_and_plan | full_auto |
| 176 | scan_profile: Scan intensity: quick | normal | full | stealth |
| 177 | os_hint: OS family for AI remediation prompts |
| 178 | max_exploit_concurrent: Max parallel Metasploit check() calls |
| 179 | """ |
| 180 | if mode not in VALID_MODES: |
| 181 | raise ValueError(f"Invalid mode '{mode}'. Choose from: {VALID_MODES}") |
| 182 | |
| 183 | session = guardrails.active_session() |
| 184 | if not session: |
| 185 | raise PermissionError( |
| 186 | "No active engagement session. " |
| 187 | "Call guardrails.create_session() before running the loop." |
| 188 | ) |
| 189 | if session.is_expired(): |
| 190 | raise PermissionError("Engagement session has expired. Create a new session.") |
| 191 | |
| 192 | report = LoopReport( |
| 193 | target=target, |
| 194 | mode=mode, |
| 195 | operator=session.operator, |
no outgoing calls
no test coverage detected