# BUILD NOTES — SENTINEL Gateway

## What this is
A runnable Flask prototype of the "Filter Before It Hits You" inbound-message
gateway. It scores messages with local heuristics, runs a **simulated** sandbox
detonation, logs everything to SQLite, and returns a **sanitized** message whose
risky links are replaced by a tokenized placeholder URL.

## Architecture
- `gateway.py` — single-file Flask app.
  - **Heuristics** (pure functions, no I/O): `analyze_url`, `analyze_attachment`,
    `looks_like_brand_impersonation`, `score_message`.
  - **Simulated sandbox**: `_simulate_detonation()` derives a synthetic verdict
    from the heuristic point score + a SHA-256 hash of the artifact string. It
    always returns `real_execution: false`.
  - **Tokenization**: `_tokenize_link()` produces a stable
    `https://gateway.sentinel.local/t/<12-hex>` placeholder; `_sanitize()` swaps
    risky links inside the body and quarantines risky attachments.
  - **Persistence**: SQLite table `scans` (id, ts, sender, subject, verdict,
    score, reasons JSON, raw_message JSON, full result JSON).
- `templates/dashboard.html` — dark security-console UI (Space Grotesk / Inter /
  JetBrains Mono via CDN). KPI cards, scan log with clickable detail, and an
  animated concept diagram explaining the tokenizing filter. Polls the API every
  8 s.

## Scoring model
Additive point score → verdict thresholds (`>=7` malicious, `>=3` suspicious,
else clean). Keyword contribution is capped so a single artifact signal (e.g. an
`.exe`) can still dominate appropriately. Thresholds were tuned against the seed
corpus to give a realistic clean/suspicious/malicious spread (verified: 4/1/5).

## Safety review (against ../shared/BRIEF.md)
- **Guardrail 1 & 3 (no reaching out, simulated analysis only):** grep confirms
  no outbound network call touches any scanned link/attachment. The only HTTP is
  the local Flask server and the optional seeder posting to `localhost`. No
  `subprocess`, no file execution, no fetch of scanned URLs.
- **Guardrail 5 (synthetic data):** all seed messages use example/reserved/.local
  domains and fictional content.
- Every scan response includes an explicit `disclaimer` and each sandbox verdict
  carries `real_execution: false` and a `note` restating that nothing ran.

## Verification performed
- `python demo_seed.py --offline` → seeded 10 messages, correct verdict spread.
- Started server, seeded over HTTP, confirmed `/api/stats` = clean:4 susp:1 mal:5.
- Single `POST /scan` confirmed: verdict `malicious`, body link rewritten to a
  `gateway.sentinel.local/t/...` token, `real_execution: false`.
- `GET /` returns HTTP 200.
- Dashboard screenshot could not be captured (remote screenshotter can't reach
  the sandbox localhost, and Playwright is not installed), but the HTML +
  JSON API contract is verified and self-consistent.

## Possible next steps (not built)
- Real click-time re-inspection behind the token URL.
- Tier-aware policy (stricter thresholds / mandatory quarantine at Tier 3).
- Pluggable threat-intel feeds; DKIM/SPF/DMARC header parsing.
