docs: define milestone v3.0 requirements
This commit is contained in:
parent
149bd08bd6
commit
cefa963565
1 changed files with 161 additions and 49 deletions
|
|
@ -1,74 +1,186 @@
|
|||
# Requirements: PAX8 Integration (v2.0)
|
||||
# Requirements: Pulse — v3.0 Phishing Triage Automation
|
||||
|
||||
**Defined:** 2026-07-10
|
||||
**Core Value:** Managers can see PAX8 subscription costs and seat counts alongside existing Autotask company data in Pulse, without manually cross-referencing PAX8's own portal.
|
||||
**Source:** `.planning/seeds/SEED-002-pax8-integration.md` (scoped via `/gsd-explore` on 2026-07-10)
|
||||
**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.
|
||||
|
||||
## v2.0 Requirements
|
||||
## v1 Requirements
|
||||
|
||||
Requirements for this milestone. Each maps to a roadmap phase.
|
||||
### Detection
|
||||
|
||||
### PAX8 — Client & Auth
|
||||
- [ ] **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")
|
||||
- [ ] **DETECT-02**: Re-scanning does not reprocess a ticket already ingested unless
|
||||
its source ticket data has changed since last processed (idempotent)
|
||||
- [ ] **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
|
||||
|
||||
- [x] **PAX8-01**: Pulse authenticates to the PAX8 REST API (`api.pax8.com/v1`) via OAuth2 client-credentials, using the developer-provisioned client ID/secret
|
||||
- [x] **PAX8-02**: `isPax8Configured()` helper reports whether PAX8 credentials are present, following the existing `is<Name>Configured()` factory pattern (`lib/services/pax8-factory.ts`)
|
||||
### Evidence Extraction
|
||||
|
||||
### PAX8 — Data Sync
|
||||
- [ ] **EVID-01**: For each candidate ticket, the system extracts ticket ID/number,
|
||||
company, requester/reporter, title, description, notes, relevant time entries,
|
||||
and attachment metadata
|
||||
- [ ] **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
|
||||
- [ ] **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)
|
||||
- [ ] **EVID-04**: The system stores a sanitized/truncated body preview alongside
|
||||
raw evidence, and never executes or fetches any URL found in a message
|
||||
|
||||
- [x] **PAX8-03**: Pulse syncs PAX8 companies into Postgres
|
||||
- [x] **PAX8-04**: Pulse syncs PAX8 subscriptions (product, seat count, billing term) into Postgres
|
||||
- [x] **PAX8-05**: Pulse syncs PAX8 product catalog (SKUs, categories) into Postgres, so subscriptions are human-readable
|
||||
- [x] **PAX8-06**: Pulse syncs PAX8 orders/invoices (historical line items) into Postgres, enabling cost reconciliation over time, not just current-state seats
|
||||
- [x] **PAX8-07**: Sync runs on a daily schedule via the existing `sync-scheduler.ts` cron pattern
|
||||
- [x] **PAX8-08**: All PAX8 sync operations are read-only — no writes back to the PAX8 API (no seat adjustments, no order placement)
|
||||
- [x] **PAX8-09**: PAX8 integration can be toggled on/off via `/admin/integrations`, consistent with other integrations (`integration_settings` table)
|
||||
### Campaign Grouping
|
||||
|
||||
### PAX8 — Company Matching
|
||||
- [ ] **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
|
||||
- [ ] **CAMP-02**: A campaign can accumulate many linked ticket reports and
|
||||
recipients over time as duplicates are detected
|
||||
- [ ] **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}`)
|
||||
|
||||
- [x] **PAX8-10**: PAX8 companies are automatically matched to existing Autotask companies by fuzzy name similarity at sync time
|
||||
- [x] **PAX8-11**: Unmatched or ambiguous company matches are flagged rather than silently guessed
|
||||
- [x] **PAX8-12**: An admin can view flagged/ambiguous company matches and manually resolve them to the correct Autotask company
|
||||
### Blast Radius (Mimecast)
|
||||
|
||||
### PAX8 — UI Surface
|
||||
- [ ] **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
|
||||
- [ ] **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
|
||||
|
||||
- [x] **PAX8-13**: A new `/pax8` page lists PAX8 companies with their subscriptions and a cost breakdown
|
||||
- [x] **PAX8-14**: The `/pax8` page surfaces flagged/ambiguous company matches (PAX8-11) for manual resolution
|
||||
### Classification
|
||||
|
||||
## Future Requirements
|
||||
- [ ] **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
|
||||
- [ ] **CLASSIFY-02**: Any classification recommending a destructive action
|
||||
(purge, block, delete, reset, etc.) always sets `requires_approval: true`
|
||||
- [ ] **CLASSIFY-03**: When evidence is incomplete (no Mimecast data, no `.eml`,
|
||||
etc.), confidence is lowered and the missing evidence is named in the reasons
|
||||
- [ ] **CLASSIFY-04**: Known/expected KnowBe4 security-awareness simulations are
|
||||
not classified as `THREAT` absent contrary evidence
|
||||
- [ ] **CLASSIFY-05**: An operator can (re-)trigger classification of a campaign
|
||||
via API (`POST /api/phishing/campaigns/{id}/classify`)
|
||||
- [ ] **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
|
||||
|
||||
<!-- Deferred — not this milestone. -->
|
||||
### Remediation & Approval Safety
|
||||
|
||||
- Write access to PAX8 (seat adjustments, order placement) — no concrete need identified yet; revisit only if reconciliation surfaces one
|
||||
- Domain-based or external-ID-based company matching, if research resolves [[RESEARCH-pax8-company-identifiers]] in `.planning/research/questions.md` and finds a more stable join key than name
|
||||
- General Pulse data assistant (chatbot) consuming this data — separate future milestone, see `.planning/seeds/SEED-003-general-pulse-data-assistant.md`
|
||||
- [ ] **REMED-01**: Recommended remediation actions are recorded as `proposed`
|
||||
but never executed automatically in this milestone
|
||||
- [ ] **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
|
||||
- [ ] **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
|
||||
- [ ] **REMED-04**: Re-running remediation against an already-completed action
|
||||
does not duplicate the destructive effect (idempotent)
|
||||
- [ ] **REMED-05**: An operator can mark a campaign as a false positive via API
|
||||
(`POST /api/phishing/campaigns/{id}/mark-false-positive`)
|
||||
- [ ] **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
|
||||
|
||||
- [ ] **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
|
||||
|
||||
- [ ] **ACCESS-01**: All `/api/phishing/*` endpoints enforce existing Pulse auth
|
||||
conventions (`requireAuth`/`requirePermission`), with approve/remediate
|
||||
requiring elevated permission beyond plain read access
|
||||
|
||||
## 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
|
||||
|
||||
<!-- Explicit exclusions with reasoning. -->
|
||||
|
||||
- Write-back to PAX8 — this integration is read-only in v2.0, matching the pattern of most existing Pulse integrations (RMM, IT Glue, Veeam)
|
||||
- Chatbot/NL query layer — deliberately separated into SEED-003 so this milestone stays scoped to the data sync itself
|
||||
| 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 |
|
||||
|-------------|-------|--------|
|
||||
| PAX8-01 | Phase 10 | Complete |
|
||||
| PAX8-02 | Phase 10 | Complete |
|
||||
| PAX8-03 | Phase 11 | Complete |
|
||||
| PAX8-04 | Phase 11 | Complete |
|
||||
| PAX8-05 | Phase 11 | Complete |
|
||||
| PAX8-08 | Phase 11 | Complete |
|
||||
| PAX8-06 | Phase 12 | Complete |
|
||||
| PAX8-10 | Phase 12 | Complete |
|
||||
| PAX8-11 | Phase 12 | Complete |
|
||||
| PAX8-07 | Phase 13 | Complete |
|
||||
| PAX8-09 | Phase 13 | Complete |
|
||||
| PAX8-12 | Phase 14 | Complete |
|
||||
| PAX8-13 | Phase 14 | Complete |
|
||||
| PAX8-14 | Phase 14 | Complete |
|
||||
| DETECT-01 | TBD | Pending |
|
||||
| DETECT-02 | TBD | Pending |
|
||||
| DETECT-03 | TBD | Pending |
|
||||
| EVID-01 | TBD | Pending |
|
||||
| EVID-02 | TBD | Pending |
|
||||
| EVID-03 | TBD | Pending |
|
||||
| EVID-04 | TBD | Pending |
|
||||
| CAMP-01 | TBD | Pending |
|
||||
| CAMP-02 | TBD | Pending |
|
||||
| CAMP-03 | TBD | Pending |
|
||||
| BLAST-01 | TBD | Pending |
|
||||
| BLAST-02 | TBD | Pending |
|
||||
| CLASSIFY-01 | TBD | Pending |
|
||||
| CLASSIFY-02 | TBD | Pending |
|
||||
| CLASSIFY-03 | TBD | Pending |
|
||||
| CLASSIFY-04 | TBD | Pending |
|
||||
| CLASSIFY-05 | TBD | Pending |
|
||||
| CLASSIFY-06 | TBD | Pending |
|
||||
| REMED-01 | TBD | Pending |
|
||||
| REMED-02 | TBD | Pending |
|
||||
| REMED-03 | TBD | Pending |
|
||||
| REMED-04 | TBD | Pending |
|
||||
| REMED-05 | TBD | Pending |
|
||||
| REMED-06 | TBD | Pending |
|
||||
| NOTE-01 | TBD | Pending |
|
||||
| ACCESS-01 | TBD | Pending |
|
||||
|
||||
**Coverage:** 14/14 v2.0 requirements mapped ✓
|
||||
**Coverage:**
|
||||
- v1 requirements: 26 total
|
||||
- Mapped to phases: 0 (pending roadmap)
|
||||
- Unmapped: 26 ⚠️ (resolved by roadmapper)
|
||||
|
||||
---
|
||||
*Requirements defined: 2026-07-10*
|
||||
*Requirements defined: 2026-07-14*
|
||||
*Last updated: 2026-07-14 after initial definition*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue