Purpose: Executable plan to complete the seven-domain enterprise security map (five Zero Trust protection pillars + two operational engines) and close NIST CSF 2.0 Gate A/B remediation gaps.
Version: 1.1
Date: 18 June 2026
Owner: ICT Governance / Security Engineering
Status: Active — not a certification or completion claim
Related documents:
The framework’s June 2026 sprint delivered strong Identity and substantial Devices coverage (JIT/Break Glass, asset register). Three domains remain weak or unproven for audit:
| Gap | Domain | NIST CSF 2.0 | Gate |
|---|---|---|---|
| Missing 5th ZT pillar | Data (classification / DLP) | PR.DS | P3 / Focus Area 8 |
| Open-loop detection | SecOps (detect → ticket → resolve) | DE., RS. | G-A4, G-B2, G-B4 |
| Unmeasured recovery | Resilience (Git-to-cloud DR) | RC.RP | G-B3 |
| Incomplete supply chain | Software (CASB / SBOM) | GV.SC | G-A3 |
Engineering priority: Complete the active defense loop (SecOps) first — highest gate leverage and builds on existing POST /api/governance/incidents. Then Software supply chain persistence, then validated resilience, then Data/DLP (backlog).
Phase 3 readiness controls (Sprint A — implemented June 2026):
| Control | Status | Evidence |
|---|---|---|
| Event-driven FAIR on incident ingest | Done | services/governance-incident-ingest.js → computeFairExposure({ triggerSource: 'incident' }) |
Cross-domain correlation_id |
Done | governance_incidents, ingest log, FAIR telemetry + calculation log |
| Incident ingest audit log | Done | governance_incident_ingest_log (raw_payload + processed_fields) |
| Full SLA definition (Ack + MTTR) | Done | services/governance-sla.js; env-tunable via SLA_CRITICAL_* |
| FAIR audit telemetry | Done | fair_risk_telemetry_log, KPI-GOV-RISK-DELTA-24H |
| CISO dashboard live ALE | Done | CISOExecutiveDashboard.js → /api/governance/risk/exposure |
Verification: npm run verify:secops (incident → ingest log → FAIR calc log) and npm run verify:fair-risk (19 tests). Phase 3 evidence: Phase 3 Audit Evidence Pack + npm run export:audit-evidence.
Sprint cadence: Four two-week sprints (A–D), ~8 weeks total for core path. Sprint E (Data pillar) is backlog.
| # | Pillar | System boundary | NIST primary | Current status | Target |
|---|---|---|---|---|---|
| 1 | Identity | JIT elevation, Break Glass, RBAC | PR.AA, GV.RR | Delivered (June 2026) | Phase 3 validation |
| 2 | Devices | Multi-cloud asset register, DR posture | ID.AM | Substantial (G-B1) | Multi-cloud sync depth |
| 3 | Software | CASB catalog, SBOM, vulnerability gating | GV.SC | Weak (in-memory catalog) | PostgreSQL + console |
| 4 | Network | Segmentation, port exposure scanning | PR.PS | Docs / IaC only | Topology monitor (backlog) |
| 5 | Data | Purview / Macie classification, DLP | PR.DS | IaC encryption only | App-layer DLP ingest (backlog) |
| # | Engine | System boundary | NIST primary | Current status | Target |
|---|---|---|---|---|---|
| 6 | SecOps | Sentinel correlation, auto-ticketing, IR workflow | DE.CM, DE.AE, RS.MA, RS.AN | Partial (ingest API; PowerShell stub) | Closed loop < 5 min |
| 7 | Resilience | Git-to-cloud recovery orchestrator | RC.RP, RC.IM | Partial (script + DR fields) | Measured RTO/RPO in pipeline |
Identity and devices are governed with ephemeral JIT authority and a live asset register. SecOps proves detect-to-ticket in under five minutes. Software supply chain and shadow IT are inventoried from live CASB feeds. Recovery is a measured engineering function with documented RTO/RPO — not a PDF-only plan.
flowchart LR
subgraph delivered [Delivered June 2026]
ID[Identity JIT / Break Glass]
DEV[Devices Asset Register]
end
subgraph sprintA [Sprint A SecOps Loop]
PS[PowerShell ticket wiring]
LC[Incident lifecycle API]
DASH[Live dashboard feeds]
end
subgraph sprintB [Sprint B Correlation]
SENT[Sentinel correlation]
IR[IR workflow API]
TST[verify:secops]
end
subgraph sprintC [Sprint C Software]
CASB[CASB PostgreSQL]
SCC[Supply chain console]
end
subgraph sprintD [Sprint D Resilience]
DR[Test-GitToCloudRecovery CI]
RTO[RTO/RPO attestation]
end
delivered --> sprintA
sprintA --> sprintB
sprintB --> sprintC
sprintB --> sprintD
sprintC --> GateB[Gate B sign-off path]
sprintD --> GateB
sprintA --> GateA[G-A4 partial close]
sprintB --> GateA2[G-B2 G-B4]
| Sprint | Closes (minimum) | Owner sign-off |
|---|---|---|
| A | G-A4 (stub removed), G-A2 (substantial) | Engineering lead |
| B | G-B2, G-B4 | CISO + Engineering |
| C | G-A3 (substantial) | Compliance + Engineering |
| D | G-B3 | BC lead + Service Delivery |
Focus Area: 2 (Live detect & respond)
Gates: G-A4, G-A2 (substantial — live executive metrics; Strategic Initiatives demo-only)
NIST: DE.CM, RS.MA
Prerequisite: npm run setup:governance, API running on :4000
Create-IncidentTicket stub in PowerShell with live API calls.| Component | Path | Action |
|---|---|---|
| Incident stub | azure-automation/Continuous-Compliance-Monitoring.ps1 L599–617 |
Call POST /api/governance/incidents with GOVERNANCE_WEBHOOK_SECRET |
| Ingest API | ict-governance-framework/api/governance-router.js |
Add PATCH /incidents/:id for status transitions |
| Schema | ict-governance-framework/sql/governance.sql |
Optional: add acknowledged_at, remediated_at, sla_breached columns |
| Dashboard | app/compliance-dashboard/page.js, ExecutiveDashboard.js |
Wire incident count / MTTR from GET /api/governance/incidents |
| Env | .env.example |
Document GOVERNANCE_API_URL, GOVERNANCE_WEBHOOK_SECRET for automation |
| Status | Meaning | SLA clock |
|---|---|---|
Detected |
Auto-created from monitoring or webhook | Starts |
Acknowledged |
Correlated to asset / assigned owner | < 5 min for CRITICAL |
Remediating |
Playbook or human action in progress | — |
Resolved |
Control restored; resolved_at set |
Stop |
services/governance-sla.js)| Severity | Detect → Ticket | Ticket → Ack | MTTR |
|---|---|---|---|
| CRITICAL | < 5 min | < 5 min | < 60 min |
| HIGH | < 15 min | < 15 min | < 4 h |
| MEDIUM | < 1 h | < 1 h | < 24 h |
| LOW | < 24 h | < 24 h | < 72 h |
GET /api/governance/incidents returns computed time_to_acknowledge_ms, time_to_resolve_ms, and sla_*_breached flags per row.
Every automated outcome persists input → transformation → output:
| System | Table | Fields |
|---|---|---|
| SecOps ingest | governance_incident_ingest_log |
raw_payload, processed_fields, correlation_id |
| FAIR engine | fair_risk_telemetry_log |
driver, raw_value, multiplier_applied, correlation_id |
| FAIR sweep | fair_risk_calculation_log |
ale_before_usd, ale_after_usd, trigger_source, incident_id |
| DR (Sprint D) | TBD | source_event, result_state, correlation_id |
| CASB (Sprint C) | TBD | catalog change history |
Shared correlation_id (UUID) propagates: incident → FAIR recalc → telemetry drivers. Pass via x-correlation-id header or body correlationId on ingest.
GOVERNANCE_WEBHOOK_SECRET in dev and test tenantexternal_ticket_id fieldgovernance-sla.js)POST /incidents (governance-incident-ingest.js)correlation_id on incidents + governance_incident_ingest_logfair_risk_calculation_log — ale_before / ale_after per sweepGET /incidents (time_to_acknowledge_ms, sla_mttr_breached)PATCH /api/governance/incidents/:incidentId — body: { status, resolutionNotes? }Detected → Acknowledged → Remediating → Resolvedresolved_at / acknowledged_at automatically on transitionincident_workflow_events append-only log + FAIR on Resolved onlytimeToAcknowledgeMs / timeToResolveMs in GET /api/governance/incidents for dashboard widgetsscripts/setup-incident-lifecycle.js)Invoke-GovernanceIncidentApi helper in Continuous-Compliance-Monitoring.ps1Create-IncidentTicket stub with REST POST to /api/governance/incidentsCRITICAL|HIGH|MEDIUM|LOW and drift taxonomy categoryassetId when violation references Azure resource ID (correlate via asset register)GET /api/governance/executive/metrics (G-A2)GET /api/governance/executive/metrics (G-A2)ict-governance-framework/tests/secops-incident-loop.test.jstests/secops-incident-loop.test.js — correlation_id, ingest log, FAIR calc lognpm run verify:secops — synthetic violation → POST → PATCH Resolved under 5 min (simulated clock)npm run verify:secops — incident ingest → FAIR event trigger (12 assertions)npm run verify:secops in CI or document local gate commandContinuous-Compliance-Monitoring.ps1 against test tenant; confirm row in governance_incidents# Add incident creation logic here stub text in Create-IncidentTicketnpm run verify:secops passesFocus Area: 2 (continued)
Gates: G-B2, G-B4
NIST: DE.AE, RS.AN, RS.MI
Prerequisite: Sprint A complete
verify:secops expansion.| Component | Action |
|---|---|
governance-router.js |
Enhance extractIncidentFields for additional Sentinel entity shapes |
New api/incident-workflow-router.js |
POST /assign, POST /escalate, GET /:id/timeline |
privileged_action_logs |
Optional FK or query bridge from incident → JIT ticket |
app/secops-console/ (new) |
Incident queue UI under Security nav (optional but recommended) |
Automated-Remediation-Framework.ps1 |
Top 3 resource types — remove stub remediation paths |
docs/implementation/guides/ (redacted)asset_register.asset_idAcknowledged when asset correlation succeedsGET /api/governance/incidents?severity=CRITICAL&status=Detected for SOC queuex-governance-webhook-secret on all ingest pathsincident_workflow_events table (append-only): assign, escalate, comment, remediaterisk_updated events in incident_workflow_events + GET /incidents/:id/timelinefair_scenario_id linkage (mitre-enrichment.js, mitre_enrichment.sql)incident_detected events include mitre block; root timeline response exposes mitre + fair_scenario_idmitre_to_fair_mapping table — tunable technique/tactic → scenario + severity_weight; FAIR sweep applies MITRE multiplier; GET /mitre/mappingsPOST /api/governance/incidents/:id/assign — { assigneeId, justification }POST /api/governance/incidents/:id/escalate — RPAS-ESC metadataGET /api/governance/incidents/:id/timeline — incidents + workflow events + linked JIT actionsscripts/send-test-sentinel-payload.js)Automated-Remediation-Framework.ps1/secops-console page — open incidents, SLA badge, link to asset register rowverify:secops — Sentinel-shaped payload → correlated asset → timelinenpm run verify:secops:correlation (or flags on base command)asset_id existsverify:secops correlation scenario passesFocus Area: 5 (Supply chain & application governance)
Gates: G-A3 (substantial)
NIST: GV.SC, Software ZT pillar
Prerequisite: Sprint A complete (incidents link to shadow IT discoveries)
asset_origin = CASB_Discovery).| Component | Action |
|---|---|
sql/casb_catalog.sql (new) |
casb_applications, casb_app_risk_snapshots |
api/casb-app-catalog.js |
Refactor to PostgreSQL pool |
services/compliance-validation-service.js |
Replace mock with live catalog queries |
app/supply-chain/ or asset register filter |
Software pillar UI |
| CASB polling worker | Write through to persisted catalog |
casb_applications.id ↔ asset_register.casb_source_idcasb_catalog.sql migrationcasb-app-catalog.js — CRUD against PostgreSQLGET /api/casb/supply-chain/summary — counts by risk tier for dashboardCASB_Discovery + unverified posture/supply-chain console with vendor risk tablenpm run verify:casb-catalog — ingest → persist → query → asset linknpm run verify:casb-ingest against persisted catalogin-memory / sample-only catalog path in production code pathverify:casb-catalog passesFocus Area: 6 (Validated business continuity)
Gates: G-B3
NIST: RC.RP, RC.IM
Prerequisite: Asset register DR fields (delivered); Sprint A recommended for incident logging during DR test
Test-GitToCloudRecovery.ps1 as a repeatable pipeline step.| Component | Path |
|---|---|
| DR orchestrator | governance/rpas/scripts/Test-GitToCloudRecovery.ps1 |
| CI workflow | .github/workflows/dr-recovery-validation.yml (new, quarterly + manual) |
| Asset DR fields | asset_register.last_dr_drill_timestamp, rto_seconds, rpo_flag_triggered |
| Attestation | generated-documents/ or governance/rpas/status/dr-attestation-*.json |
Test-GitToCloudRecovery.ps1 -CsrId CSR-42 -TenantId tenant-01 — capture full logDR_Hydrated or Failed_Validation)KPI-GOV-AUTOMATION-TARGET or DR-specific metric)dr-recovery-validation.ymlnpm run verify:dr-recovery wrapper invoking PowerShell script in smoke modenpm run verify:dr-recovery documented in root READMEFocus Area: 8 (Security awareness & data protection depth)
NIST: PR.DS
Gate: None for Phase 3 — schedule after Sprints A–D
data_classification table linked to tenant and assetPOST /api/governance/incidents (reuse SecOps loop)verify:data-protection harnessStart Sprint E only after: Sprint A SecOps loop proven (DLP events need a ticket target).
| Item | Notes |
|---|---|
| Network topology monitor | Requires authoritative asset + software inventory first |
| Micro-segmentation posture API | Integrate after Sprint C |
| Continuous port scanning | Azure Policy / Defender export → asset register enrichment |
Use this table for steering committee / bi-weekly reviews.
| ID | Milestone | Sprint | Target date | Status |
|---|---|---|---|---|
| M1 | SecOps stub removed; verify:secops green |
A | Week 2 | ☐ |
| M2 | Live incident data on compliance/executive dashboard | A | Week 2 | ☐ |
| M3 | Sentinel correlation + IR timeline API | B | Week 4 | ☐ |
| M4 | SecOps console shipped | B | Week 4 | ☐ |
| M5 | CASB catalog PostgreSQL + supply chain view | C | Week 6 | ☐ |
| M6 | DR test attestation with RTO/RPO | D | Week 8 | ☐ |
| M7 | Gate A items G-A2–G-A4 substantially closed | A–C | Week 6 | ☐ |
| M8 | Gate B items G-B2–G-B4 substantially closed | B | Week 4 | ☐ |
| M9 | Gate B item G-B3 substantially closed | D | Week 8 | ☐ |
| M10 | Compliance Officer Gate A readiness review | Post-A–C | Week 7 | ☐ |
| M11 | Service Delivery Gate B readiness review | Post-D | Week 9 | ☐ |
Run from ict-governance-framework/ after database setup:
# Existing (June 2026 baseline)
npm run verify:jit
npm run verify:break-glass
npm run verify:assets
npm run setup:governance
# Sprint A+
npm run verify:secops # planned — incident loop < 5 min
# Sprint B+
npm run verify:secops:correlation # planned — Sentinel + asset bind
# Sprint C+
npm run verify:casb-catalog # planned — persisted catalog
# Sprint D+
npm run verify:dr-recovery # planned — smoke DR orchestrator
| Activity | Engineering | SecOps / Azure auto | Compliance | CISO | Service Delivery |
|---|---|---|---|---|---|
| API & schema | R | C | I | I | I |
| PowerShell automation | C | R | I | C | I |
| Dashboard / console UI | R | I | C | C | I |
| Sprint verification scripts | R | C | I | I | I |
| Gate evidence pack | C | C | R | A | A (Gate B) |
| NIST doc updates | C | I | R | A | I |
R = Responsible, A = Accountable, C = Consulted, I = Informed
| Risk | Mitigation |
|---|---|
| ServiceNow integration delays Sprint A | v1 uses internal PostgreSQL ledger; external_ticket_id reserved |
| Sentinel webhook shape drift | extractIncidentFields + fixture tests in verify:secops |
| Executive dashboard still mock after Sprint A | Explicit Demo Mode labels until Sprint B CISO widgets live |
| DR test impacts shared dev tenant | Isolated subscription; smoke mode for CI |
| Scope creep into Network/DLP | Sprint E and Network backlog frozen until M6 complete |
| Static FAIR parameters drift from reality | Phase 4 calibration loop (fair_model_calibration_log, npm run verify:calibration) |
Focus: Adaptive risk model (GV.RM)
Prerequisite: G-A2 closed, MITRE → FAIR mapping live
severity_weight from observed technique frequency.| Component | Path |
|---|---|
| Schema | sql/fair_model_calibration.sql — tef_calibration_factor, fair_model_calibration_log |
| Service | services/fair-risk-calibration.js |
| API | GET /api/governance/risk/calibration, GET .../calibration/log, POST .../calibrate |
| FAIR engine | computeScenarioAle applies tef_calibration_factor |
| Verification | npm run verify:calibration (11 assertions) |
npm run verify:calibration passescalibration block + SEC-A8 checksazure-automation/Continuous-Compliance-Monitoring.ps1 — incident stub L599–617ict-governance-framework/api/governance-router.js — incident ingestict-governance-framework/sql/governance.sql — governance_incidents schemagovernance/rpas/scripts/Test-GitToCloudRecovery.ps1 — G-B3 orchestrator| Certification | This plan does not constitute NIST CSF 2.0 certification |
| Next action | Begin Sprint A — assign owner and target start date |
| Tracking | Update gate tables in Improvement Focus Areas at each sprint close |