Files
cve-dashboard/.kiro/specs/atlas-action-plans/requirements.md
root 4c04c9870a Add Atlas InfoSec action plans integration
Integrate Atlas InfoSec API to manage compliance action plans directly from
the ReportingPage. Users can view, create, and update action plans for host
findings without switching to the Atlas web tool.

Backend:
- Add atlasApi.js helper with Basic Auth, TLS skip, GET/PUT/PATCH/POST
- Add atlas_action_plans_cache migration for SQLite cache table
- Add atlas.js router with sync, status, and proxy CRUD endpoints
- Mount Atlas router at /api/atlas in server.js
- Extract hostId from Ivanti host findings during sync

Frontend:
- Add AtlasBadge component (amber=needs plan, green=has plan)
- Add AtlasSlideOutPanel with plan list, create form, edit capability
- Separate active plans from inactive history in collapsible section
- Custom dark-themed plan type dropdown
- Optimistic local state shows pending plans immediately after creation
- Atlas sync button on ReportingPage toolbar
- Prepopulate finding ID in create form from clicked row

Environment:
- Add ATLAS_API_URL, ATLAS_API_USER, ATLAS_API_PASS, ATLAS_SKIP_TLS to .env.example
2026-04-23 21:52:53 +00:00

15 KiB

Requirements Document

Introduction

Integrate the Atlas InfoSec action plans API into the STEAM Security Dashboard so that users can view and manage compliance action plans for host findings directly from the ReportingPage. This eliminates the need to context-switch to the separate Atlas InfoSec web tool. The integration uses STEAM's Ivanti findings as the source of truth and checks which hosts also exist in Atlas, displaying action plan status badges and providing a slide-out panel for plan creation and management.

Glossary

  • Dashboard: The STEAM Security Dashboard frontend React application
  • Backend: The STEAM Security Dashboard Express.js API server
  • Atlas_API: The Atlas InfoSec REST API at https://atlas-infosec.caas.charterlab.com, documented in docs/atlasinfosec-api-spec.json
  • Atlas_Helper: The backend helper module (backend/helpers/atlasApi.js) responsible for HTTP communication with the Atlas_API
  • Atlas_Cache: A SQLite table storing host-level action plan status per hostId, refreshed on-demand via manual sync
  • Atlas_Router: The backend Express route module (backend/routes/atlas.js) exposing Atlas-related endpoints under /api/atlas
  • ReportingPage: The existing frontend page (frontend/src/components/pages/ReportingPage.js) displaying Ivanti host findings
  • Action_Plan: A compliance plan created in Atlas InfoSec for a host finding, with a type (decommission, remediation, false_positive, risk_acceptance, scan_exclusion), a commit date, and optional reference fields
  • Host_ID: The shared numeric identifier linking an Ivanti host finding (host.hostId) to an Atlas host (host_id URL parameter)
  • Finding_ID: The Ivanti finding-level identifier (f.id) that maps to Atlas's active_host_findings_id
  • Slide_Out_Panel: A right-side drawer component on the ReportingPage for viewing and managing action plans for a specific host
  • Atlas_Badge: A visual indicator on the ReportingPage Host column showing whether a host exists in Atlas and its action plan coverage status
  • Ivanti_Cache: The existing ivanti_findings_cache SQLite table holding synced Ivanti host findings

Requirements

Requirement 1: Atlas API Helper Module

User Story: As a backend developer, I want a centralized helper module for Atlas InfoSec API communication, so that all Atlas HTTP calls use consistent authentication, TLS handling, and error management.

Acceptance Criteria

  1. THE Atlas_Helper SHALL send all requests to the Atlas_API base URL configured via the ATLAS_API_URL environment variable
  2. THE Atlas_Helper SHALL include a Basic Auth Authorization header computed by base64-encoding the ATLAS_API_USER and ATLAS_API_PASS environment variable values at runtime
  3. WHEN the ATLAS_SKIP_TLS environment variable is set to true, THE Atlas_Helper SHALL disable TLS certificate verification for Atlas_API requests
  4. WHEN the ATLAS_SKIP_TLS environment variable is not set or set to false, THE Atlas_Helper SHALL enforce TLS certificate verification for Atlas_API requests
  5. THE Atlas_Helper SHALL support GET, PUT, PATCH, and POST HTTP methods for communicating with the Atlas_API
  6. THE Atlas_Helper SHALL set a request timeout of 15 seconds for single-host endpoints and 60 seconds for bulk endpoints
  7. WHEN the Atlas_API returns a non-2xx status code, THE Atlas_Helper SHALL resolve the promise with the status code and response body without throwing an exception
  8. WHEN a network error or timeout occurs, THE Atlas_Helper SHALL reject the promise with a descriptive error message including the HTTP method and URL path

Requirement 2: Atlas Cache Table and Migration

User Story: As a system administrator, I want Atlas action plan status cached locally in SQLite, so that the ReportingPage can render badges without calling the Atlas_API on every page load.

Acceptance Criteria

  1. THE Backend SHALL provide a migration script (backend/migrations/add_atlas_action_plans_cache.js) that creates the Atlas_Cache table
  2. THE Atlas_Cache table SHALL store one row per Host_ID with columns for: host_id (integer, unique), has_action_plan (integer, 0 or 1), plan_count (integer), plans_json (text, JSON array of plan summaries), and synced_at (datetime)
  3. THE migration script SHALL create an index on the host_id column of the Atlas_Cache table
  4. THE migration script SHALL follow the existing migration pattern: open the database at backend/cve_database.db, use db.serialize(), log progress to the console, and close the database on completion
  5. WHEN the migration script is run multiple times, THE migration script SHALL complete without errors by using CREATE TABLE IF NOT EXISTS and CREATE INDEX IF NOT EXISTS

Requirement 3: Atlas Sync Route

User Story: As a dashboard user, I want to trigger a manual sync of Atlas action plan data, so that the badge indicators on the ReportingPage reflect the current state of action plans in Atlas.

Acceptance Criteria

  1. THE Atlas_Router SHALL expose a POST /api/atlas/sync endpoint that requires authentication and membership in the Admin or Standard_User group
  2. WHEN the sync endpoint is called, THE Atlas_Router SHALL extract unique Host_ID values from the Ivanti_Cache findings
  3. WHEN unique Host_ID values are extracted, THE Atlas_Router SHALL call the Atlas_API GET /hosts/{host_id}/action-plans endpoint for each Host_ID to retrieve action plan data
  4. WHEN action plan data is retrieved for a Host_ID, THE Atlas_Router SHALL upsert the Atlas_Cache row for that Host_ID with the plan count, plan summary JSON, and current timestamp
  5. WHEN the Atlas_API returns a non-2xx response for a specific Host_ID, THE Atlas_Router SHALL skip that host and continue processing remaining hosts
  6. WHEN the sync completes, THE Atlas_Router SHALL return a JSON response containing the count of hosts synced, the count of hosts with action plans, and the count of hosts that failed
  7. THE Atlas_Router SHALL log an audit entry for each sync operation with the initiating user and result summary

Requirement 4: Atlas Status Route

User Story: As a frontend developer, I want a single endpoint that returns cached Atlas status for all hosts, so that the ReportingPage can render badges without individual API calls per row.

Acceptance Criteria

  1. THE Atlas_Router SHALL expose a GET /api/atlas/status endpoint that requires authentication
  2. WHEN the status endpoint is called, THE Atlas_Router SHALL return all rows from the Atlas_Cache table as a JSON array
  3. THE status response SHALL include for each host: host_id, has_action_plan, plan_count, and synced_at

Requirement 5: Atlas Action Plan Proxy Routes

User Story: As a dashboard user, I want to create, view, and update Atlas action plans from the STEAM Dashboard, so that I do not need to switch to the Atlas InfoSec web tool.

Acceptance Criteria

  1. THE Atlas_Router SHALL expose a GET /api/atlas/hosts/:hostId/action-plans endpoint that requires authentication and proxies to the Atlas_API GET /hosts/{host_id}/action-plans endpoint
  2. THE Atlas_Router SHALL expose a PUT /api/atlas/hosts/:hostId/action-plans endpoint that requires authentication and membership in the Admin or Standard_User group
  3. WHEN the PUT endpoint receives a request body, THE Atlas_Router SHALL validate that plan_type is one of: decommission, remediation, false_positive, risk_acceptance, scan_exclusion
  4. WHEN the PUT endpoint receives a request body, THE Atlas_Router SHALL validate that commit_date is present and is a valid date string in YYYY-MM-DD format
  5. WHEN validation passes, THE Atlas_Router SHALL proxy the request body to the Atlas_API PUT /hosts/{host_id}/action-plans endpoint and return the Atlas_API response
  6. THE Atlas_Router SHALL expose a PATCH /api/atlas/hosts/:hostId/action-plans endpoint that requires authentication and membership in the Admin or Standard_User group
  7. WHEN the PATCH endpoint receives a request body, THE Atlas_Router SHALL validate that action_plan_id (string) and updates (object) are present
  8. WHEN validation passes, THE Atlas_Router SHALL proxy the request body to the Atlas_API PATCH /hosts/{host_id}/action-plans endpoint and return the Atlas_API response
  9. THE Atlas_Router SHALL expose a POST /api/atlas/hosts/bulk-action-plans endpoint that requires authentication and membership in the Admin or Standard_User group
  10. WHEN the bulk endpoint receives a request body, THE Atlas_Router SHALL validate that host_ids is a non-empty array of integers, plan_type is valid, and commit_date is a valid YYYY-MM-DD date string
  11. WHEN validation passes, THE Atlas_Router SHALL proxy the request body to the Atlas_API POST /hosts/create-bulk-action-plans endpoint and return the Atlas_API response
  12. WHEN any proxy endpoint receives a non-2xx response from the Atlas_API, THE Atlas_Router SHALL return the Atlas_API status code and error body to the frontend
  13. THE Atlas_Router SHALL log an audit entry for each create (PUT) and update (PATCH) action plan operation with the user, Host_ID, and plan type

Requirement 6: Atlas Badge on ReportingPage

User Story: As a dashboard user, I want to see at a glance which hosts in the findings table have Atlas action plans, so that I can prioritize hosts that still need compliance attention.

Acceptance Criteria

  1. WHEN the ReportingPage loads, THE Dashboard SHALL fetch cached Atlas status from GET /api/atlas/status and store the result in component state
  2. WHEN a finding row's Host_ID matches an entry in the Atlas status data, THE Dashboard SHALL display an Atlas_Badge in the Host column next to the hostname
  3. WHEN a host exists in Atlas but has zero action plans, THE Atlas_Badge SHALL display with a warning style indicating the host needs attention
  4. WHEN a host exists in Atlas and has one or more active action plans, THE Atlas_Badge SHALL display with a success style indicating the host is covered
  5. WHEN a finding row's Host_ID does not match any entry in the Atlas status data, THE Dashboard SHALL display no Atlas_Badge for that row
  6. THE Atlas_Badge SHALL display the action plan count as text within the badge when the host has one or more plans

Requirement 7: Atlas Slide-Out Panel

User Story: As a dashboard user, I want to click an Atlas badge to see full action plan details and create or update plans, so that I can manage compliance without leaving the ReportingPage.

Acceptance Criteria

  1. WHEN a user clicks an Atlas_Badge, THE Dashboard SHALL open the Slide_Out_Panel on the right side of the ReportingPage
  2. WHEN the Slide_Out_Panel opens, THE Dashboard SHALL fetch full action plan details from GET /api/atlas/hosts/:hostId/action-plans and display them in the panel
  3. THE Slide_Out_Panel SHALL display each existing action plan with: plan type, commit date, status, and any associated VNR or EXC reference numbers
  4. WHEN the user is in the Admin or Standard_User group, THE Slide_Out_Panel SHALL display a form to create a new action plan with fields for: plan type (dropdown selector), commit date (date picker), qualys_id (optional text input), active_host_findings_id (optional numeric input), jira_vnr (optional text input), and archer_exc (optional text input)
  5. WHEN the user submits the create form with valid data, THE Dashboard SHALL send a PUT request to /api/atlas/hosts/:hostId/action-plans and refresh the plan list on success
  6. WHEN the user is in the Admin or Standard_User group, THE Slide_Out_Panel SHALL provide an edit capability for existing action plans
  7. WHEN the user submits an update with valid data, THE Dashboard SHALL send a PATCH request to /api/atlas/hosts/:hostId/action-plans and refresh the plan list on success
  8. WHEN the Atlas_API returns an error for a create or update operation, THE Slide_Out_Panel SHALL display the error message to the user
  9. WHEN the user clicks outside the Slide_Out_Panel or clicks a close button, THE Dashboard SHALL close the panel
  10. WHEN the user is in the Viewer group, THE Slide_Out_Panel SHALL display existing plans in read-only mode without the create or edit forms

Requirement 8: Atlas Sync Button on ReportingPage

User Story: As a dashboard user, I want a manual sync button for Atlas data on the ReportingPage, so that I can refresh action plan status on demand.

Acceptance Criteria

  1. THE Dashboard SHALL display an Atlas sync button on the ReportingPage near the existing Ivanti sync button
  2. WHEN the user is in the Admin or Standard_User group, THE Atlas sync button SHALL be enabled
  3. WHEN the user is in the Viewer group, THE Atlas sync button SHALL be disabled with a tooltip indicating insufficient permissions
  4. WHEN the user clicks the Atlas sync button, THE Dashboard SHALL send a POST request to /api/atlas/sync
  5. WHILE the Atlas sync is in progress, THE Atlas sync button SHALL display a loading indicator and be disabled to prevent duplicate requests
  6. WHEN the Atlas sync completes successfully, THE Dashboard SHALL refresh the Atlas status data and update all Atlas_Badge indicators on the page
  7. WHEN the Atlas sync fails, THE Dashboard SHALL display an error notification with the failure reason

Requirement 9: Environment Configuration

User Story: As a system administrator, I want Atlas API credentials and configuration documented alongside existing environment variables, so that deployment setup is straightforward.

Acceptance Criteria

  1. THE Backend SHALL read the Atlas_API base URL from the ATLAS_API_URL environment variable
  2. THE Backend SHALL read the Atlas service account username from the ATLAS_API_USER environment variable
  3. THE Backend SHALL read the Atlas service account password from the ATLAS_API_PASS environment variable
  4. THE Backend SHALL read the TLS verification skip flag from the ATLAS_SKIP_TLS environment variable
  5. THE Backend SHALL document all four Atlas environment variables in backend/.env.example with descriptive comments

Requirement 10: Access Control

User Story: As a security administrator, I want Atlas operations restricted by user group, so that only authorized users can modify action plans or trigger syncs.

Acceptance Criteria

  1. THE Atlas_Router SHALL allow all authenticated users to access the GET /api/atlas/status endpoint
  2. THE Atlas_Router SHALL allow all authenticated users to access the GET /api/atlas/hosts/:hostId/action-plans endpoint
  3. THE Atlas_Router SHALL restrict the POST /api/atlas/sync endpoint to users in the Admin or Standard_User group
  4. THE Atlas_Router SHALL restrict the PUT /api/atlas/hosts/:hostId/action-plans endpoint to users in the Admin or Standard_User group
  5. THE Atlas_Router SHALL restrict the PATCH /api/atlas/hosts/:hostId/action-plans endpoint to users in the Admin or Standard_User group
  6. THE Atlas_Router SHALL restrict the POST /api/atlas/hosts/bulk-action-plans endpoint to users in the Admin or Standard_User group
  7. WHEN an unauthorized user attempts a restricted operation, THE Atlas_Router SHALL return HTTP 403 with an error message indicating insufficient permissions