chore: remove REQUIREMENTS.md for v3.0 milestone
Archived to .planning/milestones/v3.0-REQUIREMENTS.md. Fresh REQUIREMENTS.md gets created when the next milestone's requirements are defined. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W6RuWdiUiXrPK6FLBHjtpY
This commit is contained in:
parent
e5d42bda88
commit
075c4bbd24
1 changed files with 0 additions and 254 deletions
|
|
@ -1,254 +0,0 @@
|
|||
# Requirements: Pulse — v3.0 Phishing Triage Automation
|
||||
|
||||
**Defined:** 2026-07-14
|
||||
**Core Value:** A manager/security operator can see every phishing/spam report ticket
|
||||
automatically triaged, deduplicated into campaigns, and classified — with any
|
||||
destructive remediation gated behind explicit human approval.
|
||||
|
||||
## v1 Requirements
|
||||
|
||||
### Detection
|
||||
|
||||
- [x] **DETECT-01**: System scans recent Autotask/Pulse tickets and flags candidates
|
||||
matching known phishing/spam-report patterns (title/body: "Phishing Report",
|
||||
"Spam Alert", "Phishing Alert - Email Security Report", "KnowBe4 Phish Alert
|
||||
Report", "Source: KnowBe4 Phish Alert Button", "userSubmissionsReportMessage",
|
||||
"reported message destinations", "Microsoft directly")
|
||||
- [x] **DETECT-02**: Re-scanning does not reprocess a ticket already ingested unless
|
||||
its source ticket data has changed since last processed (idempotent)
|
||||
- [x] **DETECT-03**: An operator can trigger analysis of one specific ticket by ID
|
||||
on demand (`POST /api/phishing/tickets/{ticket_id}/analyze`) instead of waiting
|
||||
for the scheduled scan
|
||||
|
||||
### Evidence Extraction
|
||||
|
||||
- [x] **EVID-01**: For each candidate ticket, the system extracts ticket ID/number,
|
||||
company, requester/reporter, title, description, notes, relevant time entries,
|
||||
and attachment metadata
|
||||
- [x] **EVID-02**: When multiple `.eml` attachments exist, the system prefers
|
||||
`rfc.eml` as the original reported message over `OriginatingEmail.eml`
|
||||
(wrapper/context), matching case-insensitively and by `message/rfc822`
|
||||
content-type, not filename alone
|
||||
- [x] **EVID-03**: The system parses the selected original email's RFC822/MIME
|
||||
structure into normalized headers (From, display name, sender email/domain,
|
||||
Reply-To, Return-Path, To, Cc, Subject, Date, Message-ID, Received chain,
|
||||
SPF/DKIM/DMARC authentication results), extracted URLs, and attachment
|
||||
metadata (name, content-type, size, hash)
|
||||
- [x] **EVID-04**: The system stores a sanitized/truncated body preview alongside
|
||||
raw evidence, and never executes or fetches any URL found in a message
|
||||
|
||||
### Campaign Grouping
|
||||
|
||||
- [x] **CAMP-01**: Reports are grouped into a campaign using original Message-ID
|
||||
first, then attachment-hash/URL-domain + subject + sender + time-window, then
|
||||
sender + normalized subject + client + time-window as fallback keys
|
||||
- [x] **CAMP-02**: A campaign can accumulate many linked ticket reports and
|
||||
recipients over time as duplicates are detected
|
||||
- [x] **CAMP-03**: An operator can list campaigns and view a single campaign's
|
||||
full detail (linked reports, messages, indicators, classification history)
|
||||
via API (`GET /api/phishing/campaigns`, `GET /api/phishing/campaigns/{id}`)
|
||||
|
||||
### Blast Radius (Mimecast)
|
||||
|
||||
- [x] **BLAST-01**: The system can query a Mimecast blast-radius abstraction for
|
||||
message delivery data (matched/delivered/held/rejected/clicked counts,
|
||||
per-recipient status) when Mimecast is configured, keyed on message ID,
|
||||
sender, recipient/reporter, subject, and date window
|
||||
- [x] **BLAST-02**: When Mimecast is not configured, the system records
|
||||
`status: unavailable` for that lookup and classification proceeds using
|
||||
ticket/email evidence alone — it never blocks on missing Mimecast config
|
||||
|
||||
### Classification
|
||||
|
||||
- [x] **CLASSIFY-01**: The system classifies a campaign as exactly one of
|
||||
`SPAM` / `UNWANTED` / `THREAT`, with confidence, a short summary,
|
||||
evidence-backed reasons, recommended actions, and a `requires_approval` flag
|
||||
- [x] **CLASSIFY-02**: Any classification recommending a destructive action
|
||||
(purge, block, delete, reset, etc.) always sets `requires_approval: true`
|
||||
- [x] **CLASSIFY-03**: When evidence is incomplete (no Mimecast data, no `.eml`,
|
||||
etc.), confidence is lowered and the missing evidence is named in the reasons
|
||||
- [x] **CLASSIFY-04**: Known/expected KnowBe4 security-awareness simulations are
|
||||
not classified as `THREAT` absent contrary evidence
|
||||
- [x] **CLASSIFY-05**: An operator can (re-)trigger classification of a campaign
|
||||
via API (`POST /api/phishing/campaigns/{id}/classify`)
|
||||
- [x] **CLASSIFY-06**: The classifier accepts structured, size-bounded evidence
|
||||
(not raw unbounded email bodies) — long bodies are redacted/truncated before
|
||||
reaching any AI layer, and IT Glue-sourced evidence goes through the existing
|
||||
redacted search path if referenced
|
||||
|
||||
### Remediation & Approval Safety
|
||||
|
||||
- [x] **REMED-01**: Recommended remediation actions are recorded as `proposed`
|
||||
but never executed automatically in this milestone
|
||||
- [x] **REMED-02**: An authorized operator can approve a campaign's remediation
|
||||
via API (`POST /api/phishing/campaigns/{id}/approve`), recording approver,
|
||||
timestamp, and the exact approved action parameters
|
||||
- [x] **REMED-03**: `POST /api/phishing/campaigns/{id}/remediate` proceeds only
|
||||
for approved actions against a configured, non-destructive-by-default
|
||||
provider path; otherwise it returns `not_implemented`/an explicit failure —
|
||||
it never silently succeeds without taking or logging an action
|
||||
- [x] **REMED-04**: Re-running remediation against an already-completed action
|
||||
does not duplicate the destructive effect (idempotent)
|
||||
- [x] **REMED-05**: An operator can mark a campaign as a false positive via API
|
||||
(`POST /api/phishing/campaigns/{id}/mark-false-positive`)
|
||||
- [x] **REMED-06**: Every state-changing action (classify, approve, remediate,
|
||||
mark-false-positive) is recorded as an audit event with actor, event type,
|
||||
and payload
|
||||
|
||||
### Autotask Integration
|
||||
|
||||
- [x] **NOTE-01**: If Pulse already has a safe Autotask note-writing method, the
|
||||
system can post an internal triage note summarizing classification, evidence,
|
||||
blast radius, and recommended actions (sanitized — no raw secrets/tokens/full
|
||||
malicious URL query strings); otherwise the note text is returned via API
|
||||
without writing anything to Autotask
|
||||
|
||||
### Access Control
|
||||
|
||||
- [x] **ACCESS-01**: All `/api/phishing/*` endpoints enforce existing Pulse auth
|
||||
conventions (`requireAuth`/`requirePermission`), with approve/remediate
|
||||
requiring elevated permission beyond plain read access
|
||||
|
||||
### Approval UI (LiveLink)
|
||||
|
||||
- [x] **REVIEW-01**: A stable, ticket-ID-addressable Pulse route (e.g.
|
||||
`/phishing/tickets/{ticketId}`) resolves the ticket to its campaign and
|
||||
renders that campaign's review page, suitable as an Autotask LiveLink target
|
||||
(LiveLink supplies the ticket ID as dynamic content, not the internal
|
||||
campaign UUID), authenticated via the existing Better Auth session only —
|
||||
no separate token or query-param auth scheme
|
||||
- [x] **REVIEW-02**: The page displays the campaign's timeline — linked
|
||||
reports, classification history, and audit events (classify/approve/
|
||||
remediate/mark-false-positive) — in chronological order
|
||||
- [x] **REVIEW-03**: The page displays the gathered evidence — parsed EML
|
||||
headers/URLs/attachments, sanitized body preview, and Mimecast blast-radius
|
||||
data (including an explicit `unavailable` state when Mimecast isn't
|
||||
configured) — never rendering a raw/unsanitized body or unredacted secrets
|
||||
- [x] **REVIEW-04**: The page displays the current classification (SPAM/
|
||||
UNWANTED/THREAT), confidence, reasons, and recommended remediation
|
||||
action(s)
|
||||
- [x] **REVIEW-05**: An operator can approve, remediate, or mark a campaign as
|
||||
a false positive directly from the page, calling the existing
|
||||
`/api/phishing/campaigns/{id}` approve/remediate/mark-false-positive
|
||||
endpoints and reflecting the resulting state (e.g. a remediated campaign
|
||||
shows as remediated, not re-offered for approval)
|
||||
- [x] **REVIEW-06**: An operator without the elevated permission approve/
|
||||
remediate already require sees those actions disabled or hidden rather than
|
||||
a failed request; the page enforces no separate or relaxed permission model
|
||||
from the underlying APIs
|
||||
|
||||
### Classification Disposition + Automation Gate
|
||||
|
||||
- [x] **CLASSDISP-01**: The classifier assigns a dedicated `USER_AWARENESS`
|
||||
verdict to campaigns confirmed as phishing-simulation-vendor (KnowBe4/Breach
|
||||
Secure Now) reports, replacing the previous forced-`UNWANTED` disposition
|
||||
for these confirmed-simulation cases
|
||||
- [x] **CLASSDISP-02**: `USER_AWARENESS` maps to a new non-destructive
|
||||
`acknowledge_user` action that posts a customer-visible thank-you note
|
||||
(Autotask `noteType: 18`, "Client Portal Note") to the reporting employee
|
||||
- [x] **CLASSDISP-03**: The campaign review UI surfaces `USER_AWARENESS` and
|
||||
`acknowledge_user` distinctly from the existing SPAM/UNWANTED/THREAT
|
||||
verdicts and their actions
|
||||
- [x] **AUTOGATE-01**: A per-company `phishing_automation_gate` table and
|
||||
admin-gated `GET`/`PATCH`/`DELETE` API let an operator read and set three
|
||||
independent opt-in automation flags (`auto_parse`, `auto_classify`,
|
||||
`auto_report`) per Autotask company, defaulting to all-OFF when no row
|
||||
exists
|
||||
- [x] **AUTOGATE-02**: An `/admin/phishing-automation` page lists companies
|
||||
with three independent per-company `Switch` toggles (one per automation
|
||||
stage), backed by the `AUTOGATE-01` API
|
||||
- [x] **AUTOGATE-03**: When a company's automation gate stages are enabled,
|
||||
the Autotask webhook automatically runs the gated parse→classify→acknowledge
|
||||
chain for that company's phishing reports, with the `acknowledge_user`
|
||||
auto-post carve-out narrowly scoped to `USER_AWARENESS` verdicts only — all
|
||||
other verdicts/actions still require manual approval regardless of gate
|
||||
state
|
||||
|
||||
## v2 Requirements
|
||||
|
||||
Deferred to future release. Tracked but not in current roadmap.
|
||||
|
||||
### Remediation Execution
|
||||
|
||||
- **REMEDEXEC-01**: Actually execute Mimecast sender/domain/URL block (behind
|
||||
approval, once REMED-01..06 land and are trusted)
|
||||
- **REMEDEXEC-02**: Microsoft Graph mailbox search/delete/move for delivered
|
||||
copies
|
||||
- **REMEDEXEC-03**: Microsoft Defender/Exchange purge (may be preferable to
|
||||
Graph — needs its own evaluation)
|
||||
- **REMEDEXEC-04**: Auto-create/associate an Autotask parent incident ticket
|
||||
- **REMEDEXEC-05**: Auto-close duplicate reports once a campaign is resolved
|
||||
|
||||
### Enrichment
|
||||
|
||||
- **ENRICH-01**: URL reputation lookup / safe expansion of shortened links
|
||||
(without detonation)
|
||||
- **ENRICH-02**: LLM-backed classification layer wired into the
|
||||
`CLASSIFY-*` rule engine (rule layer ships first; this plugs in behind the
|
||||
same interface)
|
||||
|
||||
## Out of Scope
|
||||
|
||||
| Feature | Reason |
|
||||
|---------|--------|
|
||||
| Automatic tenant-wide mailbox purge | Destructive; requires proven accuracy and explicit approval infrastructure first (REMED-01..04) |
|
||||
| Automatic password reset / session revocation | Too high-blast-radius for an MVP triage tool; human-in-the-loop only |
|
||||
| URL detonation / sandbox execution | Security risk of interacting with malicious infra; reputation-only enrichment deferred to v2 |
|
||||
| Fully automated ticket closure | Accuracy not yet proven; operator closes tickets manually in this milestone |
|
||||
| Assuming Microsoft Graph is the eventual purge mechanism | Defender/Exchange purge may be preferable; decision deferred to whichever v2 remediation-execution phase picks it up |
|
||||
| Real customer `.eml` fixtures in tests | Privacy/security — all test fixtures are synthetic |
|
||||
|
||||
## Traceability
|
||||
|
||||
Populated during roadmap creation.
|
||||
|
||||
| Requirement | Phase | Status |
|
||||
|-------------|-------|--------|
|
||||
| DETECT-01 | Phase 15 | Complete |
|
||||
| DETECT-02 | Phase 15 | Complete |
|
||||
| DETECT-03 | Phase 18 | Complete |
|
||||
| EVID-01 | Phase 15 | Complete |
|
||||
| EVID-02 | Phase 16 | Complete |
|
||||
| EVID-03 | Phase 16 | Complete |
|
||||
| EVID-04 | Phase 16 | Complete |
|
||||
| CAMP-01 | Phase 18 | Complete |
|
||||
| CAMP-02 | Phase 18 | Complete |
|
||||
| CAMP-03 | Phase 18 | Complete |
|
||||
| BLAST-01 | Phase 17 | Complete |
|
||||
| BLAST-02 | Phase 17 | Complete |
|
||||
| CLASSIFY-01 | Phase 19 | Complete |
|
||||
| CLASSIFY-02 | Phase 19 | Complete |
|
||||
| CLASSIFY-03 | Phase 19 | Complete |
|
||||
| CLASSIFY-04 | Phase 19 | Complete |
|
||||
| CLASSIFY-05 | Phase 19 | Complete |
|
||||
| CLASSIFY-06 | Phase 19 | Complete |
|
||||
| REMED-01 | Phase 20 | Complete |
|
||||
| REMED-02 | Phase 20 | Complete |
|
||||
| REMED-03 | Phase 20 | Complete |
|
||||
| REMED-04 | Phase 20 | Complete |
|
||||
| REMED-05 | Phase 20 | Complete |
|
||||
| REMED-06 | Phase 20 | Complete |
|
||||
| NOTE-01 | Phase 21 | Complete |
|
||||
| ACCESS-01 | Phase 18 | Complete |
|
||||
| REVIEW-01 | Phase 22 | Complete |
|
||||
| REVIEW-02 | Phase 22 | Complete |
|
||||
| REVIEW-03 | Phase 22 | Complete |
|
||||
| REVIEW-04 | Phase 22 | Complete |
|
||||
| REVIEW-05 | Phase 22 | Complete |
|
||||
| REVIEW-06 | Phase 22 | Complete |
|
||||
| CLASSDISP-01 | Phase 23 | Complete |
|
||||
| CLASSDISP-02 | Phase 23 | Complete |
|
||||
| CLASSDISP-03 | Phase 23 | Complete |
|
||||
| AUTOGATE-01 | Phase 23 | Complete |
|
||||
| AUTOGATE-02 | Phase 23 | Complete |
|
||||
| AUTOGATE-03 | Phase 23 | Complete |
|
||||
|
||||
**Coverage:**
|
||||
- v1 requirements: 38 total
|
||||
- Mapped to phases: 38 (Phases 15-23)
|
||||
- Unmapped: 0 ✓
|
||||
|
||||
---
|
||||
*Requirements defined: 2026-07-14*
|
||||
*Traceability populated: 2026-07-14 — ROADMAP.md Phases 15-21*
|
||||
*Last updated: 2026-07-16 — backfilled Phase 23 CLASSDISP-*/AUTOGATE-* entries (23-03)*
|
||||
Loading…
Add table
Add a link
Reference in a new issue