added kiro specs
This commit is contained in:
86
.kiro/specs/finding-archive-tracking/requirements.md
Normal file
86
.kiro/specs/finding-archive-tracking/requirements.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Requirements Document
|
||||
|
||||
## Introduction
|
||||
|
||||
The Finding Archive Tracking system extends the Ivanti sync pipeline in the STEAM Security Dashboard to detect and track findings that disappear from sync results due to severity score drift (not remediation). Findings follow a four-state lifecycle (ACTIVE → ARCHIVED → RETURNED → CLOSED) with full transition history, enabling the security team to maintain visibility into findings that fall below the severity threshold and may reappear.
|
||||
|
||||
## Glossary
|
||||
|
||||
- **Sync_Pipeline**: The existing Ivanti/RiskSense host finding sync process that fetches open findings matching BU and severity filters on a daily schedule.
|
||||
- **Finding**: A single host-level vulnerability record identified by a unique `finding_id` from Ivanti/RiskSense.
|
||||
- **Archive_Record**: A database row in the `ivanti_finding_archives` table tracking a finding's current lifecycle state and metadata.
|
||||
- **Transition_History**: A database row in the `ivanti_archive_transitions` table recording a single state change event with timestamps, severity scores, and reason.
|
||||
- **Archive_Detector**: The logic within the sync pipeline that compares previous sync results against current results to identify disappeared and returned findings.
|
||||
- **Archive_Summary_Bar**: A React UI component displaying counts for each lifecycle state (ACTIVE, ARCHIVED, RETURNED, CLOSED) with click-through navigation.
|
||||
- **Archive_API**: The set of three Express route endpoints serving archived finding data, transition history, and summary statistics.
|
||||
- **Lifecycle_State**: One of four states a finding can occupy: ACTIVE (present in sync results), ARCHIVED (disappeared from sync results due to score drift), RETURNED (reappeared after being archived), CLOSED (remediated in Ivanti).
|
||||
|
||||
## Requirements
|
||||
|
||||
### Requirement 1: Archive Detection During Sync
|
||||
|
||||
**User Story:** As a security analyst, I want the system to automatically detect findings that disappear from sync results, so that I can track findings lost due to severity score drift rather than actual remediation.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN the Sync_Pipeline completes a sync, THE Archive_Detector SHALL compare the current sync result finding IDs against the previous sync result finding IDs to identify findings that are no longer present.
|
||||
2. WHEN a finding is present in the previous sync but absent from the current sync, THE Archive_Detector SHALL create an Archive_Record with state ARCHIVED, recording the finding metadata, last known severity score, and a timestamp.
|
||||
3. WHEN a finding already has an Archive_Record with state ARCHIVED and the finding reappears in the current sync results, THE Archive_Detector SHALL update the Archive_Record state to RETURNED and record the new severity score.
|
||||
4. WHEN a finding has an Archive_Record with state RETURNED and the finding disappears again from sync results, THE Archive_Detector SHALL update the Archive_Record state to ARCHIVED and record the severity score at time of disappearance.
|
||||
5. IF the Sync_Pipeline encounters a sync error, THEN THE Archive_Detector SHALL skip archive detection for that sync cycle to avoid false positives from incomplete data.
|
||||
|
||||
### Requirement 2: Lifecycle State Transitions
|
||||
|
||||
**User Story:** As a security analyst, I want every state change to be recorded with context, so that I can audit the full history of a finding's lifecycle.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN an Archive_Record changes state, THE Sync_Pipeline SHALL insert a Transition_History row containing the previous state, new state, timestamp, severity score at time of transition, and a reason string.
|
||||
2. THE Archive_Record SHALL store the finding_id, finding_title, host_name, ip_address, current state, last known severity score, initial archive timestamp, and last transition timestamp.
|
||||
3. WHEN a finding is confirmed as remediated (closed) in Ivanti, THE Sync_Pipeline SHALL update the Archive_Record state to CLOSED and record a Transition_History entry with reason "remediated_in_ivanti".
|
||||
4. THE Transition_History SHALL store the archive_record_id, from_state, to_state, transition timestamp, severity_at_transition, and reason.
|
||||
|
||||
### Requirement 3: Database Schema
|
||||
|
||||
**User Story:** As a developer, I want the archive data stored in two normalized SQLite tables, so that the data model supports efficient queries and maintains referential integrity.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Sync_Pipeline SHALL create an `ivanti_finding_archives` table with columns for id, finding_id (unique), finding_title, host_name, ip_address, current_state, last_severity, first_archived_at, last_transition_at, and created_at.
|
||||
2. THE Sync_Pipeline SHALL create an `ivanti_archive_transitions` table with columns for id, archive_id (foreign key to ivanti_finding_archives), from_state, to_state, severity_at_transition, reason, and transitioned_at.
|
||||
3. THE Sync_Pipeline SHALL create indexes on ivanti_finding_archives(finding_id) and ivanti_finding_archives(current_state) for query performance.
|
||||
4. THE Sync_Pipeline SHALL create an index on ivanti_archive_transitions(archive_id) for efficient history lookups.
|
||||
|
||||
### Requirement 4: Archive API Endpoints
|
||||
|
||||
**User Story:** As a frontend developer, I want REST API endpoints to query archived findings, transition history, and summary statistics, so that I can build the archive tracking UI.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. WHEN a GET request is made to `/api/ivanti/archive`, THE Archive_API SHALL return a list of all Archive_Records with optional filtering by current_state query parameter.
|
||||
2. WHEN a GET request is made to `/api/ivanti/archive/:findingId/history`, THE Archive_API SHALL return the Transition_History entries for the specified finding ordered by transitioned_at descending.
|
||||
3. WHEN a GET request is made to `/api/ivanti/archive/stats`, THE Archive_API SHALL return an object containing the count of Archive_Records in each Lifecycle_State (ACTIVE, ARCHIVED, RETURNED, CLOSED).
|
||||
4. WHEN an unauthenticated request is made to any Archive_API endpoint, THE Archive_API SHALL return a 401 status code.
|
||||
5. WHEN a GET request is made to `/api/ivanti/archive/:findingId/history` with a finding_id that has no Archive_Record, THE Archive_API SHALL return an empty transitions array with a 200 status code.
|
||||
|
||||
### Requirement 5: Archive Summary Bar UI
|
||||
|
||||
**User Story:** As a security analyst, I want a visual summary bar on the Ivanti dashboard showing counts for each archive state, so that I can quickly assess the archive landscape and navigate to details.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE Archive_Summary_Bar SHALL display four stat cards showing the count of findings in each Lifecycle_State: ACTIVE, ARCHIVED, RETURNED, and CLOSED.
|
||||
2. WHEN the Archive_Summary_Bar loads, THE Archive_Summary_Bar SHALL fetch data from the `/api/ivanti/archive/stats` endpoint.
|
||||
3. WHEN a user clicks a state card in the Archive_Summary_Bar, THE Archive_Summary_Bar SHALL filter the displayed archive list to show only findings in that state.
|
||||
4. THE Archive_Summary_Bar SHALL use the existing design system colors: sky blue (#0EA5E9) for ACTIVE, amber (#F59E0B) for ARCHIVED, emerald (#10B981) for RETURNED, and red (#EF4444) for CLOSED.
|
||||
5. THE Archive_Summary_Bar SHALL use Lucide icons and monospace typography consistent with the existing dashboard design system.
|
||||
|
||||
### Requirement 6: Migration Script
|
||||
|
||||
**User Story:** As a developer, I want a standalone migration script to create the archive tables, so that the schema can be applied to existing deployments following the established migration pattern.
|
||||
|
||||
#### Acceptance Criteria
|
||||
|
||||
1. THE migration script SHALL be located at `backend/migrations/add_finding_archive_tables.js` and follow the existing migration pattern of opening the database, running DDL statements in `db.serialize()`, and closing the connection.
|
||||
2. THE migration script SHALL use `CREATE TABLE IF NOT EXISTS` and `CREATE INDEX IF NOT EXISTS` to be idempotent.
|
||||
3. WHEN the migration script is executed, THE migration script SHALL log progress messages for each table and index created.
|
||||
Reference in New Issue
Block a user