Scanning Flow¶
Prompt Scanning¶
sequenceDiagram
participant C as Cursor IDE
participant H as beforeSubmitPrompt Hook
participant S as Scanner
participant CB as Circuit Breaker
participant A as AIRS Sync API
C->>H: stdin JSON { prompt, user_email, ... }
H->>S: scanPrompt(config, prompt, logger)
S->>CB: shouldAllow()
alt Circuit Open
CB-->>S: false (bypass)
S-->>H: { action: "pass" }
else Circuit Closed/Half-Open
CB-->>S: true
S->>A: POST /v1/scan/sync/request { prompt }
A-->>S: { action, prompt_detected }
S->>CB: recordSuccess() / recordFailure()
alt Enforce + Block Verdict
S-->>H: { action: "block", message }
H-->>C: { continue: false, user_message }
else Allow / Observe
S-->>H: { action: "pass" }
H-->>C: { continue: true }
end
end
Response Scanning¶
sequenceDiagram
participant C as Cursor IDE
participant H as afterAgentResponse Hook
participant X as Code Extractor
participant S as Scanner
participant A as AIRS Sync API
C->>H: stdin JSON { text, ... }
H->>S: scanResponse(config, text, logger)
S->>X: extractCode(text)
X-->>S: { naturalLanguage, codeBlocks[] }
S->>A: POST /v1/scan/sync/request { response, code_response }
A-->>S: { action, response_detected }
alt Enforce + Block Verdict
S-->>H: { action: "block", message }
H-->>C: { permission: "deny" } + exit 2
else Allow / Observe
S-->>H: { action: "pass" }
H-->>C: { permission: "allow" }
end
Code Extraction Strategy¶
The code extractor processes AI responses using three strategies in priority order:
- Fenced code blocks --
```language ... ```with language detection - Indented code blocks -- 4+ leading spaces
- Heuristic fallback -- content matching code indicators (imports, function definitions, braces) above a character threshold
Extracted code is joined with \n\n---\n\n separators and sent in the code_response field, which triggers WildFire/ATP malicious code scanning on the AIRS side.
Content Splitting¶
| AIRS Field | Content | Detections |
|---|---|---|
prompt |
User's prompt text | Prompt injection, DLP, toxicity, custom topics |
response |
Natural language from AI response | DLP, toxicity, URL categorization |
code_response |
Extracted code blocks | Malicious code (WildFire/ATP) |
Why split content?
Sending code separately in code_response enables dedicated malicious code detection engines (WildFire, ATP) that don't run on natural language content. This catches things like reverse shells, credential stealers, and obfuscated payloads in generated code.