icdev 0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- args/agent_config.yaml +113 -0
- args/audit_regimes/cisa_sbd.json +381 -0
- args/audit_regimes/cmmc_l2.json +906 -0
- args/audit_regimes/dod_cssp.json +393 -0
- args/audit_regimes/dodi_5000_87.json +297 -0
- args/audit_regimes/fedramp_moderate.json +650 -0
- args/audit_regimes/ieee_1012.json +373 -0
- args/audit_regimes/nist_800_171.json +624 -0
- args/audit_regimes/nist_800_53.json +907 -0
- args/cloudforge_blueprints/aws_commercial.yaml +29 -0
- args/cloudforge_blueprints/aws_govcloud_il4.yaml +34 -0
- args/cloudforge_blueprints/aws_govcloud_il5.yaml +38 -0
- args/cloudforge_blueprints/azure_commercial.yaml +28 -0
- args/cloudforge_blueprints/azure_gov_il4.yaml +32 -0
- args/cloudforge_blueprints/azure_gov_il5.yaml +36 -0
- args/cloudforge_blueprints/gcp_commercial.yaml +28 -0
- args/cloudforge_blueprints/oci_commercial.yaml +28 -0
- args/cloudforge_config.yaml +231 -0
- args/cloudforge_runbook_templates/backup_verify.yaml +98 -0
- args/cloudforge_runbook_templates/dr_failover.yaml +107 -0
- args/cloudforge_runbook_templates/health_check.yaml +97 -0
- args/cloudforge_runbook_templates/incident_response.yaml +101 -0
- args/cloudforge_runbook_templates/migration_cutover.yaml +105 -0
- args/cloudforge_runbook_templates/patch_rollout.yaml +92 -0
- args/cloudforge_runbook_templates/zone_provision.yaml +93 -0
- args/code_pattern_config.yaml +151 -0
- args/code_quality_config.yaml +47 -0
- args/compliance_config.yaml +17 -0
- args/control_inheritance.yaml +177 -0
- args/csp_mcp_config.yaml +41 -0
- args/cui_markings.yaml +35 -0
- args/databridge_config.yaml +232 -0
- args/db_config.yaml +116 -0
- args/decision_tables/agent_trust_decision.yaml +143 -0
- args/decision_tables/ato_boundary_impact.yaml +132 -0
- args/decision_tables/deployment_approval.yaml +152 -0
- args/degradation_matrix.yaml +163 -0
- args/devsecops_config.yaml +286 -0
- args/endpoint_security_config.yaml +207 -0
- args/exit_criteria.yaml +102 -0
- args/feature_flags.yaml +235 -0
- args/file_access_tiers.yaml +88 -0
- args/forge_studio/blueprint_config.yaml +27 -0
- args/forge_studio/component_catalog.json +411 -0
- args/forge_studio/workflow_templates.yaml +103 -0
- args/govcon_config.yaml +41 -0
- args/harness_config.yaml +67 -0
- args/innovation_config.yaml +321 -0
- args/knowledge_graph_config.yaml +113 -0
- args/llm_config.yaml +222 -0
- args/marketplace_config.yaml +260 -0
- args/monitoring_config.yaml +127 -0
- args/mosa_config.yaml +190 -0
- args/observability_tracing_config.yaml +170 -0
- args/owasp_agentic_config.yaml +171 -0
- args/pipeline_gates.yaml +197 -0
- args/project_defaults.yaml +235 -0
- args/prompt_chains.yaml +163 -0
- args/rag_config.yaml +167 -0
- args/research_config.yaml +89 -0
- args/resilience_config.yaml +197 -0
- args/ricoas_config.yaml +191 -0
- args/security_gates.yaml +763 -0
- args/storage_config.yaml +63 -0
- args/writeguard_config.yaml +131 -0
- args/zta_config.yaml +247 -0
- context/__init__.py +6 -0
- context/agent/__init__.py +6 -0
- context/agent/response_schemas/__init__.py +6 -0
- context/agent/response_schemas/debate_position.json +46 -0
- context/agent/response_schemas/fitness_scorecard.json +74 -0
- context/agent/response_schemas/review_decision.json +39 -0
- context/agent/response_schemas/task_decomposition.json +82 -0
- context/agent/response_schemas/veto_decision.json +40 -0
- context/agentic/__init__.py +6 -0
- context/agentic/architecture_patterns.md +269 -0
- context/agentic/capability_registry.yaml +223 -0
- context/agentic/csp_integration.md +30 -0
- context/agentic/csp_mcp_registry.yaml +280 -0
- context/agentic/fitness_rubric.md +56 -0
- context/agentic/governance_baseline.md +205 -0
- context/ci/__init__.py +6 -0
- context/ci/worktree_templates.json +44 -0
- context/cloud/__init__.py +6 -0
- context/cloud/csp_service_registry.json +739 -0
- context/compliance/__init__.py +6 -0
- context/compliance/ai_rmf_crosswalk.yaml +226 -0
- context/compliance/atlas_mitigations.json +293 -0
- context/compliance/atlas_techniques.json +833 -0
- context/compliance/cisa_sbd_requirements.json +477 -0
- context/compliance/cjis_security_policy.json +522 -0
- context/compliance/cmmc_practices.json +2494 -0
- context/compliance/cmmc_report_template.md +142 -0
- context/compliance/cnssi_1253_overlay.json +109 -0
- context/compliance/control_crosswalk.json +1914 -0
- context/compliance/control_families/__init__.py +6 -0
- context/compliance/csp_certifications.json +251 -0
- context/compliance/cssp_report_template.md +193 -0
- context/compliance/cui_templates/__init__.py +6 -0
- context/compliance/cui_templates/banner_block.txt +4 -0
- context/compliance/cui_templates/code_header.txt +8 -0
- context/compliance/cui_templates/document_template.md +35 -0
- context/compliance/data_type_framework_map.json +321 -0
- context/compliance/data_type_registry.json +147 -0
- context/compliance/dod_cssp_8530.json +463 -0
- context/compliance/eu_ai_act_annex_iii.json +108 -0
- context/compliance/export_templates/__init__.py +6 -0
- context/compliance/export_templates/emass_controls.csv.j2 +4 -0
- context/compliance/export_templates/evidence_package.md.j2 +39 -0
- context/compliance/export_templates/executive_summary.md.j2 +55 -0
- context/compliance/export_templates/poam_tracking.csv.j2 +4 -0
- context/compliance/fedramp_20x_ksi_schemas.json +133 -0
- context/compliance/fedramp_high_baseline.json +4370 -0
- context/compliance/fedramp_moderate_baseline.json +2183 -0
- context/compliance/fedramp_report_template.md +181 -0
- context/compliance/fips_200_areas.json +362 -0
- context/compliance/gao_ai_accountability.json +262 -0
- context/compliance/hipaa_security_rule.json +720 -0
- context/compliance/hitrust_csf_v11.json +930 -0
- context/compliance/impact_level_profiles.json +251 -0
- context/compliance/incident_response_template.md +1110 -0
- context/compliance/iso27001_2022_controls.json +750 -0
- context/compliance/iso27001_nist_bridge.json +382 -0
- context/compliance/iso42001_controls.json +254 -0
- context/compliance/ivv_checklist_template.md +80 -0
- context/compliance/ivv_report_template.md +116 -0
- context/compliance/ivv_requirements.json +372 -0
- context/compliance/mosa_crosswalk.json +327 -0
- context/compliance/mosa_framework.json +250 -0
- context/compliance/narrative_templates/AC.md.j2 +101 -0
- context/compliance/narrative_templates/AU.md.j2 +106 -0
- context/compliance/narrative_templates/IA.md.j2 +104 -0
- context/compliance/narrative_templates/SC.md.j2 +102 -0
- context/compliance/narrative_templates/SI.md.j2 +111 -0
- context/compliance/narrative_templates/__init__.py +6 -0
- context/compliance/narrative_templates/default.md.j2 +50 -0
- context/compliance/narrative_templates/executive_summary.j2 +27 -0
- context/compliance/narrative_templates/poam_milestone.j2 +19 -0
- context/compliance/narrative_templates/ssp_section.j2 +11 -0
- context/compliance/nist_800_171_controls.json +1552 -0
- context/compliance/nist_800_207_crosswalk.json +399 -0
- context/compliance/nist_800_207_zta.json +258 -0
- context/compliance/nist_800_53.json +324 -0
- context/compliance/nist_ai_600_1_genai.json +326 -0
- context/compliance/nist_ai_rmf.json +206 -0
- context/compliance/nist_sp_800_60_types.json +1667 -0
- context/compliance/omb_m25_21_high_impact_ai.json +248 -0
- context/compliance/omb_m26_04_unbiased_ai.json +262 -0
- context/compliance/owasp_agentic_asi.json +133 -0
- context/compliance/owasp_agentic_threats.json +285 -0
- context/compliance/owasp_llm_top10.json +274 -0
- context/compliance/pci_dss_v4.json +510 -0
- context/compliance/poam_template.md +117 -0
- context/compliance/safeai_controls.json +512 -0
- context/compliance/sbd_report_template.md +77 -0
- context/compliance/siem_config_templates/__init__.py +6 -0
- context/compliance/siem_config_templates/filebeat.yml +213 -0
- context/compliance/siem_config_templates/log_sources.json +208 -0
- context/compliance/soc2_trust_criteria.json +661 -0
- context/compliance/ssp_template.md +432 -0
- context/compliance/stig_templates/__init__.py +6 -0
- context/compliance/stig_templates/webapp_stig.json +139 -0
- context/compliance/xai_requirements.json +108 -0
- context/dashboard/__init__.py +6 -0
- context/dashboard/nlq_examples.json +50 -0
- context/dashboard/schema_descriptions.json +23 -0
- context/icdev_methodology.md +100 -0
- context/integration/__init__.py +6 -0
- context/integration/approval_workflows.json +32 -0
- context/integration/gitlab_field_mappings.json +33 -0
- context/integration/jira_field_mappings.json +32 -0
- context/integration/reqif_export_schema.json +23 -0
- context/integration/servicenow_field_mappings.json +22 -0
- context/languages/__init__.py +6 -0
- context/languages/framework_patterns.json +205 -0
- context/languages/language_registry.json +279 -0
- context/llm/__init__.py +6 -0
- context/llm/example_provider.py +89 -0
- context/marketplace/assets/writeguard-core.yaml +100 -0
- context/marketplace/assets/writeguard-govcon.yaml +45 -0
- context/marketplace/assets/writeguard-style-guides.yaml +44 -0
- context/mbse/__init__.py +6 -0
- context/mbse/des_report_template.md +162 -0
- context/mbse/des_requirements.json +411 -0
- context/mbse/digital_thread_patterns.json +403 -0
- context/mbse/reqif_schema.json +280 -0
- context/mbse/sysml_element_types.json +432 -0
- context/oscal/NIST_SP-800-53_rev5_catalog.json +254987 -0
- context/oscal/README.md +43 -0
- context/patterns/__init__.py +6 -0
- context/profiles/__init__.py +6 -0
- context/profiles/dod_baseline_v1.yaml +145 -0
- context/profiles/fedramp_baseline_v1.yaml +143 -0
- context/profiles/financial_baseline_v1.yaml +142 -0
- context/profiles/healthcare_baseline_v1.yaml +135 -0
- context/profiles/law_enforcement_v1.yaml +129 -0
- context/profiles/startup_v1.yaml +134 -0
- context/rag/source_mappings.json +42 -0
- context/requirements/__init__.py +6 -0
- context/requirements/ambiguity_patterns.json +97 -0
- context/requirements/boundary_impact_rules.json +123 -0
- context/requirements/default_constitutions.json +67 -0
- context/requirements/document_extraction_rules.json +58 -0
- context/requirements/gap_patterns.json +108 -0
- context/requirements/readiness_rubric.json +78 -0
- context/requirements/red_alternative_patterns.json +210 -0
- context/requirements/safe_templates.json +72 -0
- context/requirements/spec_quality_checklist.json +122 -0
- context/research/regulatory_registry.json +114 -0
- context/research/verticals/cybersecurity.json +127 -0
- context/research/verticals/defense.json +104 -0
- context/research/verticals/fintech.json +125 -0
- context/research/verticals/healthcare.json +118 -0
- context/research/verticals/logistics.json +117 -0
- context/research/verticals/trading.json +145 -0
- context/simulation/__init__.py +6 -0
- context/simulation/architecture_patterns.json +36 -0
- context/simulation/coa_templates.json +38 -0
- context/simulation/cost_models.json +23 -0
- context/simulation/risk_categories.json +46 -0
- context/supply_chain/__init__.py +6 -0
- context/supply_chain/isa_templates.json +129 -0
- context/supply_chain/nist_800_161_controls.json +247 -0
- context/supply_chain/scrm_risk_matrix.json +147 -0
- context/templates/__init__.py +6 -0
- context/templates/ansible/__init__.py +6 -0
- context/templates/ansible/playbooks/__init__.py +6 -0
- context/templates/ansible/roles/__init__.py +6 -0
- context/templates/gitlab_ci/__init__.py +6 -0
- context/templates/grafana/__init__.py +6 -0
- context/templates/kubernetes/__init__.py +6 -0
- context/templates/project/__init__.py +6 -0
- context/templates/project/api/__init__.py +6 -0
- context/templates/project/cli/__init__.py +6 -0
- context/templates/project/data_pipeline/__init__.py +6 -0
- context/templates/project/iac/__init__.py +6 -0
- context/templates/project/javascript_frontend/__init__.py +6 -0
- context/templates/project/javascript_frontend/src/__init__.py +6 -0
- context/templates/project/javascript_frontend/tests/__init__.py +6 -0
- context/templates/project/microservice/__init__.py +6 -0
- context/templates/project/python_backend/__init__.py +6 -0
- context/templates/project/python_backend/src/__init__.py +6 -0
- context/templates/project/python_backend/tests/__init__.py +6 -0
- context/templates/project/python_backend/tests/features/__init__.py +6 -0
- context/templates/project/python_backend/tests/steps/__init__.py +6 -0
- context/templates/terraform/__init__.py +6 -0
- context/templates/terraform/govcloud_base/__init__.py +6 -0
- context/templates/terraform/modules/__init__.py +6 -0
- context/tone/__init__.py +6 -0
- context/writing/grammar_rules/common_errors.json +306 -0
- context/writing/grammar_rules/govcon_vocabulary.json +113 -0
- context/writing/style_guides/academic.yaml +43 -0
- context/writing/style_guides/business.yaml +42 -0
- context/writing/style_guides/government.yaml +59 -0
- context/writing/style_guides/proposal.yaml +58 -0
- context/writing/style_guides/technical.yaml +43 -0
- docs/adr/README.md +66 -0
- docs/adr/connector-forge-decisions.md +318 -0
- docs/adr/core-decisions.md +289 -0
- docs/adr/db-decisions.md +94 -0
- docs/adr/harness-decisions.md +122 -0
- docs/adr/innovation-decisions.md +262 -0
- docs/adr/marketplace-decisions.md +109 -0
- docs/adr/sbd-decisions.md +109 -0
- docs/adr/scale-engine-decisions.md +108 -0
- docs/adr/writeguard-decisions.md +136 -0
- docs/architecture/bounded-contexts.md +1032 -0
- docs/features/phase-65-writeguard.md +139 -0
- docs/features/phase-66-marketplace-commerce.md +79 -0
- docs/features/phase-67-knowledge-ingestion-rag-autodraft.md +97 -0
- docs/features/phase-68-enhanced-autodraft-pipeline.md +109 -0
- docs/features/phase-69-proposalai-marketplace-module.md +131 -0
- docs/features/phase-70-databridge.md +214 -0
- docs/features/phase-71-databridge-messaging.md +102 -0
- docs/implementation-plan-architecture-evolution.md +614 -0
- docs/marketplace/CONTRIBUTING.md +124 -0
- docs/marketplace/module_manifest_schema.yaml +83 -0
- docs/research/ai-architecture-patterns-2024-2026.md +1236 -0
- docs/research/app-builder-platform-analysis.md +582 -0
- docs/research/architecture-patterns-c4-ddd-agentic.md +871 -0
- docs/research/flowable-boat-competitive-analysis.md +426 -0
- docs/research/modern-dev-practices-2024-2026.md +1615 -0
- docs/research/secure-by-design-cloudyrion-adaptation.md +270 -0
- goals/agent_management.md +144 -0
- goals/ai_accountability.md +90 -0
- goals/ai_narratives.md +79 -0
- goals/ai_transparency.md +76 -0
- goals/ato_simulator.md +78 -0
- goals/audit_engine.md +177 -0
- goals/bite_sized_plans.md +225 -0
- goals/boundary_supply_chain.md +206 -0
- goals/brainstorming_gate.md +186 -0
- goals/build_app.md +604 -0
- goals/cato_live_evidence.md +77 -0
- goals/cloudforge.md +106 -0
- goals/code_intelligence.md +197 -0
- goals/compliance_workflow.md +858 -0
- goals/connector_forge.md +133 -0
- goals/databridge.md +128 -0
- goals/deploy_workflow.md +390 -0
- goals/developer_scorecard.md +78 -0
- goals/devsecops_workflow.md +408 -0
- goals/firmware_sbom.md +79 -0
- goals/forge_hub.md +78 -0
- goals/golden_path.md +77 -0
- goals/harness_engineering.md +91 -0
- goals/integration_testing.md +189 -0
- goals/knowledge_graph.md +128 -0
- goals/maintenance_audit.md +196 -0
- goals/manifest.md +50 -0
- goals/monitoring.md +126 -0
- goals/mosa_workflow.md +463 -0
- goals/multi_agent_orchestration.md +68 -0
- goals/observability_traceability_xai.md +154 -0
- goals/owasp_agentic_security.md +395 -0
- goals/pr_intelligence.md +78 -0
- goals/requirements_intake.md +213 -0
- goals/secure_by_design.md +135 -0
- goals/security_scan.md +381 -0
- goals/self_healing.md +120 -0
- goals/simulation_engine.md +111 -0
- goals/subagent_review.md +205 -0
- goals/systematic_debugging.md +257 -0
- goals/tdd_workflow.md +403 -0
- goals/template_exchange.md +77 -0
- goals/thread_heatmap.md +77 -0
- goals/threat_modeler.md +77 -0
- goals/verification_iron_law.md +192 -0
- goals/vsm_dashboard.md +76 -0
- goals/writeguard.md +89 -0
- goals/zero_trust_architecture.md +403 -0
- hardprompts/__init__.py +6 -0
- hardprompts/agent/__init__.py +6 -0
- hardprompts/agent/agentic_architect.md +100 -0
- hardprompts/agent/debate_prompt.md +32 -0
- hardprompts/agent/fitness_evaluation.md +48 -0
- hardprompts/agent/governance_review.md +214 -0
- hardprompts/agent/reviewer_prompt.md +34 -0
- hardprompts/agent/skill_design.md +172 -0
- hardprompts/agent/task_decomposition.md +275 -0
- hardprompts/agent/veto_check_prompt.md +33 -0
- hardprompts/architect/__init__.py +6 -0
- hardprompts/architect/api_design.md +283 -0
- hardprompts/architect/data_model.md +277 -0
- hardprompts/architect/system_design.md +180 -0
- hardprompts/builder/__init__.py +6 -0
- hardprompts/builder/code_generation.md +59 -0
- hardprompts/builder/refactor.md +58 -0
- hardprompts/builder/scaffold_project.md +69 -0
- hardprompts/builder/test_generation.md +87 -0
- hardprompts/ci/__init__.py +6 -0
- hardprompts/ci/worktree_setup.md +35 -0
- hardprompts/compliance/__init__.py +6 -0
- hardprompts/compliance/cmmc_assessment.md +63 -0
- hardprompts/compliance/cssp_assessment.md +75 -0
- hardprompts/compliance/cui_marking.md +86 -0
- hardprompts/compliance/fedramp_assessment.md +55 -0
- hardprompts/compliance/ivv_assessment.md +96 -0
- hardprompts/compliance/poam_generation.md +57 -0
- hardprompts/compliance/sbd_assessment.md +101 -0
- hardprompts/compliance/security_categorization.md +74 -0
- hardprompts/compliance/ssp_generation.md +56 -0
- hardprompts/compliance/stig_evaluation.md +63 -0
- hardprompts/dashboard/__init__.py +6 -0
- hardprompts/dashboard/nlq_system_prompt.md +26 -0
- hardprompts/infra/__init__.py +6 -0
- hardprompts/infra/k8s_manifests.md +118 -0
- hardprompts/infra/pipeline_generation.md +160 -0
- hardprompts/infra/terraform_generation.md +92 -0
- hardprompts/integration/__init__.py +6 -0
- hardprompts/integration/approval_review.md +17 -0
- hardprompts/integration/jira_mapping.md +25 -0
- hardprompts/integration/servicenow_mapping.md +14 -0
- hardprompts/knowledge/__init__.py +6 -0
- hardprompts/knowledge/pattern_detection.md +73 -0
- hardprompts/knowledge/recommendation_engine.md +90 -0
- hardprompts/knowledge/root_cause_analysis.md +91 -0
- hardprompts/maintenance/__init__.py +6 -0
- hardprompts/maintenance/maintenance_assessment.md +82 -0
- hardprompts/mbse/__init__.py +6 -0
- hardprompts/mbse/digital_thread.md +67 -0
- hardprompts/mbse/model_import.md +62 -0
- hardprompts/mbse/model_to_code.md +65 -0
- hardprompts/modernization/__init__.py +6 -0
- hardprompts/modernization/legacy_analysis.md +93 -0
- hardprompts/modernization/migration_planning.md +150 -0
- hardprompts/modernization/seven_r_assessment.md +107 -0
- hardprompts/proposal_draft.md +53 -0
- hardprompts/rag_citation.md +12 -0
- hardprompts/rag_rerank.md +31 -0
- hardprompts/requirements/__init__.py +6 -0
- hardprompts/requirements/bdd_generation.md +35 -0
- hardprompts/requirements/clarification_prioritization.md +29 -0
- hardprompts/requirements/decomposition.md +60 -0
- hardprompts/requirements/document_extraction.md +45 -0
- hardprompts/requirements/gap_detection.md +70 -0
- hardprompts/requirements/intake_conversation.md +101 -0
- hardprompts/requirements/readiness_assessment.md +39 -0
- hardprompts/requirements/spec_quality.md +33 -0
- hardprompts/requirements/traceability_analysis.md +23 -0
- hardprompts/security/__init__.py +6 -0
- hardprompts/security/endpoint_security.md +78 -0
- hardprompts/security/threat_model.md +70 -0
- hardprompts/security/vulnerability_assessment.md +81 -0
- hardprompts/simulation/__init__.py +6 -0
- hardprompts/simulation/architecture_impact.md +27 -0
- hardprompts/simulation/coa_alternative.md +27 -0
- hardprompts/simulation/coa_generation.md +25 -0
- hardprompts/simulation/compliance_impact.md +28 -0
- hardprompts/simulation/cost_estimation.md +33 -0
- hardprompts/simulation/risk_assessment.md +28 -0
- hardprompts/translation/code_translation.md +68 -0
- hardprompts/translation/dependency_suggestion.md +44 -0
- hardprompts/translation/test_translation.md +64 -0
- hardprompts/translation/translation_repair.md +59 -0
- icdev-0.0.3.dist-info/METADATA +909 -0
- icdev-0.0.3.dist-info/RECORD +1214 -0
- icdev-0.0.3.dist-info/WHEEL +5 -0
- icdev-0.0.3.dist-info/entry_points.txt +9 -0
- icdev-0.0.3.dist-info/licenses/LICENSE +201 -0
- icdev-0.0.3.dist-info/licenses/NOTICE +11 -0
- icdev-0.0.3.dist-info/top_level.txt +7 -0
- memory/MEMORY.md +52 -0
- memory/logs/2026-02-14.md +17 -0
- memory/logs/2026-03-03.md +2 -0
- memory/logs/__init__.py +1 -0
- tools/a2a/icdev_callback_client.py +210 -0
- tools/agent/cards/architect_card.json +29 -0
- tools/agent/cards/builder_card.json +34 -0
- tools/agent/cards/compliance_card.json +29 -0
- tools/agent/cards/connector_forge_card.json +49 -0
- tools/agent/cards/devsecops_zta_card.json +24 -0
- tools/agent/cards/knowledge_card.json +29 -0
- tools/agent/cards/monitor_card.json +29 -0
- tools/agent/cards/orchestrator_card.json +29 -0
- tools/agent/cards/requirements_analyst_card.json +24 -0
- tools/agent/cards/security_card.json +29 -0
- tools/agent/cards/simulation_card.json +24 -0
- tools/agent/cards/supply_chain_card.json +24 -0
- tools/analysis/__init__.py +1 -0
- tools/analysis/code_analyzer.py +770 -0
- tools/analysis/runtime_feedback.py +379 -0
- tools/analytics/__init__.py +2 -0
- tools/analytics/scorecard.py +538 -0
- tools/analytics/vsm_engine.py +612 -0
- tools/architecture/__init__.py +2 -0
- tools/architecture/adr_extractor.py +393 -0
- tools/audit/__init__.py +1 -0
- tools/audit/audit_logger.py +199 -0
- tools/audit/audit_query.py +153 -0
- tools/audit/decision_recorder.py +73 -0
- tools/audit_engine/__init__.py +12 -0
- tools/audit_engine/ai_advisor.py +906 -0
- tools/audit_engine/cli.py +286 -0
- tools/audit_engine/comparator.py +305 -0
- tools/audit_engine/eject_scaffolder.py +399 -0
- tools/audit_engine/engine.py +614 -0
- tools/audit_engine/git_fetcher.py +341 -0
- tools/audit_engine/regime_loader.py +200 -0
- tools/audit_engine/regime_updater.py +325 -0
- tools/audit_engine/report_card.py +289 -0
- tools/audit_engine/scanner.py +684 -0
- tools/audit_engine/self_heal.py +1042 -0
- tools/ci/__init__.py +2 -0
- tools/ci/connectors/__init__.py +2 -0
- tools/ci/connectors/base_connector.py +80 -0
- tools/ci/connectors/connector_registry.py +188 -0
- tools/ci/connectors/mattermost_connector.py +159 -0
- tools/ci/connectors/slack_connector.py +197 -0
- tools/ci/core/__init__.py +2 -0
- tools/ci/core/air_gap_detector.py +115 -0
- tools/ci/core/comment_handler.py +192 -0
- tools/ci/core/conversation_manager.py +480 -0
- tools/ci/core/event_envelope.py +500 -0
- tools/ci/core/event_router.py +444 -0
- tools/ci/core/failure_parser.py +397 -0
- tools/ci/core/recovery_engine.py +527 -0
- tools/ci/gate_enforcer.py +361 -0
- tools/ci/modules/__init__.py +2 -0
- tools/ci/modules/agent.py +271 -0
- tools/ci/modules/git_ops.py +175 -0
- tools/ci/modules/state.py +117 -0
- tools/ci/modules/vcs.py +303 -0
- tools/ci/modules/workflow_ops.py +295 -0
- tools/ci/modules/worktree.py +337 -0
- tools/ci/pipeline_config_generator.py +558 -0
- tools/ci/pr_intelligence.py +485 -0
- tools/ci/triggers/__init__.py +2 -0
- tools/ci/triggers/gitlab_task_monitor.py +327 -0
- tools/ci/triggers/poll_trigger.py +237 -0
- tools/ci/triggers/webhook_server.py +356 -0
- tools/ci/workflows/__init__.py +2 -0
- tools/ci/workflows/icdev_build.py +140 -0
- tools/ci/workflows/icdev_comply.py +284 -0
- tools/ci/workflows/icdev_document.py +152 -0
- tools/ci/workflows/icdev_e2e.py +188 -0
- tools/ci/workflows/icdev_patch.py +186 -0
- tools/ci/workflows/icdev_plan.py +202 -0
- tools/ci/workflows/icdev_plan_build.py +41 -0
- tools/ci/workflows/icdev_plan_build_test.py +46 -0
- tools/ci/workflows/icdev_plan_build_test_review.py +47 -0
- tools/ci/workflows/icdev_review.py +126 -0
- tools/ci/workflows/icdev_sdlc.py +261 -0
- tools/ci/workflows/icdev_test.py +240 -0
- tools/cli/__init__.py +1 -0
- tools/cli/output_formatter.py +756 -0
- tools/cloudforge/__init__.py +12 -0
- tools/cloudforge/airgap/__init__.py +2 -0
- tools/cloudforge/airgap/il_classifier.py +70 -0
- tools/cloudforge/airgap/offline_validator.py +42 -0
- tools/cloudforge/airgap/shift_emulator.py +155 -0
- tools/cloudforge/airgap/sneakernet.py +91 -0
- tools/cloudforge/cd_hub/__init__.py +2 -0
- tools/cloudforge/cd_hub/canary_deployer.py +88 -0
- tools/cloudforge/cd_hub/gitops_renderer.py +123 -0
- tools/cloudforge/cd_hub/hub_controller.py +143 -0
- tools/cloudforge/cd_hub/pipeline_bridge.py +30 -0
- tools/cloudforge/cd_hub/rollback_engine.py +29 -0
- tools/cloudforge/cd_hub/spoke_agent.py +51 -0
- tools/cloudforge/compliance/__init__.py +2 -0
- tools/cloudforge/compliance/ato_accelerator.py +272 -0
- tools/cloudforge/compliance/control_inheritor.py +127 -0
- tools/cloudforge/compliance/evidence_generator.py +129 -0
- tools/cloudforge/compliance/poam_bridge.py +41 -0
- tools/cloudforge/compliance/ssp_bridge.py +52 -0
- tools/cloudforge/compliance/stig_bridge.py +41 -0
- tools/cloudforge/container_forge/__init__.py +2 -0
- tools/cloudforge/container_forge/bigbang_renderer.py +85 -0
- tools/cloudforge/container_forge/hardener.py +169 -0
- tools/cloudforge/container_forge/image_scanner_bridge.py +33 -0
- tools/cloudforge/container_forge/runtime_policy.py +87 -0
- tools/cloudforge/container_forge/sbom_bridge.py +42 -0
- tools/cloudforge/finops/__init__.py +2 -0
- tools/cloudforge/finops/anomaly_detector.py +78 -0
- tools/cloudforge/finops/budget_tracker.py +96 -0
- tools/cloudforge/finops/chargeback.py +69 -0
- tools/cloudforge/finops/cost_collector.py +141 -0
- tools/cloudforge/finops/optimizer.py +55 -0
- tools/cloudforge/hybrid/__init__.py +2 -0
- tools/cloudforge/hybrid/connection_manager.py +141 -0
- tools/cloudforge/hybrid/dns_federator.py +56 -0
- tools/cloudforge/hybrid/health_monitor.py +108 -0
- tools/cloudforge/hybrid/identity_federator.py +53 -0
- tools/cloudforge/hybrid/network_bridge.py +68 -0
- tools/cloudforge/hybrid/topology_manager.py +147 -0
- tools/cloudforge/hybrid/workload_abstractor.py +92 -0
- tools/cloudforge/iac/__init__.py +2 -0
- tools/cloudforge/iac/drift_detector.py +154 -0
- tools/cloudforge/iac/module_library.py +265 -0
- tools/cloudforge/iac/opentofu_adapter.py +89 -0
- tools/cloudforge/iac/pulumi_renderer.py +292 -0
- tools/cloudforge/iac/state_backend.py +146 -0
- tools/cloudforge/iac/terraform_renderer.py +626 -0
- tools/cloudforge/landing_zone/__init__.py +2 -0
- tools/cloudforge/landing_zone/blueprint_loader.py +98 -0
- tools/cloudforge/landing_zone/blueprint_validator.py +113 -0
- tools/cloudforge/landing_zone/zone_provisioner.py +306 -0
- tools/cloudforge/landing_zone/zone_state.py +143 -0
- tools/cloudforge/mbse_thread/__init__.py +2 -0
- tools/cloudforge/mbse_thread/ato_thread_weaver.py +111 -0
- tools/cloudforge/mbse_thread/control_tracer.py +68 -0
- tools/cloudforge/mbse_thread/system_boundary.py +83 -0
- tools/cloudforge/metastore/__init__.py +2 -0
- tools/cloudforge/metastore/dependency_graph.py +202 -0
- tools/cloudforge/metastore/discovery.py +192 -0
- tools/cloudforge/metastore/registry.py +185 -0
- tools/cloudforge/metastore/rto_tracker.py +92 -0
- tools/cloudforge/metastore/runbook_linker.py +82 -0
- tools/cloudforge/migration/__init__.py +2 -0
- tools/cloudforge/migration/assessor.py +187 -0
- tools/cloudforge/migration/cutover_orchestrator.py +117 -0
- tools/cloudforge/migration/databridge_bridge.py +92 -0
- tools/cloudforge/migration/planner.py +98 -0
- tools/cloudforge/migration/risk_scorer.py +97 -0
- tools/cloudforge/migration/validation_runner.py +45 -0
- tools/cloudforge/migration/workload_inventory.py +107 -0
- tools/cloudforge/provider.py +319 -0
- tools/cloudforge/providers/__init__.py +2 -0
- tools/cloudforge/providers/aws_commercial.py +92 -0
- tools/cloudforge/providers/aws_govcloud.py +229 -0
- tools/cloudforge/providers/aws_secret.py +83 -0
- tools/cloudforge/providers/azure_commercial.py +80 -0
- tools/cloudforge/providers/azure_gov.py +91 -0
- tools/cloudforge/providers/azure_secret.py +71 -0
- tools/cloudforge/providers/gcp.py +102 -0
- tools/cloudforge/providers/oci.py +102 -0
- tools/cloudforge/registry.py +140 -0
- tools/cloudforge/runbooks/__init__.py +2 -0
- tools/cloudforge/runbooks/ai_generator.py +119 -0
- tools/cloudforge/runbooks/dag_validator.py +219 -0
- tools/cloudforge/runbooks/engine.py +470 -0
- tools/cloudforge/runbooks/models.py +99 -0
- tools/cloudforge/runbooks/snippet_library.py +158 -0
- tools/cloudforge/runbooks/template_loader.py +122 -0
- tools/cloudforge/runbooks/visualization.py +108 -0
- tools/cloudforge/siem/__init__.py +2 -0
- tools/cloudforge/siem/alert_rules.py +86 -0
- tools/cloudforge/siem/correlation_engine.py +61 -0
- tools/cloudforge/siem/log_aggregator.py +113 -0
- tools/cloudforge/siem/siem_dashboard_data.py +28 -0
- tools/cloudforge/supply_chain/__init__.py +2 -0
- tools/cloudforge/supply_chain/bridge.py +33 -0
- tools/cloudforge/supply_chain/iac_dependency_scanner.py +36 -0
- tools/cloudforge/supply_chain/provider_trust_scorer.py +54 -0
- tools/compat/__init__.py +21 -0
- tools/compat/cli_harmonizer.py +251 -0
- tools/compat/datetime_utils.py +18 -0
- tools/compat/db_utils.py +190 -0
- tools/compat/platform_utils.py +123 -0
- tools/compliance/__init__.py +1 -0
- tools/compliance/accountability_manager.py +391 -0
- tools/compliance/ai_accountability_audit.py +287 -0
- tools/compliance/ai_impact_assessor.py +267 -0
- tools/compliance/ai_incident_response.py +295 -0
- tools/compliance/ai_inventory_manager.py +233 -0
- tools/compliance/ai_reassessment_scheduler.py +250 -0
- tools/compliance/ai_transparency_audit.py +247 -0
- tools/compliance/atlas_assessor.py +276 -0
- tools/compliance/atlas_report_generator.py +1199 -0
- tools/compliance/base_assessor.py +591 -0
- tools/compliance/cato_live_engine.py +607 -0
- tools/compliance/cato_monitor.py +1371 -0
- tools/compliance/cato_scheduler.py +698 -0
- tools/compliance/cjis_assessor.py +76 -0
- tools/compliance/classification_manager.py +1340 -0
- tools/compliance/cmmc_assessor.py +1478 -0
- tools/compliance/cmmc_report_generator.py +1087 -0
- tools/compliance/compliance_detector.py +452 -0
- tools/compliance/compliance_exporter.py +418 -0
- tools/compliance/compliance_status.py +810 -0
- tools/compliance/control_mapper.py +488 -0
- tools/compliance/crosswalk_engine.py +1208 -0
- tools/compliance/cssp_assessor.py +1032 -0
- tools/compliance/cssp_evidence_collector.py +716 -0
- tools/compliance/cssp_report_generator.py +1103 -0
- tools/compliance/cui_marker.py +387 -0
- tools/compliance/diagram_validator.py +599 -0
- tools/compliance/emass/__init__.py +2 -0
- tools/compliance/emass/emass_client.py +822 -0
- tools/compliance/emass/emass_export.py +758 -0
- tools/compliance/emass/emass_sync.py +807 -0
- tools/compliance/eu_ai_act_classifier.py +193 -0
- tools/compliance/evidence_collector.py +459 -0
- tools/compliance/fairness_assessor.py +310 -0
- tools/compliance/fedramp_20x_ksi_emitter.py +692 -0
- tools/compliance/fedramp_assessor.py +1795 -0
- tools/compliance/fedramp_authorization_packager.py +137 -0
- tools/compliance/fedramp_ksi_generator.py +349 -0
- tools/compliance/fedramp_report_generator.py +1115 -0
- tools/compliance/fips199_categorizer.py +869 -0
- tools/compliance/fips200_validator.py +304 -0
- tools/compliance/firmware_sbom.py +646 -0
- tools/compliance/gao_ai_assessor.py +228 -0
- tools/compliance/gao_evidence_builder.py +302 -0
- tools/compliance/hipaa_assessor.py +78 -0
- tools/compliance/hitrust_assessor.py +49 -0
- tools/compliance/incident_response_plan.py +705 -0
- tools/compliance/inheritance_engine.py +693 -0
- tools/compliance/iso27001_assessor.py +92 -0
- tools/compliance/iso42001_assessor.py +114 -0
- tools/compliance/ivv_assessor.py +2314 -0
- tools/compliance/ivv_report_generator.py +1649 -0
- tools/compliance/model_card_generator.py +291 -0
- tools/compliance/mosa_assessor.py +117 -0
- tools/compliance/multi_regime_assessor.py +441 -0
- tools/compliance/narrative_generator.py +1012 -0
- tools/compliance/narrative_quality_gate.py +701 -0
- tools/compliance/narrative_workflow.py +814 -0
- tools/compliance/nist_800_207_assessor.py +191 -0
- tools/compliance/nist_ai_600_1_assessor.py +185 -0
- tools/compliance/nist_ai_rmf_assessor.py +110 -0
- tools/compliance/nist_lookup.py +244 -0
- tools/compliance/omb_m25_21_assessor.py +225 -0
- tools/compliance/omb_m26_04_assessor.py +185 -0
- tools/compliance/oscal_catalog_adapter.py +395 -0
- tools/compliance/oscal_generator.py +2157 -0
- tools/compliance/oscal_tools.py +1182 -0
- tools/compliance/oscal_validator.py +692 -0
- tools/compliance/owasp_agentic_assessor.py +227 -0
- tools/compliance/owasp_asi_assessor.py +197 -0
- tools/compliance/owasp_llm_assessor.py +245 -0
- tools/compliance/pci_dss_assessor.py +80 -0
- tools/compliance/pi_compliance_tracker.py +1447 -0
- tools/compliance/poam_generator.py +388 -0
- tools/compliance/resolve_marking.py +272 -0
- tools/compliance/sbd_assessor.py +2070 -0
- tools/compliance/sbd_report_generator.py +1223 -0
- tools/compliance/sbom_generator.py +993 -0
- tools/compliance/siem_config_generator.py +661 -0
- tools/compliance/slsa_attestation_generator.py +479 -0
- tools/compliance/soc2_assessor.py +77 -0
- tools/compliance/ssp_generator.py +556 -0
- tools/compliance/stig_checker.py +712 -0
- tools/compliance/swft_evidence_bundler.py +326 -0
- tools/compliance/system_card_generator.py +303 -0
- tools/compliance/template_exchange.py +513 -0
- tools/compliance/traceability_matrix.py +1268 -0
- tools/compliance/universal_classification_manager.py +1159 -0
- tools/compliance/xacta/__init__.py +2 -0
- tools/compliance/xacta/xacta_client.py +438 -0
- tools/compliance/xacta/xacta_export.py +546 -0
- tools/compliance/xacta/xacta_sync.py +322 -0
- tools/compliance/xai_assessor.py +231 -0
- tools/core/__init__.py +2 -0
- tools/core/circuit_breaker.py +353 -0
- tools/core/compliance_sidecar.py +344 -0
- tools/core/container.py +110 -0
- tools/core/errors.py +256 -0
- tools/core/feature_flags.py +311 -0
- tools/core/task_dlq.py +350 -0
- tools/dashboard/__init__.py +2 -0
- tools/dashboard/app.py +6288 -0
- tools/dashboard/templates/agent_evolution.html +287 -0
- tools/dashboard/templates/agents/list.html +71 -0
- tools/dashboard/templates/agents.html +132 -0
- tools/dashboard/templates/architecture.html +289 -0
- tools/dashboard/templates/ato_simulator.html +170 -0
- tools/dashboard/templates/audit_engine.html +844 -0
- tools/dashboard/templates/base.html +236 -0
- tools/dashboard/templates/cato_live.html +116 -0
- tools/dashboard/templates/cloudforge.html +195 -0
- tools/dashboard/templates/cloudforge_finops.html +111 -0
- tools/dashboard/templates/cloudforge_hybrid.html +122 -0
- tools/dashboard/templates/cloudforge_metastore.html +234 -0
- tools/dashboard/templates/cloudforge_migration.html +87 -0
- tools/dashboard/templates/cloudforge_runbooks.html +201 -0
- tools/dashboard/templates/cloudforge_siem.html +94 -0
- tools/dashboard/templates/compliance_accel.html +292 -0
- tools/dashboard/templates/crashes.html +122 -0
- tools/dashboard/templates/databridge.html +305 -0
- tools/dashboard/templates/databridge_analytics.html +195 -0
- tools/dashboard/templates/databridge_mapping.html +345 -0
- tools/dashboard/templates/databridge_messaging.html +321 -0
- tools/dashboard/templates/decisions.html +258 -0
- tools/dashboard/templates/devices.html +151 -0
- tools/dashboard/templates/devsecops_maturity.html +278 -0
- tools/dashboard/templates/edge_ai.html +128 -0
- tools/dashboard/templates/firmware.html +120 -0
- tools/dashboard/templates/firmware_sbom.html +193 -0
- tools/dashboard/templates/forge_hub.html +196 -0
- tools/dashboard/templates/forge_studio.html +379 -0
- tools/dashboard/templates/forge_studio_analytics.html +360 -0
- tools/dashboard/templates/forge_studio_builder.html +1637 -0
- tools/dashboard/templates/forge_studio_compliance.html +310 -0
- tools/dashboard/templates/forge_studio_deploy.html +573 -0
- tools/dashboard/templates/forge_studio_enterprise.html +888 -0
- tools/dashboard/templates/forge_studio_marketplace.html +502 -0
- tools/dashboard/templates/forge_studio_workflow.html +696 -0
- tools/dashboard/templates/golden_path.html +175 -0
- tools/dashboard/templates/govcon.html +280 -0
- tools/dashboard/templates/harness.html +148 -0
- tools/dashboard/templates/index.html +207 -0
- tools/dashboard/templates/intelligence.html +336 -0
- tools/dashboard/templates/knowledge/index.html +190 -0
- tools/dashboard/templates/knowledge_graph.html +739 -0
- tools/dashboard/templates/login.html +51 -0
- tools/dashboard/templates/marketplace.html +336 -0
- tools/dashboard/templates/marketplace_admin.html +247 -0
- tools/dashboard/templates/missions.html +403 -0
- tools/dashboard/templates/narratives.html +154 -0
- tools/dashboard/templates/pr_intelligence.html +151 -0
- tools/dashboard/templates/proposals/detail.html +300 -0
- tools/dashboard/templates/proposals/list.html +52 -0
- tools/dashboard/templates/proposals/sam_detail.html +132 -0
- tools/dashboard/templates/proposals/section_detail.html +375 -0
- tools/dashboard/templates/research.html +222 -0
- tools/dashboard/templates/resilience.html +300 -0
- tools/dashboard/templates/scorecard.html +162 -0
- tools/dashboard/templates/simulator.html +131 -0
- tools/dashboard/templates/template_exchange.html +147 -0
- tools/dashboard/templates/thread_heatmap.html +151 -0
- tools/dashboard/templates/threat_model.html +195 -0
- tools/dashboard/templates/vsm.html +141 -0
- tools/dashboard/templates/writeguard.html +277 -0
- tools/databridge/__init__.py +5 -0
- tools/databridge/agent/__init__.py +2 -0
- tools/databridge/agent/daemon.py +227 -0
- tools/databridge/agent/tunnel.py +101 -0
- tools/databridge/agent/ws_relay.py +91 -0
- tools/databridge/analytics.py +167 -0
- tools/databridge/arrow_pipeline.py +327 -0
- tools/databridge/connection_manager.py +424 -0
- tools/databridge/connector.py +331 -0
- tools/databridge/connectors/__init__.py +2 -0
- tools/databridge/connectors/argocd_connector.py +160 -0
- tools/databridge/connectors/avro_connector.py +203 -0
- tools/databridge/connectors/azure_blob.py +63 -0
- tools/databridge/connectors/cdc_connector.py +205 -0
- tools/databridge/connectors/csv_connector.py +172 -0
- tools/databridge/connectors/datadog_connector.py +153 -0
- tools/databridge/connectors/discord_messaging.py +215 -0
- tools/databridge/connectors/dynamics365.py +151 -0
- tools/databridge/connectors/elasticsearch_connector.py +145 -0
- tools/databridge/connectors/email_base.py +114 -0
- tools/databridge/connectors/excel_connector.py +175 -0
- tools/databridge/connectors/fsspec_base.py +300 -0
- tools/databridge/connectors/gcs.py +53 -0
- tools/databridge/connectors/github_connector.py +138 -0
- tools/databridge/connectors/gitlab_connector.py +132 -0
- tools/databridge/connectors/gmail_connector.py +182 -0
- tools/databridge/connectors/hdfs.py +57 -0
- tools/databridge/connectors/health_base.py +401 -0
- tools/databridge/connectors/hubspot.py +124 -0
- tools/databridge/connectors/imap_connector.py +171 -0
- tools/databridge/connectors/jenkins_connector.py +138 -0
- tools/databridge/connectors/jira_connector.py +86 -0
- tools/databridge/connectors/json_connector.py +184 -0
- tools/databridge/connectors/kafka_connector.py +246 -0
- tools/databridge/connectors/kinesis_connector.py +238 -0
- tools/databridge/connectors/local_fs.py +30 -0
- tools/databridge/connectors/matrix.py +197 -0
- tools/databridge/connectors/mattermost_messaging.py +184 -0
- tools/databridge/connectors/messaging_base.py +172 -0
- tools/databridge/connectors/mssql.py +63 -0
- tools/databridge/connectors/mysql.py +57 -0
- tools/databridge/connectors/netsuite.py +170 -0
- tools/databridge/connectors/o365_mail.py +196 -0
- tools/databridge/connectors/oracle.py +65 -0
- tools/databridge/connectors/pagerduty_connector.py +162 -0
- tools/databridge/connectors/parquet_connector.py +131 -0
- tools/databridge/connectors/postgresql.py +58 -0
- tools/databridge/connectors/s3.py +65 -0
- tools/databridge/connectors/saas_base.py +198 -0
- tools/databridge/connectors/salesforce.py +126 -0
- tools/databridge/connectors/sap.py +89 -0
- tools/databridge/connectors/servicenow.py +60 -0
- tools/databridge/connectors/signal_messaging.py +150 -0
- tools/databridge/connectors/slack_messaging.py +203 -0
- tools/databridge/connectors/smtp_connector.py +126 -0
- tools/databridge/connectors/soap_base.py +258 -0
- tools/databridge/connectors/splunk_connector.py +171 -0
- tools/databridge/connectors/sql_base.py +310 -0
- tools/databridge/connectors/sqlite_connector.py +76 -0
- tools/databridge/connectors/teams.py +148 -0
- tools/databridge/connectors/telegram.py +192 -0
- tools/databridge/connectors/whatsapp.py +137 -0
- tools/databridge/data_profiler.py +99 -0
- tools/databridge/forge/__init__.py +6 -0
- tools/databridge/forge/base_selector.py +150 -0
- tools/databridge/forge/code_generator.py +206 -0
- tools/databridge/forge/community_hub.py +539 -0
- tools/databridge/forge/forge_agent.py +306 -0
- tools/databridge/forge/import_handler.py +133 -0
- tools/databridge/forge/integration_tester.py +127 -0
- tools/databridge/forge/marketplace_publisher.py +164 -0
- tools/databridge/forge/promoter.py +159 -0
- tools/databridge/forge/sandbox_manager.py +257 -0
- tools/databridge/forge/spec_parser.py +358 -0
- tools/databridge/forge/static_validator.py +363 -0
- tools/databridge/forge/templates/__init__.py +591 -0
- tools/databridge/format_converter.py +188 -0
- tools/databridge/mapping_engine.py +348 -0
- tools/databridge/messaging/__init__.py +5 -0
- tools/databridge/messaging/agent_bridge.py +254 -0
- tools/databridge/messaging/message_envelope.py +111 -0
- tools/databridge/messaging/message_logger.py +204 -0
- tools/databridge/messaging/messaging_daemon.py +326 -0
- tools/databridge/messaging/oauth2_manager.py +411 -0
- tools/databridge/pii_detector.py +221 -0
- tools/databridge/registry.py +352 -0
- tools/databridge/relay_server.py +105 -0
- tools/databridge/scale/__init__.py +16 -0
- tools/databridge/scale/backpressure.py +134 -0
- tools/databridge/scale/chunked_pipeline.py +169 -0
- tools/databridge/scale/connection_pool.py +293 -0
- tools/databridge/scale/engine.py +492 -0
- tools/databridge/scale/worker_pool.py +140 -0
- tools/databridge/scale/write_batcher.py +250 -0
- tools/databridge/schema_engine.py +324 -0
- tools/databridge/stream_manager.py +225 -0
- tools/databridge/sync_engine.py +411 -0
- tools/databridge/transforms.py +302 -0
- tools/db/__init__.py +1 -0
- tools/db/backup.py +312 -0
- tools/db/backup_manager.py +832 -0
- tools/db/init_icdev_db.py +7753 -0
- tools/db/init_sparkpilot_db.py +431 -0
- tools/db/migrate.py +177 -0
- tools/db/migrate_innovation_audit.py +165 -0
- tools/db/migration_runner.py +548 -0
- tools/db/migrations/001_baseline/meta.json +9 -0
- tools/db/migrations/001_baseline/up.py +67 -0
- tools/db/migrations/002_memory_enhancements/down.sql +8 -0
- tools/db/migrations/002_memory_enhancements/meta.json +9 -0
- tools/db/migrations/002_memory_enhancements/up.py +119 -0
- tools/db/migrations/003_dev_profiles/meta.json +8 -0
- tools/db/migrations/003_dev_profiles/up.py +93 -0
- tools/db/migrations/004_innovation_engine/down.py +19 -0
- tools/db/migrations/004_innovation_engine/up.py +227 -0
- tools/db/migrations/005_phase_37_ai_security/down.py +19 -0
- tools/db/migrations/005_phase_37_ai_security/up.py +257 -0
- tools/db/migrations/006_phase_36_evolution/down.py +21 -0
- tools/db/migrations/006_phase_36_evolution/up.py +323 -0
- tools/db/migrations/007_phase_38_cloud/down.py +14 -0
- tools/db/migrations/007_phase_38_cloud/up.py +110 -0
- tools/db/migrations/008_phase36_37_integration/up.py +55 -0
- tools/db/migrations/__init__.py +2 -0
- tools/db/pg_migrate.py +642 -0
- tools/db/storage.py +1080 -0
- tools/decisions/__init__.py +2 -0
- tools/decisions/dmn_engine.py +695 -0
- tools/devsecops/__init__.py +2 -0
- tools/devsecops/attestation_manager.py +449 -0
- tools/devsecops/network_segmentation_generator.py +604 -0
- tools/devsecops/pdp_config_generator.py +1246 -0
- tools/devsecops/pipeline_security_generator.py +475 -0
- tools/devsecops/policy_generator.py +644 -0
- tools/devsecops/profile_manager.py +374 -0
- tools/devsecops/service_mesh_generator.py +1063 -0
- tools/devsecops/zta_maturity_scorer.py +355 -0
- tools/devsecops/zta_terraform_generator.py +1301 -0
- tools/edge_ai/__init__.py +2 -0
- tools/edge_ai/model_manager.py +200 -0
- tools/embedded/__init__.py +2 -0
- tools/embedded/cmake_generator.py +318 -0
- tools/embedded/crash_analyzer.py +191 -0
- tools/embedded/nl_to_firmware.py +277 -0
- tools/events/__init__.py +1 -0
- tools/events/event_bus.py +199 -0
- tools/finetune/pair_generator.py +832 -0
- tools/fleet/__init__.py +2 -0
- tools/fleet/device_registry.py +148 -0
- tools/fleet/ota_manager.py +153 -0
- tools/forge_studio/__init__.py +13 -0
- tools/forge_studio/analytics/__init__.py +0 -0
- tools/forge_studio/analytics/process_miner.py +383 -0
- tools/forge_studio/audit.py +183 -0
- tools/forge_studio/blueprint/__init__.py +2 -0
- tools/forge_studio/blueprint/build_tracker.py +317 -0
- tools/forge_studio/blueprint/export_engine.py +441 -0
- tools/forge_studio/blueprint/parent_client.py +335 -0
- tools/forge_studio/catalog/__init__.py +2 -0
- tools/forge_studio/catalog/component_registry.py +176 -0
- tools/forge_studio/catalog/schema_validator.py +193 -0
- tools/forge_studio/compliance/__init__.py +1 -0
- tools/forge_studio/compliance/compliance_wiring.py +554 -0
- tools/forge_studio/deploy/__init__.py +1 -0
- tools/forge_studio/deploy/airgap_packager.py +466 -0
- tools/forge_studio/deploy/deploy_engine.py +1792 -0
- tools/forge_studio/deploy/env_manager.py +431 -0
- tools/forge_studio/eject/__init__.py +2 -0
- tools/forge_studio/eject/docker_compose_generator.py +237 -0
- tools/forge_studio/eject/eject_engine.py +230 -0
- tools/forge_studio/eject/expo_scaffolder.py +303 -0
- tools/forge_studio/eject/nextjs_scaffolder.py +338 -0
- tools/forge_studio/enterprise/__init__.py +0 -0
- tools/forge_studio/enterprise/custom_frameworks.py +826 -0
- tools/forge_studio/enterprise/hardening_engine.py +1530 -0
- tools/forge_studio/enterprise/sso_manager.py +718 -0
- tools/forge_studio/enterprise/whitelabel_engine.py +887 -0
- tools/forge_studio/formula/__init__.py +0 -0
- tools/forge_studio/formula/expression_engine.py +562 -0
- tools/forge_studio/formula/formula_registry.py +265 -0
- tools/forge_studio/generator/__init__.py +2 -0
- tools/forge_studio/generator/app_generator.py +584 -0
- tools/forge_studio/generator/complexity_detector.py +368 -0
- tools/forge_studio/generator/prompt_templates.py +104 -0
- tools/forge_studio/generator/spec_builder.py +192 -0
- tools/forge_studio/intake_bridge.py +898 -0
- tools/forge_studio/marketplace/__init__.py +0 -0
- tools/forge_studio/marketplace/component_hub.py +428 -0
- tools/forge_studio/models.py +369 -0
- tools/forge_studio/renderer/__init__.py +2 -0
- tools/forge_studio/renderer/json_render_engine.py +623 -0
- tools/forge_studio/renderer/layout_engine.py +214 -0
- tools/forge_studio/renderer/rn_component_map.py +182 -0
- tools/forge_studio/supabase/__init__.py +2 -0
- tools/forge_studio/supabase/auth_generator.py +283 -0
- tools/forge_studio/supabase/migration_generator.py +93 -0
- tools/forge_studio/supabase/schema_generator.py +281 -0
- tools/forge_studio/tenant_manager.py +387 -0
- tools/forge_studio/workflow/__init__.py +2 -0
- tools/forge_studio/workflow/bpmn_adapter.py +489 -0
- tools/govcon/draft_orchestrator.py +1151 -0
- tools/govcon/engine_enrichment.py +373 -0
- tools/govcon/knowledge_base.py +487 -0
- tools/govcon/knowledge_ingestion.py +510 -0
- tools/govcon/sam_scanner.py +754 -0
- tools/harness/__init__.py +6 -0
- tools/harness/exit_criteria_evaluator.py +231 -0
- tools/harness/maturity_assessor.py +347 -0
- tools/harness/scaffold_harness.py +416 -0
- tools/harness/trace_analyzer.py +281 -0
- tools/infra/__init__.py +1 -0
- tools/infra/ansible_generator.py +867 -0
- tools/infra/dockerfile_generator.py +359 -0
- tools/infra/infra_status.py +384 -0
- tools/infra/ironbank_metadata_generator.py +403 -0
- tools/infra/k8s_generator.py +1000 -0
- tools/infra/pipeline_generator.py +830 -0
- tools/infra/rollback.py +389 -0
- tools/infra/terraform_generator.py +1140 -0
- tools/infra/terraform_generator_azure.py +1252 -0
- tools/infra/terraform_generator_gcp.py +951 -0
- tools/infra/terraform_generator_ibm.py +359 -0
- tools/infra/terraform_generator_oci.py +918 -0
- tools/infra/terraform_generator_onprem.py +318 -0
- tools/knowledge/__init__.py +1 -0
- tools/knowledge/knowledge_ingest.py +281 -0
- tools/knowledge/pattern_detector.py +681 -0
- tools/knowledge/recommendation_engine.py +449 -0
- tools/knowledge/self_heal_analyzer.py +492 -0
- tools/knowledge_graph/__init__.py +2 -0
- tools/knowledge_graph/graph_rag.py +498 -0
- tools/knowledge_graph/ingester.py +406 -0
- tools/knowledge_graph/insight_generator.py +369 -0
- tools/knowledge_graph/text_network.py +832 -0
- tools/llm/__init__.py +72 -0
- tools/llm/anthropic_provider.py +170 -0
- tools/llm/azure_openai_provider.py +338 -0
- tools/llm/bedrock_provider.py +315 -0
- tools/llm/embedding_provider.py +438 -0
- tools/llm/gemini_provider.py +381 -0
- tools/llm/ibm_watsonx_provider.py +231 -0
- tools/llm/oci_genai_provider.py +462 -0
- tools/llm/ollama_provider.py +350 -0
- tools/llm/openai_provider.py +225 -0
- tools/llm/prompt_registry.py +447 -0
- tools/llm/provider.py +355 -0
- tools/llm/provider_sdk.py +175 -0
- tools/llm/router.py +1124 -0
- tools/llm/semantic_cache.py +394 -0
- tools/llm/vertex_ai_provider.py +374 -0
- tools/maintenance/__init__.py +2 -0
- tools/maintenance/dependency_scanner.py +1016 -0
- tools/maintenance/maintenance_auditor.py +804 -0
- tools/maintenance/remediation_engine.py +957 -0
- tools/maintenance/vulnerability_checker.py +978 -0
- tools/manifest.md +1066 -0
- tools/marketplace/asset_installer.py +639 -0
- tools/marketplace/feedback_validator.py +359 -0
- tools/marketplace/license_client.py +458 -0
- tools/marketplace/module_crypto.py +544 -0
- tools/marketplace/module_runtime.py +236 -0
- tools/marketplace/token_store.py +264 -0
- tools/mbse/__init__.py +3 -0
- tools/mbse/des_assessor.py +1173 -0
- tools/mbse/des_report_generator.py +787 -0
- tools/mbse/diagram_extractor.py +792 -0
- tools/mbse/digital_thread.py +1650 -0
- tools/mbse/model_code_generator.py +1115 -0
- tools/mbse/model_control_mapper.py +410 -0
- tools/mbse/pi_model_tracker.py +1079 -0
- tools/mbse/reqif_parser.py +1468 -0
- tools/mbse/sync_engine.py +1789 -0
- tools/mbse/thread_heatmap.py +445 -0
- tools/mbse/xmi_parser.py +1558 -0
- tools/mcp/builder_server.py +64 -0
- tools/mcp/compliance_server.py +64 -0
- tools/mcp/connector_forge_server.py +155 -0
- tools/mcp/core_server.py +64 -0
- tools/mcp/devsecops_server.py +11 -0
- tools/mcp/devsecops_zta_server.py +64 -0
- tools/mcp/knowledge_server.py +64 -0
- tools/mcp/monitor_server.py +64 -0
- tools/mcp/ops_server.py +300 -0
- tools/mcp/requirements_analyst_server.py +64 -0
- tools/mcp/requirements_server.py +11 -0
- tools/mcp/security_server.py +64 -0
- tools/mcp/simulation_server.py +64 -0
- tools/mcp/supply_chain_server.py +64 -0
- tools/mcp/tool_registry.py +299 -0
- tools/memory/__init__.py +2 -0
- tools/memory/auto_capture.py +346 -0
- tools/memory/embed_memory.py +157 -0
- tools/memory/history_compressor.py +334 -0
- tools/memory/hybrid_search.py +235 -0
- tools/memory/maintenance_cron.py +288 -0
- tools/memory/memory_consolidation.py +439 -0
- tools/memory/memory_db.py +132 -0
- tools/memory/memory_read.py +101 -0
- tools/memory/memory_write.py +221 -0
- tools/memory/semantic_search.py +138 -0
- tools/memory/time_decay.py +434 -0
- tools/missions/__init__.py +2 -0
- tools/missions/mission_engine.py +459 -0
- tools/monitor/__init__.py +1 -0
- tools/monitor/alert_correlator.py +486 -0
- tools/monitor/auto_resolver.py +603 -0
- tools/monitor/health_checker.py +507 -0
- tools/monitor/heartbeat_daemon.py +779 -0
- tools/monitor/log_analyzer.py +507 -0
- tools/monitor/metric_collector.py +484 -0
- tools/mosa/__init__.py +10 -0
- tools/mosa/icd_generator.py +358 -0
- tools/mosa/modular_design_analyzer.py +682 -0
- tools/mosa/mosa_code_enforcer.py +348 -0
- tools/mosa/tsp_generator.py +265 -0
- tools/observability/__init__.py +100 -0
- tools/observability/genai_attributes.py +88 -0
- tools/observability/instrumentation.py +140 -0
- tools/observability/mlflow_exporter.py +193 -0
- tools/observability/otel_tracer.py +168 -0
- tools/observability/provenance/__init__.py +3 -0
- tools/observability/provenance/prov_recorder.py +322 -0
- tools/observability/shap/__init__.py +3 -0
- tools/observability/shap/agent_shap.py +274 -0
- tools/observability/sqlite_tracer.py +360 -0
- tools/observability/trace_context.py +205 -0
- tools/observability/tracer.py +230 -0
- tools/orchestration/__init__.py +1 -0
- tools/orchestration/peer_channels.py +254 -0
- tools/orchestration/saga_coordinator.py +390 -0
- tools/project/__init__.py +1 -0
- tools/project/manifest_loader.py +418 -0
- tools/project/project_create.py +350 -0
- tools/project/project_list.py +171 -0
- tools/project/project_scaffold.py +1715 -0
- tools/project/project_status.py +478 -0
- tools/project/session_context_builder.py +752 -0
- tools/project/validate_manifest.py +54 -0
- tools/rag/corrective_rag.py +582 -0
- tools/rag/source_registry.py +482 -0
- tools/requirements/__init__.py +1 -0
- tools/requirements/ai_governance_scorer.py +207 -0
- tools/requirements/boundary_analyzer.py +1281 -0
- tools/requirements/clarification_engine.py +605 -0
- tools/requirements/complexity_scorer.py +369 -0
- tools/requirements/consistency_analyzer.py +789 -0
- tools/requirements/constitution_manager.py +592 -0
- tools/requirements/decomposition_engine.py +764 -0
- tools/requirements/document_extractor.py +1002 -0
- tools/requirements/elicitation_techniques.py +508 -0
- tools/requirements/gap_detector.py +260 -0
- tools/requirements/intake_engine.py +2175 -0
- tools/requirements/prd_generator.py +839 -0
- tools/requirements/prd_validator.py +584 -0
- tools/requirements/readiness_scorer.py +302 -0
- tools/requirements/spec_organizer.py +1015 -0
- tools/requirements/spec_quality_checker.py +1083 -0
- tools/requirements/traceability_builder.py +566 -0
- tools/research/__init__.py +3 -0
- tools/research/academic_scanner.py +130 -0
- tools/research/build_buy_analyzer.py +229 -0
- tools/research/challenge_scorer.py +280 -0
- tools/research/community_scanner.py +174 -0
- tools/research/cross_engine_bridge.py +124 -0
- tools/research/dossier_generator.py +305 -0
- tools/research/landscape_scanner.py +315 -0
- tools/research/regulatory_scanner.py +248 -0
- tools/research/research_manager.py +469 -0
- tools/research/source_scanner.py +150 -0
- tools/research/vertical_loader.py +118 -0
- tools/saas/__init__.py +0 -0
- tools/saas/licensing/__init__.py +0 -0
- tools/saas/licensing/license_validator.py +345 -0
- tools/scaffold/__init__.py +2 -0
- tools/scaffold/golden_path.py +504 -0
- tools/security/__init__.py +1 -0
- tools/security/agent_output_validator.py +330 -0
- tools/security/agent_trust_scorer.py +652 -0
- tools/security/ai_bom_generator.py +718 -0
- tools/security/ai_telemetry_logger.py +469 -0
- tools/security/atlas_red_team.py +541 -0
- tools/security/code_pattern_scanner.py +382 -0
- tools/security/confabulation_detector.py +265 -0
- tools/security/container_scanner.py +489 -0
- tools/security/dependency_auditor.py +942 -0
- tools/security/endpoint_security_scanner.py +626 -0
- tools/security/mcp_tool_authorizer.py +242 -0
- tools/security/output_verifier.py +427 -0
- tools/security/prompt_injection_detector.py +737 -0
- tools/security/sast_runner.py +946 -0
- tools/security/secret_detector.py +376 -0
- tools/security/threat_modeler.py +678 -0
- tools/security/tool_chain_validator.py +357 -0
- tools/security/vuln_scanner.py +536 -0
- tools/simulation/__init__.py +2 -0
- tools/simulation/ato_simulator.py +517 -0
- tools/simulation/coa_generator.py +1539 -0
- tools/simulation/monte_carlo.py +745 -0
- tools/simulation/scenario_manager.py +1060 -0
- tools/simulation/simulation_engine.py +1091 -0
- tools/simulator/__init__.py +2 -0
- tools/simulator/sim_runner.py +272 -0
- tools/supply_chain/__init__.py +2 -0
- tools/supply_chain/cve_triager.py +690 -0
- tools/supply_chain/dependency_graph.py +630 -0
- tools/supply_chain/isa_manager.py +526 -0
- tools/supply_chain/scrm_assessor.py +531 -0
- tools/supply_chain/slsa_verifier.py +473 -0
- tools/testing/__init__.py +2 -0
- tools/testing/acceptance_validator.py +411 -0
- tools/testing/api_surface_extractor.py +749 -0
- tools/testing/claude_dir_validator.py +831 -0
- tools/testing/data_types.py +199 -0
- tools/testing/e2e_runner.py +715 -0
- tools/testing/fuzz_cli.py +306 -0
- tools/testing/health_check.py +483 -0
- tools/testing/platform_check.py +143 -0
- tools/testing/production_audit.py +1836 -0
- tools/testing/production_remediate.py +803 -0
- tools/testing/screenshot_validator.py +538 -0
- tools/testing/smoke_test.py +283 -0
- tools/testing/test_agent_models.py +117 -0
- tools/testing/test_orchestrator.py +957 -0
- tools/testing/utils.py +229 -0
- tools/writeguard/__init__.py +1 -0
- tools/writeguard/main.py +1 -0
- tools/writing/__init__.py +7 -0
- tools/writing/ai_content_detector.py +316 -0
- tools/writing/analysis_engine.py +454 -0
- tools/writing/batch_analyzer.py +276 -0
- tools/writing/coherence_analyzer.py +221 -0
- tools/writing/govcon_bridge.py +509 -0
- tools/writing/grammar_checker.py +270 -0
- tools/writing/plagiarism_detector.py +106 -0
- tools/writing/readability_scorer.py +201 -0
- tools/writing/rewriter.py +96 -0
- tools/writing/signal_registrar.py +167 -0
- tools/writing/snippet_manager.py +276 -0
- tools/writing/style_enforcer.py +220 -0
- tools/writing/style_guide_manager.py +438 -0
- tools/writing/tone_profiler.py +168 -0
|
@@ -0,0 +1,1795 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# CUI // SP-CTI
|
|
3
|
+
# Controlled by: Department of Defense
|
|
4
|
+
# CUI Category: CTI
|
|
5
|
+
# Distribution: D
|
|
6
|
+
# POC: ICDEV System Administrator
|
|
7
|
+
"""FedRAMP Moderate/High assessment engine for ICDEV.
|
|
8
|
+
|
|
9
|
+
Loads FedRAMP baseline controls from fedramp_moderate_baseline.json or
|
|
10
|
+
fedramp_high_baseline.json, performs automated checks per control family,
|
|
11
|
+
inherits NIST 800-53 implementations via the crosswalk engine, stores
|
|
12
|
+
results in the fedramp_assessments table, evaluates FedRAMP readiness
|
|
13
|
+
gates, applies CUI markings, and logs audit events.
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
python tools/compliance/fedramp_assessor.py --project-id proj-123
|
|
17
|
+
python tools/compliance/fedramp_assessor.py --project-id proj-123 --baseline high
|
|
18
|
+
python tools/compliance/fedramp_assessor.py --project-id proj-123 --project-dir /path/to/project
|
|
19
|
+
python tools/compliance/fedramp_assessor.py --project-id proj-123 --gate
|
|
20
|
+
python tools/compliance/fedramp_assessor.py --project-id proj-123 --output-dir /path/to/output
|
|
21
|
+
python tools/compliance/fedramp_assessor.py --project-id proj-123 --json
|
|
22
|
+
|
|
23
|
+
Databases:
|
|
24
|
+
- data/icdev.db: fedramp_assessments, projects, project_controls, audit_trail
|
|
25
|
+
|
|
26
|
+
See also:
|
|
27
|
+
- tools/compliance/crosswalk_engine.py (inherit NIST 800-53 implementations)
|
|
28
|
+
- tools/compliance/classification_manager.py (CUI/SECRET markings)
|
|
29
|
+
- tools/compliance/fedramp_report_generator.py (report generation)
|
|
30
|
+
- context/compliance/fedramp_moderate_baseline.json
|
|
31
|
+
- context/compliance/fedramp_high_baseline.json
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import argparse
|
|
35
|
+
import json
|
|
36
|
+
import os
|
|
37
|
+
import re
|
|
38
|
+
import sys
|
|
39
|
+
from datetime import datetime, timezone
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
from tools.db.storage import get_connection
|
|
42
|
+
DB_PATH = None # Storage layer handles path resolution (D-DB-20)
|
|
43
|
+
|
|
44
|
+
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
|
45
|
+
FEDRAMP_MODERATE_PATH = BASE_DIR / "context" / "compliance" / "fedramp_moderate_baseline.json"
|
|
46
|
+
FEDRAMP_HIGH_PATH = BASE_DIR / "context" / "compliance" / "fedramp_high_baseline.json"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# -----------------------------------------------------------------
|
|
50
|
+
# Database helpers
|
|
51
|
+
# -----------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _get_project(conn, project_id):
|
|
55
|
+
"""Load project data from the projects table."""
|
|
56
|
+
row = conn.execute(
|
|
57
|
+
"SELECT * FROM projects WHERE id = ?", (project_id,)
|
|
58
|
+
).fetchone()
|
|
59
|
+
if not row:
|
|
60
|
+
raise ValueError(f"Project '{project_id}' not found.")
|
|
61
|
+
return dict(row)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _log_audit_event(conn, project_id, action, details, file_path=None):
|
|
65
|
+
"""Log an audit trail event (append-only, NIST AU compliant)."""
|
|
66
|
+
try:
|
|
67
|
+
conn.execute(
|
|
68
|
+
"""INSERT INTO audit_trail
|
|
69
|
+
(project_id, event_type, actor, action, details,
|
|
70
|
+
affected_files, classification)
|
|
71
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)""",
|
|
72
|
+
(
|
|
73
|
+
project_id,
|
|
74
|
+
"fedramp_assessed",
|
|
75
|
+
"icdev-compliance-engine",
|
|
76
|
+
action,
|
|
77
|
+
json.dumps(details),
|
|
78
|
+
json.dumps([str(file_path)] if file_path else []),
|
|
79
|
+
"CUI",
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
conn.commit()
|
|
83
|
+
except Exception as e:
|
|
84
|
+
print(f"Warning: Could not log audit event: {e}", file=sys.stderr)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# -----------------------------------------------------------------
|
|
88
|
+
# Configuration helpers
|
|
89
|
+
# -----------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
def _load_cui_config():
|
|
92
|
+
"""Load CUI marking configuration via classification_manager or fallback."""
|
|
93
|
+
try:
|
|
94
|
+
sys.path.insert(0, str(BASE_DIR / "tools" / "compliance"))
|
|
95
|
+
from classification_manager import get_document_banner
|
|
96
|
+
banners = get_document_banner("CUI")
|
|
97
|
+
return {
|
|
98
|
+
"document_header": banners.get("header", "CUI // SP-CTI"),
|
|
99
|
+
"document_footer": banners.get("footer", "CUI // SP-CTI"),
|
|
100
|
+
}
|
|
101
|
+
except (ImportError, Exception):
|
|
102
|
+
return {
|
|
103
|
+
"document_header": (
|
|
104
|
+
"////////////////////////////////////////////////////////////////////\n"
|
|
105
|
+
"CONTROLLED UNCLASSIFIED INFORMATION (CUI) // SP-CTI\n"
|
|
106
|
+
"Distribution: Distribution D -- Authorized DoD Personnel Only\n"
|
|
107
|
+
"////////////////////////////////////////////////////////////////////"
|
|
108
|
+
),
|
|
109
|
+
"document_footer": (
|
|
110
|
+
"////////////////////////////////////////////////////////////////////\n"
|
|
111
|
+
"CUI // SP-CTI | Department of Defense\n"
|
|
112
|
+
"////////////////////////////////////////////////////////////////////"
|
|
113
|
+
),
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def load_fedramp_baseline(baseline="moderate"):
|
|
118
|
+
"""Load FedRAMP baseline catalog from JSON.
|
|
119
|
+
|
|
120
|
+
Args:
|
|
121
|
+
baseline: "moderate" or "high".
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Tuple of (metadata dict, controls list).
|
|
125
|
+
|
|
126
|
+
Raises:
|
|
127
|
+
FileNotFoundError: If baseline JSON file does not exist.
|
|
128
|
+
ValueError: If baseline is not "moderate" or "high".
|
|
129
|
+
"""
|
|
130
|
+
baseline_lower = baseline.lower()
|
|
131
|
+
if baseline_lower not in ("moderate", "high"):
|
|
132
|
+
raise ValueError(
|
|
133
|
+
f"Invalid baseline '{baseline}'. Must be 'moderate' or 'high'."
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if baseline_lower == "moderate":
|
|
137
|
+
catalog_path = FEDRAMP_MODERATE_PATH
|
|
138
|
+
else:
|
|
139
|
+
catalog_path = FEDRAMP_HIGH_PATH
|
|
140
|
+
|
|
141
|
+
if not catalog_path.exists():
|
|
142
|
+
raise FileNotFoundError(
|
|
143
|
+
f"FedRAMP {baseline} baseline file not found: {catalog_path}\n"
|
|
144
|
+
f"Expected: context/compliance/fedramp_{baseline_lower}_baseline.json"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
with open(catalog_path, "r", encoding="utf-8") as f:
|
|
148
|
+
data = json.load(f)
|
|
149
|
+
|
|
150
|
+
metadata = data.get("metadata", {})
|
|
151
|
+
controls = data.get("controls", [])
|
|
152
|
+
return metadata, controls
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _try_inherit_nist_implementations(project_id, controls, db_path=None):
|
|
156
|
+
"""Try to inherit NIST 800-53 implementations via the crosswalk engine.
|
|
157
|
+
|
|
158
|
+
For each FedRAMP control, checks if the underlying NIST 800-53 control
|
|
159
|
+
has been implemented in the project_controls table.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
project_id: The project identifier.
|
|
163
|
+
controls: List of FedRAMP baseline control dicts.
|
|
164
|
+
db_path: Optional database path override.
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Dict mapping FedRAMP control ID -> {"inherited": bool, "nist_status": str}
|
|
168
|
+
"""
|
|
169
|
+
inherited = {}
|
|
170
|
+
|
|
171
|
+
try:
|
|
172
|
+
conn = get_connection(db_path=db_path)
|
|
173
|
+
rows = conn.execute(
|
|
174
|
+
"""SELECT control_id, implementation_status
|
|
175
|
+
FROM project_controls
|
|
176
|
+
WHERE project_id = ?""",
|
|
177
|
+
(project_id,),
|
|
178
|
+
).fetchall()
|
|
179
|
+
conn.close()
|
|
180
|
+
|
|
181
|
+
nist_statuses = {}
|
|
182
|
+
for row in rows:
|
|
183
|
+
nist_statuses[row["control_id"].upper()] = row["implementation_status"]
|
|
184
|
+
|
|
185
|
+
for ctrl in controls:
|
|
186
|
+
nist_id = ctrl.get("nist_control_id", "").upper()
|
|
187
|
+
if nist_id in nist_statuses:
|
|
188
|
+
status = nist_statuses[nist_id]
|
|
189
|
+
inherited[ctrl["id"]] = {
|
|
190
|
+
"inherited": status in ("implemented", "partially_implemented"),
|
|
191
|
+
"nist_status": status,
|
|
192
|
+
}
|
|
193
|
+
else:
|
|
194
|
+
inherited[ctrl["id"]] = {
|
|
195
|
+
"inherited": False,
|
|
196
|
+
"nist_status": "not_mapped",
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
except Exception as e:
|
|
200
|
+
print(
|
|
201
|
+
f"Warning: Could not inherit NIST implementations: {e}",
|
|
202
|
+
file=sys.stderr,
|
|
203
|
+
)
|
|
204
|
+
for ctrl in controls:
|
|
205
|
+
inherited[ctrl["id"]] = {
|
|
206
|
+
"inherited": False,
|
|
207
|
+
"nist_status": "not_available",
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return inherited
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
# -----------------------------------------------------------------
|
|
214
|
+
# Auto-check helper: walk project files matching extensions
|
|
215
|
+
# -----------------------------------------------------------------
|
|
216
|
+
|
|
217
|
+
def _scan_files(project_dir, extensions, patterns, threshold=1):
|
|
218
|
+
"""Scan project files for regex patterns.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
project_dir: Root directory to walk.
|
|
222
|
+
extensions: Tuple of file extensions to include.
|
|
223
|
+
patterns: List of regex patterns to search for.
|
|
224
|
+
threshold: Minimum number of files with matches to consider satisfied.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Tuple of (matched_files, total_scanned).
|
|
228
|
+
"""
|
|
229
|
+
matched_files = []
|
|
230
|
+
total_scanned = 0
|
|
231
|
+
for root, _, files in os.walk(project_dir):
|
|
232
|
+
for fname in files:
|
|
233
|
+
if not fname.endswith(extensions):
|
|
234
|
+
continue
|
|
235
|
+
fpath = os.path.join(root, fname)
|
|
236
|
+
total_scanned += 1
|
|
237
|
+
try:
|
|
238
|
+
with open(fpath, "r", encoding="utf-8", errors="ignore") as f:
|
|
239
|
+
content = f.read()
|
|
240
|
+
for pattern in patterns:
|
|
241
|
+
if re.search(pattern, content, re.IGNORECASE):
|
|
242
|
+
matched_files.append(fpath)
|
|
243
|
+
break
|
|
244
|
+
except Exception:
|
|
245
|
+
continue
|
|
246
|
+
return matched_files, total_scanned
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def _dir_or_file_exists(project_dir, dir_names=None, glob_patterns=None):
|
|
250
|
+
"""Check if specific directories or file globs exist under project_dir.
|
|
251
|
+
|
|
252
|
+
Args:
|
|
253
|
+
project_dir: Root directory to search.
|
|
254
|
+
dir_names: List of directory names to look for.
|
|
255
|
+
glob_patterns: List of glob patterns to match files.
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
List of found paths.
|
|
259
|
+
"""
|
|
260
|
+
found = []
|
|
261
|
+
project_path = Path(project_dir)
|
|
262
|
+
|
|
263
|
+
if dir_names:
|
|
264
|
+
for dname in dir_names:
|
|
265
|
+
candidate = project_path / dname
|
|
266
|
+
if candidate.is_dir():
|
|
267
|
+
found.append(str(candidate))
|
|
268
|
+
for child in project_path.rglob(dname):
|
|
269
|
+
if child.is_dir() and str(child) not in found:
|
|
270
|
+
found.append(str(child))
|
|
271
|
+
|
|
272
|
+
if glob_patterns:
|
|
273
|
+
for gp in glob_patterns:
|
|
274
|
+
for match in project_path.rglob(gp):
|
|
275
|
+
if str(match) not in found:
|
|
276
|
+
found.append(str(match))
|
|
277
|
+
|
|
278
|
+
return found
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# -----------------------------------------------------------------
|
|
282
|
+
# Auto-check functions (15 checks)
|
|
283
|
+
# Each returns a dict:
|
|
284
|
+
# {"status": "satisfied"|"other_than_satisfied"|"not_applicable",
|
|
285
|
+
# "evidence": "description of what was found",
|
|
286
|
+
# "details": "specifics"}
|
|
287
|
+
# -----------------------------------------------------------------
|
|
288
|
+
|
|
289
|
+
def _check_access_control(project_dir):
|
|
290
|
+
"""AC family: Check for RBAC, least privilege, session management patterns."""
|
|
291
|
+
patterns = [
|
|
292
|
+
r"@login_required|@permission_required|@requires_auth",
|
|
293
|
+
r"@Secured|@PreAuthorize|@RolesAllowed",
|
|
294
|
+
r"role_required|check_permission|has_permission",
|
|
295
|
+
r"\bRBAC\b|role.based.access",
|
|
296
|
+
r"RoleBinding|ClusterRole|ClusterRoleBinding",
|
|
297
|
+
r"least.privilege|minimum.privilege|principle.of.least",
|
|
298
|
+
r"session_timeout|SESSION_EXPIRE|session.maxAge",
|
|
299
|
+
r"from\s+flask_login|from\s+django\.contrib\.auth",
|
|
300
|
+
]
|
|
301
|
+
extensions = (".py", ".yaml", ".yml", ".js", ".ts", ".java", ".go")
|
|
302
|
+
matched, total = _scan_files(project_dir, extensions, patterns)
|
|
303
|
+
|
|
304
|
+
if total == 0:
|
|
305
|
+
return {
|
|
306
|
+
"status": "other_than_satisfied",
|
|
307
|
+
"evidence": "No source files found to assess for access control.",
|
|
308
|
+
"details": "Project directory lacks applicable source files.",
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if len(matched) >= 2:
|
|
312
|
+
return {
|
|
313
|
+
"status": "satisfied",
|
|
314
|
+
"evidence": (
|
|
315
|
+
f"Access control patterns (RBAC, least privilege, session "
|
|
316
|
+
f"management) found in {len(matched)} file(s)."
|
|
317
|
+
),
|
|
318
|
+
"details": "; ".join(os.path.basename(f) for f in matched[:5]),
|
|
319
|
+
}
|
|
320
|
+
elif len(matched) == 1:
|
|
321
|
+
return {
|
|
322
|
+
"status": "other_than_satisfied",
|
|
323
|
+
"evidence": (
|
|
324
|
+
f"Access control patterns found in only 1 file: "
|
|
325
|
+
f"{os.path.basename(matched[0])}."
|
|
326
|
+
),
|
|
327
|
+
"details": (
|
|
328
|
+
"Minimal access control detected. FedRAMP requires "
|
|
329
|
+
"comprehensive RBAC, least privilege, and session management."
|
|
330
|
+
),
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return {
|
|
334
|
+
"status": "other_than_satisfied",
|
|
335
|
+
"evidence": "No access control patterns detected (RBAC, least privilege, session mgmt).",
|
|
336
|
+
"details": (
|
|
337
|
+
"Expected: @login_required, role_required, RBAC, RoleBinding, "
|
|
338
|
+
"session_timeout, or least-privilege patterns."
|
|
339
|
+
),
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def _check_audit_logging(project_dir):
|
|
344
|
+
"""AU family: Check for logging config, audit trail, log retention."""
|
|
345
|
+
event_type_patterns = [
|
|
346
|
+
(r"login|auth.*log|authentication.*log", "authentication_logging"),
|
|
347
|
+
(r"access.*log|access_log|request.*log", "access_logging"),
|
|
348
|
+
(r"change.*log|change_log|modification.*log|update.*log", "change_logging"),
|
|
349
|
+
(r"error.*log|error_log|exception.*log", "error_logging"),
|
|
350
|
+
(r"security.*event|security.*log|security_event", "security_logging"),
|
|
351
|
+
]
|
|
352
|
+
extensions = (".py", ".js", ".ts", ".java", ".yaml", ".yml")
|
|
353
|
+
found_types = set()
|
|
354
|
+
evidence_files = []
|
|
355
|
+
|
|
356
|
+
for root, _, files in os.walk(project_dir):
|
|
357
|
+
for fname in files:
|
|
358
|
+
if not fname.endswith(extensions):
|
|
359
|
+
continue
|
|
360
|
+
fpath = os.path.join(root, fname)
|
|
361
|
+
try:
|
|
362
|
+
with open(fpath, "r", encoding="utf-8", errors="ignore") as f:
|
|
363
|
+
content = f.read()
|
|
364
|
+
for pattern, event_type in event_type_patterns:
|
|
365
|
+
if re.search(pattern, content, re.IGNORECASE):
|
|
366
|
+
found_types.add(event_type)
|
|
367
|
+
if fpath not in evidence_files:
|
|
368
|
+
evidence_files.append(fpath)
|
|
369
|
+
except Exception:
|
|
370
|
+
continue
|
|
371
|
+
|
|
372
|
+
# Check for structured logging patterns
|
|
373
|
+
struct_patterns = [
|
|
374
|
+
r"audit_trail|AuditTrail",
|
|
375
|
+
r"logging\.getLogger|getLogger",
|
|
376
|
+
r"structlog|structured.log",
|
|
377
|
+
r"log_retention|retention_days|retention_period",
|
|
378
|
+
]
|
|
379
|
+
struct_matched, _ = _scan_files(project_dir, extensions, struct_patterns)
|
|
380
|
+
if struct_matched:
|
|
381
|
+
found_types.add("structured_logging")
|
|
382
|
+
for sf in struct_matched:
|
|
383
|
+
if sf not in evidence_files:
|
|
384
|
+
evidence_files.append(sf)
|
|
385
|
+
|
|
386
|
+
count = len(found_types)
|
|
387
|
+
if count >= 3:
|
|
388
|
+
return {
|
|
389
|
+
"status": "satisfied",
|
|
390
|
+
"evidence": (
|
|
391
|
+
f"Comprehensive audit logging: {count} distinct log event "
|
|
392
|
+
f"types across {len(evidence_files)} file(s)."
|
|
393
|
+
),
|
|
394
|
+
"details": (
|
|
395
|
+
f"Event types: {', '.join(sorted(found_types))}. "
|
|
396
|
+
f"Files: {'; '.join(os.path.basename(f) for f in evidence_files[:5])}"
|
|
397
|
+
),
|
|
398
|
+
}
|
|
399
|
+
elif count >= 1:
|
|
400
|
+
return {
|
|
401
|
+
"status": "other_than_satisfied",
|
|
402
|
+
"evidence": (
|
|
403
|
+
f"Partial audit logging: {count} distinct log event "
|
|
404
|
+
f"type(s). FedRAMP requires comprehensive audit logging "
|
|
405
|
+
f"with retention policies."
|
|
406
|
+
),
|
|
407
|
+
"details": f"Event types: {', '.join(sorted(found_types))}.",
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
return {
|
|
411
|
+
"status": "other_than_satisfied",
|
|
412
|
+
"evidence": "No audit logging patterns detected in source files.",
|
|
413
|
+
"details": (
|
|
414
|
+
"Expected: authentication logging, access logging, change logging, "
|
|
415
|
+
"error logging, or security event logging with retention policies."
|
|
416
|
+
),
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def _check_identification_auth(project_dir):
|
|
421
|
+
"""IA family: Check for MFA, password policy, PKI/CAC integration."""
|
|
422
|
+
mfa_patterns = [
|
|
423
|
+
r"\bMFA\b|multi.factor|MultiFactor",
|
|
424
|
+
r"\b2FA\b|two.factor|TwoFactor",
|
|
425
|
+
r"\bTOTP\b|totp|time.based.one.time",
|
|
426
|
+
r"\bFIDO\b|fido2|WebAuthn|webauthn",
|
|
427
|
+
r"authenticator|Authenticator",
|
|
428
|
+
r"otp_secret|otp_verify|verify_otp",
|
|
429
|
+
r"\bPKI\b|pki_auth|certificate.auth",
|
|
430
|
+
r"\bCAC\b|cac_auth|smart.card",
|
|
431
|
+
r"PIV|piv_auth",
|
|
432
|
+
]
|
|
433
|
+
password_patterns = [
|
|
434
|
+
r"password_policy|PASSWORD_MIN_LENGTH|password.complexity",
|
|
435
|
+
r"password.*history|password.*reuse|password.*rotation",
|
|
436
|
+
r"bcrypt|scrypt|argon2|pbkdf2|PBKDF2",
|
|
437
|
+
r"password.*hash|hash.*password",
|
|
438
|
+
]
|
|
439
|
+
extensions = (".py", ".js", ".ts", ".java", ".yaml", ".yml", ".conf")
|
|
440
|
+
mfa_matched, total = _scan_files(project_dir, extensions, mfa_patterns)
|
|
441
|
+
pwd_matched, _ = _scan_files(project_dir, extensions, password_patterns)
|
|
442
|
+
|
|
443
|
+
if total == 0:
|
|
444
|
+
return {
|
|
445
|
+
"status": "other_than_satisfied",
|
|
446
|
+
"evidence": "No source or config files found to assess.",
|
|
447
|
+
"details": "Project directory lacks applicable files.",
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
both = bool(mfa_matched) and bool(pwd_matched)
|
|
451
|
+
either = bool(mfa_matched) or bool(pwd_matched)
|
|
452
|
+
|
|
453
|
+
if both:
|
|
454
|
+
return {
|
|
455
|
+
"status": "satisfied",
|
|
456
|
+
"evidence": (
|
|
457
|
+
f"MFA/PKI patterns found in {len(mfa_matched)} file(s) and "
|
|
458
|
+
f"password policy patterns in {len(pwd_matched)} file(s)."
|
|
459
|
+
),
|
|
460
|
+
"details": (
|
|
461
|
+
"MFA: "
|
|
462
|
+
+ "; ".join(os.path.basename(f) for f in mfa_matched[:3])
|
|
463
|
+
+ " | Password: "
|
|
464
|
+
+ "; ".join(os.path.basename(f) for f in pwd_matched[:3])
|
|
465
|
+
),
|
|
466
|
+
}
|
|
467
|
+
elif either:
|
|
468
|
+
found_type = "MFA/PKI" if mfa_matched else "password policy"
|
|
469
|
+
missing_type = "password policy" if mfa_matched else "MFA/PKI"
|
|
470
|
+
return {
|
|
471
|
+
"status": "other_than_satisfied",
|
|
472
|
+
"evidence": (
|
|
473
|
+
f"Partial IA: {found_type} patterns found but {missing_type} "
|
|
474
|
+
f"patterns not detected."
|
|
475
|
+
),
|
|
476
|
+
"details": (
|
|
477
|
+
"FedRAMP requires both MFA/PKI and password policy enforcement."
|
|
478
|
+
),
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return {
|
|
482
|
+
"status": "other_than_satisfied",
|
|
483
|
+
"evidence": "No MFA, PKI/CAC, or password policy patterns detected.",
|
|
484
|
+
"details": (
|
|
485
|
+
"Expected: MFA, 2FA, TOTP, FIDO, PKI, CAC, password complexity, "
|
|
486
|
+
"bcrypt/argon2 hashing patterns."
|
|
487
|
+
),
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
def _check_system_communications(project_dir):
|
|
492
|
+
"""SC family: Check for TLS, encryption config, network protection."""
|
|
493
|
+
secure_patterns = [
|
|
494
|
+
r"TLS\s*1\.[23]|TLSv1_[23]|tls_version.*1\.[23]",
|
|
495
|
+
r"TLS_1_2|TLS_1_3|PROTOCOL_TLS",
|
|
496
|
+
r"\bHTTPS\b|https://",
|
|
497
|
+
r"ssl_context|SSLContext",
|
|
498
|
+
r"mTLS|mutual.TLS",
|
|
499
|
+
r"strong.cipher|ECDHE|AES.GCM|CHACHA20",
|
|
500
|
+
]
|
|
501
|
+
insecure_patterns = [
|
|
502
|
+
r"SSLv2|SSLv3|PROTOCOL_SSLv",
|
|
503
|
+
r"TLSv1_0|TLS\s*1\.0|TLS_1_0",
|
|
504
|
+
r"TLSv1_1|TLS\s*1\.1|TLS_1_1",
|
|
505
|
+
r"verify\s*=\s*False|CERT_NONE|check_hostname\s*=\s*False",
|
|
506
|
+
r"ssl_verify.*false|tls_verify.*false",
|
|
507
|
+
]
|
|
508
|
+
extensions = (".py", ".yaml", ".yml", ".conf", ".tf", ".json")
|
|
509
|
+
|
|
510
|
+
secure_matched, total = _scan_files(project_dir, extensions, secure_patterns)
|
|
511
|
+
insecure_matched, _ = _scan_files(project_dir, extensions, insecure_patterns)
|
|
512
|
+
|
|
513
|
+
if total == 0:
|
|
514
|
+
return {
|
|
515
|
+
"status": "other_than_satisfied",
|
|
516
|
+
"evidence": "No configuration or source files found to assess.",
|
|
517
|
+
"details": "Project directory lacks files with expected extensions.",
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if secure_matched and not insecure_matched:
|
|
521
|
+
return {
|
|
522
|
+
"status": "satisfied",
|
|
523
|
+
"evidence": (
|
|
524
|
+
f"TLS/encryption patterns found in {len(secure_matched)} "
|
|
525
|
+
f"file(s) with no insecure protocol patterns detected."
|
|
526
|
+
),
|
|
527
|
+
"details": "; ".join(
|
|
528
|
+
os.path.basename(f) for f in secure_matched[:5]
|
|
529
|
+
),
|
|
530
|
+
}
|
|
531
|
+
elif secure_matched and insecure_matched:
|
|
532
|
+
return {
|
|
533
|
+
"status": "other_than_satisfied",
|
|
534
|
+
"evidence": (
|
|
535
|
+
f"TLS patterns found in {len(secure_matched)} file(s), but "
|
|
536
|
+
f"insecure patterns also in {len(insecure_matched)} file(s)."
|
|
537
|
+
),
|
|
538
|
+
"details": (
|
|
539
|
+
"Insecure: "
|
|
540
|
+
+ "; ".join(os.path.basename(f) for f in insecure_matched[:5])
|
|
541
|
+
+ ". Remove SSLv3, TLSv1.0, TLSv1.1, and verify=False usage."
|
|
542
|
+
),
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return {
|
|
546
|
+
"status": "other_than_satisfied",
|
|
547
|
+
"evidence": "No TLS/encryption configuration patterns detected.",
|
|
548
|
+
"details": (
|
|
549
|
+
"Expected: TLS 1.2+, FIPS-validated ciphers, SSLContext, mTLS. "
|
|
550
|
+
"FedRAMP requires FIPS 140-2 validated cryptographic modules."
|
|
551
|
+
),
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
def _check_config_management(project_dir):
|
|
556
|
+
"""CM family: Check for IaC, config files, baseline configs."""
|
|
557
|
+
iac_found = _dir_or_file_exists(
|
|
558
|
+
project_dir,
|
|
559
|
+
dir_names=["terraform", "ansible", "cloudformation", "pulumi"],
|
|
560
|
+
glob_patterns=[
|
|
561
|
+
"*.tf", "*.tfvars",
|
|
562
|
+
"playbook*.yml", "playbook*.yaml",
|
|
563
|
+
"ansible.cfg",
|
|
564
|
+
"*.cfn.yml", "*.cfn.yaml", "*.cfn.json",
|
|
565
|
+
"docker-compose*.yml", "docker-compose*.yaml",
|
|
566
|
+
],
|
|
567
|
+
)
|
|
568
|
+
|
|
569
|
+
config_patterns = [
|
|
570
|
+
r"version_control|git.*config|\.gitignore",
|
|
571
|
+
r"baseline.*config|config.*baseline|hardened.*config",
|
|
572
|
+
r"change.*management|change_request|change_control",
|
|
573
|
+
]
|
|
574
|
+
extensions = (".py", ".yaml", ".yml", ".conf", ".json", ".md")
|
|
575
|
+
config_matched, _ = _scan_files(project_dir, extensions, config_patterns)
|
|
576
|
+
|
|
577
|
+
# Check for CI/CD config (indicates config management discipline)
|
|
578
|
+
ci_found = _dir_or_file_exists(
|
|
579
|
+
project_dir,
|
|
580
|
+
glob_patterns=[
|
|
581
|
+
".gitlab-ci.yml", ".github/workflows/*.yml",
|
|
582
|
+
"Jenkinsfile", "azure-pipelines.yml",
|
|
583
|
+
".circleci/config.yml",
|
|
584
|
+
],
|
|
585
|
+
)
|
|
586
|
+
|
|
587
|
+
all_evidence = list(set(iac_found + config_matched + ci_found))
|
|
588
|
+
if len(all_evidence) >= 3:
|
|
589
|
+
return {
|
|
590
|
+
"status": "satisfied",
|
|
591
|
+
"evidence": (
|
|
592
|
+
f"Configuration management artifacts found: "
|
|
593
|
+
f"{len(all_evidence)} item(s) including IaC, configs, and CI/CD."
|
|
594
|
+
),
|
|
595
|
+
"details": "; ".join(os.path.basename(f) for f in all_evidence[:5]),
|
|
596
|
+
}
|
|
597
|
+
elif all_evidence:
|
|
598
|
+
return {
|
|
599
|
+
"status": "other_than_satisfied",
|
|
600
|
+
"evidence": (
|
|
601
|
+
f"Partial configuration management: {len(all_evidence)} "
|
|
602
|
+
f"artifact(s) found."
|
|
603
|
+
),
|
|
604
|
+
"details": (
|
|
605
|
+
"Found: " + "; ".join(os.path.basename(f) for f in all_evidence[:5])
|
|
606
|
+
+ ". FedRAMP requires IaC, baseline configs, and change management."
|
|
607
|
+
),
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
return {
|
|
611
|
+
"status": "other_than_satisfied",
|
|
612
|
+
"evidence": "No configuration management artifacts detected.",
|
|
613
|
+
"details": (
|
|
614
|
+
"Expected: Terraform/Ansible/CloudFormation, baseline configs, "
|
|
615
|
+
"CI/CD pipelines, change management documentation."
|
|
616
|
+
),
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
def _check_incident_response(project_dir):
|
|
621
|
+
"""IR family: Check for IR plan, SECURITY.md, incident procedures."""
|
|
622
|
+
found = _dir_or_file_exists(
|
|
623
|
+
project_dir,
|
|
624
|
+
glob_patterns=[
|
|
625
|
+
"SECURITY.md", "SECURITY.txt", "security.md",
|
|
626
|
+
"incident-response*", "incident_response*",
|
|
627
|
+
"ir-plan*", "ir_plan*",
|
|
628
|
+
],
|
|
629
|
+
)
|
|
630
|
+
found_dirs = _dir_or_file_exists(
|
|
631
|
+
project_dir,
|
|
632
|
+
dir_names=["incident-response", "incident_response", "security"],
|
|
633
|
+
)
|
|
634
|
+
|
|
635
|
+
ir_patterns = [
|
|
636
|
+
r"incident.response|incident.handling|incident.plan",
|
|
637
|
+
r"security.incident|breach.notification",
|
|
638
|
+
r"IR.plan|IR.procedure|IR.contact",
|
|
639
|
+
r"escalation.*procedure|escalation.*matrix",
|
|
640
|
+
]
|
|
641
|
+
extensions = (".py", ".yaml", ".yml", ".md", ".txt", ".json")
|
|
642
|
+
ir_matched, _ = _scan_files(project_dir, extensions, ir_patterns)
|
|
643
|
+
|
|
644
|
+
all_found = list(set(found + found_dirs + ir_matched))
|
|
645
|
+
if len(all_found) >= 2:
|
|
646
|
+
return {
|
|
647
|
+
"status": "satisfied",
|
|
648
|
+
"evidence": (
|
|
649
|
+
f"Incident response artifacts found: {len(all_found)} item(s)."
|
|
650
|
+
),
|
|
651
|
+
"details": "; ".join(os.path.basename(f) for f in all_found[:5]),
|
|
652
|
+
}
|
|
653
|
+
elif all_found:
|
|
654
|
+
return {
|
|
655
|
+
"status": "other_than_satisfied",
|
|
656
|
+
"evidence": (
|
|
657
|
+
f"Partial IR: {len(all_found)} artifact(s). FedRAMP requires "
|
|
658
|
+
f"a formal IR plan with procedures and contacts."
|
|
659
|
+
),
|
|
660
|
+
"details": "; ".join(os.path.basename(f) for f in all_found[:5]),
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
return {
|
|
664
|
+
"status": "other_than_satisfied",
|
|
665
|
+
"evidence": "No incident response artifacts detected.",
|
|
666
|
+
"details": (
|
|
667
|
+
"Expected: SECURITY.md, incident-response plan, IR procedures, "
|
|
668
|
+
"escalation matrix, breach notification process."
|
|
669
|
+
),
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
def _check_risk_assessment(project_dir):
|
|
674
|
+
"""RA family: Check for threat model, vulnerability assessments."""
|
|
675
|
+
found = _dir_or_file_exists(
|
|
676
|
+
project_dir,
|
|
677
|
+
glob_patterns=[
|
|
678
|
+
"threat-model*", "threat_model*", "STRIDE*", "PASTA*",
|
|
679
|
+
"threat-analysis*", "threat_analysis*",
|
|
680
|
+
"risk-assessment*", "risk_assessment*",
|
|
681
|
+
"vulnerability-assessment*", "vulnerability_assessment*",
|
|
682
|
+
],
|
|
683
|
+
)
|
|
684
|
+
found_dirs = _dir_or_file_exists(
|
|
685
|
+
project_dir,
|
|
686
|
+
dir_names=[
|
|
687
|
+
"threat-model", "threat_model", "risk-assessment", "risk_assessment",
|
|
688
|
+
],
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
ra_patterns = [
|
|
692
|
+
r"threat.model|STRIDE|PASTA|attack.tree",
|
|
693
|
+
r"risk.assessment|risk.analysis|risk.register",
|
|
694
|
+
r"vulnerability.assessment|vuln.scan|vulnerability.scan",
|
|
695
|
+
]
|
|
696
|
+
extensions = (".py", ".yaml", ".yml", ".md", ".txt", ".json")
|
|
697
|
+
ra_matched, _ = _scan_files(project_dir, extensions, ra_patterns)
|
|
698
|
+
|
|
699
|
+
all_found = list(set(found + found_dirs + ra_matched))
|
|
700
|
+
if all_found:
|
|
701
|
+
return {
|
|
702
|
+
"status": "satisfied",
|
|
703
|
+
"evidence": (
|
|
704
|
+
f"Risk assessment artifacts found: {len(all_found)} item(s)."
|
|
705
|
+
),
|
|
706
|
+
"details": "; ".join(os.path.basename(f) for f in all_found[:5]),
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
return {
|
|
710
|
+
"status": "other_than_satisfied",
|
|
711
|
+
"evidence": "No risk assessment or threat model artifacts detected.",
|
|
712
|
+
"details": (
|
|
713
|
+
"Expected: threat model (STRIDE/PASTA), risk assessment, "
|
|
714
|
+
"vulnerability assessment documentation."
|
|
715
|
+
),
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
def _check_security_assessment(project_dir):
|
|
720
|
+
"""CA family: Check for test coverage, SAST/DAST config, security testing."""
|
|
721
|
+
test_found = _dir_or_file_exists(
|
|
722
|
+
project_dir,
|
|
723
|
+
dir_names=["tests", "test", "spec", "__tests__"],
|
|
724
|
+
glob_patterns=[
|
|
725
|
+
"test_*.py", "*_test.py", "*.test.js", "*.test.ts",
|
|
726
|
+
"*.spec.js", "*.spec.ts",
|
|
727
|
+
"pytest.ini", "setup.cfg", "tox.ini",
|
|
728
|
+
],
|
|
729
|
+
)
|
|
730
|
+
|
|
731
|
+
security_patterns = [
|
|
732
|
+
r"\bbandit\b|bandit.*config|\.bandit",
|
|
733
|
+
r"\bsast\b|static.analysis|static.application.security",
|
|
734
|
+
r"\bdast\b|dynamic.analysis|dynamic.application.security",
|
|
735
|
+
r"\bsonarqube\b|sonar-project|sonar.properties",
|
|
736
|
+
r"security.*test|pen.*test|penetration.*test",
|
|
737
|
+
r"\bsnyk\b|\btrivy\b|\bgrype\b",
|
|
738
|
+
r"pip.audit|npm.audit|safety.check",
|
|
739
|
+
]
|
|
740
|
+
extensions = (".py", ".yaml", ".yml", ".json", ".conf", ".cfg", ".ini")
|
|
741
|
+
security_matched, _ = _scan_files(project_dir, extensions, security_patterns)
|
|
742
|
+
|
|
743
|
+
has_tests = bool(test_found)
|
|
744
|
+
has_security_tools = bool(security_matched)
|
|
745
|
+
|
|
746
|
+
if has_tests and has_security_tools:
|
|
747
|
+
return {
|
|
748
|
+
"status": "satisfied",
|
|
749
|
+
"evidence": (
|
|
750
|
+
f"Security assessment: test suites ({len(test_found)} item(s)) "
|
|
751
|
+
f"and security tools ({len(security_matched)} config(s)) detected."
|
|
752
|
+
),
|
|
753
|
+
"details": (
|
|
754
|
+
"Tests: " + "; ".join(os.path.basename(f) for f in test_found[:3])
|
|
755
|
+
+ " | Security: "
|
|
756
|
+
+ "; ".join(os.path.basename(f) for f in security_matched[:3])
|
|
757
|
+
),
|
|
758
|
+
}
|
|
759
|
+
elif has_tests or has_security_tools:
|
|
760
|
+
found_type = "test suites" if has_tests else "security tools"
|
|
761
|
+
missing_type = "security testing tools (SAST/DAST)" if has_tests else "test suites"
|
|
762
|
+
return {
|
|
763
|
+
"status": "other_than_satisfied",
|
|
764
|
+
"evidence": (
|
|
765
|
+
f"Partial: {found_type} found but {missing_type} not detected."
|
|
766
|
+
),
|
|
767
|
+
"details": (
|
|
768
|
+
"FedRAMP requires both functional testing and security "
|
|
769
|
+
"assessment tools (SAST, DAST, vulnerability scanning)."
|
|
770
|
+
),
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
return {
|
|
774
|
+
"status": "other_than_satisfied",
|
|
775
|
+
"evidence": "No test suites or security assessment tools detected.",
|
|
776
|
+
"details": (
|
|
777
|
+
"Expected: test directories, pytest/jest configs, SAST (bandit, "
|
|
778
|
+
"SonarQube), DAST tools, and vulnerability scanning configs."
|
|
779
|
+
),
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
|
|
783
|
+
def _check_supply_chain(project_dir):
|
|
784
|
+
"""SA/SR family: Check for SBOM, dependency auditing, vendor risk."""
|
|
785
|
+
sbom_found = _dir_or_file_exists(
|
|
786
|
+
project_dir,
|
|
787
|
+
glob_patterns=[
|
|
788
|
+
"*sbom*.json", "*bom*.xml", "*sbom*.xml",
|
|
789
|
+
"*cyclonedx*", "*spdx*",
|
|
790
|
+
],
|
|
791
|
+
)
|
|
792
|
+
|
|
793
|
+
dep_patterns = [
|
|
794
|
+
r"pip.audit|pip_audit|pipaudit",
|
|
795
|
+
r"npm\s+audit|yarn\s+audit",
|
|
796
|
+
r"\bsafety\b.*check|safety\s+scan",
|
|
797
|
+
r"\bsnyk\b.*test|snyk\s+monitor",
|
|
798
|
+
r"dependency.check|DependencyCheck",
|
|
799
|
+
r"trivy\s+fs|grype\s+dir",
|
|
800
|
+
]
|
|
801
|
+
extensions = (".yaml", ".yml", ".json", ".toml", ".cfg", ".ini")
|
|
802
|
+
dep_matched, _ = _scan_files(project_dir, extensions, dep_patterns)
|
|
803
|
+
|
|
804
|
+
lock_files = _dir_or_file_exists(
|
|
805
|
+
project_dir,
|
|
806
|
+
glob_patterns=[
|
|
807
|
+
"requirements*.txt", "poetry.lock", "Pipfile.lock",
|
|
808
|
+
"package-lock.json", "yarn.lock", "pnpm-lock.yaml",
|
|
809
|
+
"go.sum", "Cargo.lock",
|
|
810
|
+
],
|
|
811
|
+
)
|
|
812
|
+
|
|
813
|
+
has_sbom = bool(sbom_found)
|
|
814
|
+
has_dep_audit = bool(dep_matched)
|
|
815
|
+
has_lock = bool(lock_files)
|
|
816
|
+
|
|
817
|
+
if has_sbom and has_dep_audit:
|
|
818
|
+
return {
|
|
819
|
+
"status": "satisfied",
|
|
820
|
+
"evidence": (
|
|
821
|
+
f"Supply chain: SBOM ({len(sbom_found)} artifact(s)) and "
|
|
822
|
+
f"dependency auditing ({len(dep_matched)} config(s)) detected."
|
|
823
|
+
),
|
|
824
|
+
"details": (
|
|
825
|
+
"SBOM: " + "; ".join(os.path.basename(f) for f in sbom_found[:3])
|
|
826
|
+
+ " | Audit: "
|
|
827
|
+
+ "; ".join(os.path.basename(f) for f in dep_matched[:3])
|
|
828
|
+
),
|
|
829
|
+
}
|
|
830
|
+
elif has_sbom or has_dep_audit or has_lock:
|
|
831
|
+
parts = []
|
|
832
|
+
if has_sbom:
|
|
833
|
+
parts.append("SBOM")
|
|
834
|
+
if has_dep_audit:
|
|
835
|
+
parts.append("dependency auditing")
|
|
836
|
+
if has_lock:
|
|
837
|
+
parts.append("lock files")
|
|
838
|
+
return {
|
|
839
|
+
"status": "other_than_satisfied",
|
|
840
|
+
"evidence": (
|
|
841
|
+
f"Partial supply chain: {', '.join(parts)} detected but "
|
|
842
|
+
f"complete supply chain risk management not verified."
|
|
843
|
+
),
|
|
844
|
+
"details": (
|
|
845
|
+
"FedRAMP requires SBOM generation, dependency vulnerability "
|
|
846
|
+
"scanning, and software composition analysis."
|
|
847
|
+
),
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
return {
|
|
851
|
+
"status": "other_than_satisfied",
|
|
852
|
+
"evidence": "No supply chain risk management artifacts detected.",
|
|
853
|
+
"details": (
|
|
854
|
+
"Expected: SBOM (CycloneDX/SPDX), dependency audit tools "
|
|
855
|
+
"(pip-audit, npm audit, Snyk), lock files."
|
|
856
|
+
),
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
|
|
860
|
+
def _check_data_encryption(project_dir):
|
|
861
|
+
"""SC-28 family: Check for encryption at rest, key management patterns."""
|
|
862
|
+
patterns = [
|
|
863
|
+
r"\bFIPS\b|fips_mode|FIPS.140",
|
|
864
|
+
r"AES.256|AES_256|aes256",
|
|
865
|
+
r"encryption.at.rest|encrypt_at_rest|encrypted_at_rest",
|
|
866
|
+
r"storage_encrypted|StorageEncrypted|encrypted\s*=\s*true",
|
|
867
|
+
r"\bKMS\b|kms_key|aws_kms|key_management",
|
|
868
|
+
r"server.side.encryption|SSE.S3|SSE.KMS|SSEAlgorithm",
|
|
869
|
+
]
|
|
870
|
+
extensions = (".py", ".yaml", ".yml", ".tf", ".json", ".conf")
|
|
871
|
+
matched, total = _scan_files(project_dir, extensions, patterns)
|
|
872
|
+
|
|
873
|
+
if total == 0:
|
|
874
|
+
return {
|
|
875
|
+
"status": "other_than_satisfied",
|
|
876
|
+
"evidence": "No configuration files found to assess.",
|
|
877
|
+
"details": "Project directory lacks applicable config files.",
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
if matched:
|
|
881
|
+
return {
|
|
882
|
+
"status": "satisfied",
|
|
883
|
+
"evidence": (
|
|
884
|
+
f"Encryption-at-rest patterns found in "
|
|
885
|
+
f"{len(matched)} file(s)."
|
|
886
|
+
),
|
|
887
|
+
"details": "; ".join(os.path.basename(f) for f in matched[:5]),
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
return {
|
|
891
|
+
"status": "other_than_satisfied",
|
|
892
|
+
"evidence": "No encryption-at-rest patterns detected.",
|
|
893
|
+
"details": (
|
|
894
|
+
"Expected: FIPS 140-2, AES-256, KMS, storage_encrypted, or "
|
|
895
|
+
"server-side encryption. FedRAMP requires FIPS-validated modules."
|
|
896
|
+
),
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
|
|
900
|
+
def _check_backup_recovery(project_dir):
|
|
901
|
+
"""CP family: Check for backup config, disaster recovery plans."""
|
|
902
|
+
found = _dir_or_file_exists(
|
|
903
|
+
project_dir,
|
|
904
|
+
glob_patterns=[
|
|
905
|
+
"backup*", "disaster-recovery*", "disaster_recovery*",
|
|
906
|
+
"dr-plan*", "dr_plan*", "continuity*",
|
|
907
|
+
"bcp*", "contingency*",
|
|
908
|
+
],
|
|
909
|
+
)
|
|
910
|
+
found_dirs = _dir_or_file_exists(
|
|
911
|
+
project_dir,
|
|
912
|
+
dir_names=["backup", "backups", "disaster-recovery", "dr"],
|
|
913
|
+
)
|
|
914
|
+
|
|
915
|
+
cp_patterns = [
|
|
916
|
+
r"backup.*policy|backup.*schedule|backup.*config",
|
|
917
|
+
r"disaster.recovery|recovery.point|recovery.time",
|
|
918
|
+
r"RPO|RTO|continuity.plan|contingency.plan",
|
|
919
|
+
r"aws_backup|aws_db_snapshot|snapshot.*schedule",
|
|
920
|
+
r"velero|restic|borg|duplicity",
|
|
921
|
+
]
|
|
922
|
+
extensions = (".py", ".yaml", ".yml", ".tf", ".json", ".md", ".conf")
|
|
923
|
+
cp_matched, _ = _scan_files(project_dir, extensions, cp_patterns)
|
|
924
|
+
|
|
925
|
+
all_found = list(set(found + found_dirs + cp_matched))
|
|
926
|
+
if all_found:
|
|
927
|
+
return {
|
|
928
|
+
"status": "satisfied",
|
|
929
|
+
"evidence": (
|
|
930
|
+
f"Backup/recovery artifacts found: {len(all_found)} item(s)."
|
|
931
|
+
),
|
|
932
|
+
"details": "; ".join(os.path.basename(f) for f in all_found[:5]),
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
return {
|
|
936
|
+
"status": "other_than_satisfied",
|
|
937
|
+
"evidence": "No backup or disaster recovery artifacts detected.",
|
|
938
|
+
"details": (
|
|
939
|
+
"Expected: backup configs, DR plan, RPO/RTO documentation, "
|
|
940
|
+
"contingency plan, AWS Backup or equivalent tooling."
|
|
941
|
+
),
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
|
|
945
|
+
def _check_boundary_protection(project_dir):
|
|
946
|
+
"""SC-7 family: Check for firewalls, network segmentation, WAF config."""
|
|
947
|
+
patterns = [
|
|
948
|
+
r"security.group|SecurityGroup|security_group",
|
|
949
|
+
r"firewall|Firewall|NetworkPolicy|network.policy",
|
|
950
|
+
r"WAF|web.application.firewall|waf_acl",
|
|
951
|
+
r"network.segmentation|subnet|Subnet",
|
|
952
|
+
r"ingress.*rule|egress.*rule|IngressRule|EgressRule",
|
|
953
|
+
r"aws_security_group|aws_waf|aws_network_acl",
|
|
954
|
+
r"default.deny|deny.all|NetworkPolicy.*DefaultDeny",
|
|
955
|
+
]
|
|
956
|
+
extensions = (".py", ".yaml", ".yml", ".tf", ".json", ".conf")
|
|
957
|
+
matched, total = _scan_files(project_dir, extensions, patterns)
|
|
958
|
+
|
|
959
|
+
if total == 0:
|
|
960
|
+
return {
|
|
961
|
+
"status": "other_than_satisfied",
|
|
962
|
+
"evidence": "No infrastructure config files found to assess.",
|
|
963
|
+
"details": "Project directory lacks applicable IaC/config files.",
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
if len(matched) >= 2:
|
|
967
|
+
return {
|
|
968
|
+
"status": "satisfied",
|
|
969
|
+
"evidence": (
|
|
970
|
+
f"Boundary protection patterns found in "
|
|
971
|
+
f"{len(matched)} file(s)."
|
|
972
|
+
),
|
|
973
|
+
"details": "; ".join(os.path.basename(f) for f in matched[:5]),
|
|
974
|
+
}
|
|
975
|
+
elif matched:
|
|
976
|
+
return {
|
|
977
|
+
"status": "other_than_satisfied",
|
|
978
|
+
"evidence": (
|
|
979
|
+
f"Minimal boundary protection in {len(matched)} file(s). "
|
|
980
|
+
f"FedRAMP requires comprehensive network segmentation."
|
|
981
|
+
),
|
|
982
|
+
"details": "; ".join(os.path.basename(f) for f in matched[:5]),
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
return {
|
|
986
|
+
"status": "other_than_satisfied",
|
|
987
|
+
"evidence": "No boundary protection patterns detected.",
|
|
988
|
+
"details": (
|
|
989
|
+
"Expected: security groups, firewalls, WAF, network policies, "
|
|
990
|
+
"default-deny rules, subnet segmentation."
|
|
991
|
+
),
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
def _check_remote_access(project_dir):
|
|
996
|
+
"""AC-17 family: Check for VPN, remote access controls."""
|
|
997
|
+
patterns = [
|
|
998
|
+
r"\bVPN\b|vpn_config|vpn.gateway",
|
|
999
|
+
r"remote.access|RemoteAccess|remote_access",
|
|
1000
|
+
r"bastion|BastionHost|bastion.host|jump.box",
|
|
1001
|
+
r"SSM|Session.Manager|aws_ssm",
|
|
1002
|
+
r"SSH.*key|ssh_key|authorized_keys",
|
|
1003
|
+
r"client.vpn|site.to.site|ipsec|wireguard",
|
|
1004
|
+
]
|
|
1005
|
+
extensions = (".py", ".yaml", ".yml", ".tf", ".json", ".conf")
|
|
1006
|
+
matched, total = _scan_files(project_dir, extensions, patterns)
|
|
1007
|
+
|
|
1008
|
+
if total == 0:
|
|
1009
|
+
return {
|
|
1010
|
+
"status": "not_applicable",
|
|
1011
|
+
"evidence": "No infrastructure config files found. Remote access check N/A.",
|
|
1012
|
+
"details": "May require manual review if remote access is in scope.",
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
if matched:
|
|
1016
|
+
return {
|
|
1017
|
+
"status": "satisfied",
|
|
1018
|
+
"evidence": (
|
|
1019
|
+
f"Remote access control patterns found in "
|
|
1020
|
+
f"{len(matched)} file(s)."
|
|
1021
|
+
),
|
|
1022
|
+
"details": "; ".join(os.path.basename(f) for f in matched[:5]),
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
return {
|
|
1026
|
+
"status": "other_than_satisfied",
|
|
1027
|
+
"evidence": "No remote access control patterns detected.",
|
|
1028
|
+
"details": (
|
|
1029
|
+
"Expected: VPN, bastion host, SSM Session Manager, SSH key "
|
|
1030
|
+
"management, or equivalent remote access controls."
|
|
1031
|
+
),
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
|
|
1035
|
+
def _check_media_protection(project_dir):
|
|
1036
|
+
"""MP family: Check for data sanitization, media handling."""
|
|
1037
|
+
patterns = [
|
|
1038
|
+
r"data.sanitization|data.wipe|data.disposal",
|
|
1039
|
+
r"media.protection|media.handling|media.transport",
|
|
1040
|
+
r"degauss|shred|secure.erase|crypto.erase",
|
|
1041
|
+
r"data.lifecycle|data.retention|data.classification",
|
|
1042
|
+
]
|
|
1043
|
+
extensions = (".py", ".yaml", ".yml", ".md", ".txt", ".json", ".conf")
|
|
1044
|
+
matched, total = _scan_files(project_dir, extensions, patterns)
|
|
1045
|
+
|
|
1046
|
+
if total == 0:
|
|
1047
|
+
return {
|
|
1048
|
+
"status": "not_applicable",
|
|
1049
|
+
"evidence": "No files found to assess media protection.",
|
|
1050
|
+
"details": "Cloud-native systems may inherit media protection from CSP.",
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
if matched:
|
|
1054
|
+
return {
|
|
1055
|
+
"status": "satisfied",
|
|
1056
|
+
"evidence": (
|
|
1057
|
+
f"Media protection patterns found in {len(matched)} file(s)."
|
|
1058
|
+
),
|
|
1059
|
+
"details": "; ".join(os.path.basename(f) for f in matched[:5]),
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
return {
|
|
1063
|
+
"status": "other_than_satisfied",
|
|
1064
|
+
"evidence": "No media protection or data sanitization patterns detected.",
|
|
1065
|
+
"details": (
|
|
1066
|
+
"Expected: data sanitization policies, media handling procedures, "
|
|
1067
|
+
"data lifecycle management. May be inherited from CSP for cloud."
|
|
1068
|
+
),
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
|
|
1072
|
+
def _check_system_integrity(project_dir):
|
|
1073
|
+
"""SI family: Check for integrity monitoring, anti-malware, HIDS."""
|
|
1074
|
+
patterns = [
|
|
1075
|
+
r"integrity.*check|integrity.*monitor|file.*integrity",
|
|
1076
|
+
r"\bHIDS\b|host.intrusion|intrusion.detection",
|
|
1077
|
+
r"\bOSSEC\b|ossec|Wazuh|wazuh",
|
|
1078
|
+
r"\bAIDE\b|\bTripwire\b|tripwire",
|
|
1079
|
+
r"anti.malware|antivirus|malware.scan",
|
|
1080
|
+
r"ClamAV|clamav",
|
|
1081
|
+
r"patch.*management|patch.*policy|system.*update",
|
|
1082
|
+
r"flaw.remediation|vulnerability.*patch",
|
|
1083
|
+
]
|
|
1084
|
+
extensions = (".py", ".yaml", ".yml", ".tf", ".json", ".conf", ".md")
|
|
1085
|
+
matched, total = _scan_files(project_dir, extensions, patterns)
|
|
1086
|
+
|
|
1087
|
+
if total == 0:
|
|
1088
|
+
return {
|
|
1089
|
+
"status": "other_than_satisfied",
|
|
1090
|
+
"evidence": "No files found to assess system integrity.",
|
|
1091
|
+
"details": "Project directory lacks applicable files.",
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
if matched:
|
|
1095
|
+
return {
|
|
1096
|
+
"status": "satisfied",
|
|
1097
|
+
"evidence": (
|
|
1098
|
+
f"System integrity patterns found in {len(matched)} file(s)."
|
|
1099
|
+
),
|
|
1100
|
+
"details": "; ".join(os.path.basename(f) for f in matched[:5]),
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
return {
|
|
1104
|
+
"status": "other_than_satisfied",
|
|
1105
|
+
"evidence": "No system integrity monitoring patterns detected.",
|
|
1106
|
+
"details": (
|
|
1107
|
+
"Expected: file integrity monitoring (AIDE, Tripwire, OSSEC), "
|
|
1108
|
+
"anti-malware, HIDS, patch management, flaw remediation."
|
|
1109
|
+
),
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
|
|
1113
|
+
# -----------------------------------------------------------------
|
|
1114
|
+
# Control family to auto-check mapping
|
|
1115
|
+
# -----------------------------------------------------------------
|
|
1116
|
+
|
|
1117
|
+
FAMILY_CHECKS = {
|
|
1118
|
+
"AC": _check_access_control,
|
|
1119
|
+
"AU": _check_audit_logging,
|
|
1120
|
+
"IA": _check_identification_auth,
|
|
1121
|
+
"SC": _check_system_communications,
|
|
1122
|
+
"CM": _check_config_management,
|
|
1123
|
+
"IR": _check_incident_response,
|
|
1124
|
+
"RA": _check_risk_assessment,
|
|
1125
|
+
"CA": _check_security_assessment,
|
|
1126
|
+
"SA": _check_supply_chain,
|
|
1127
|
+
"CP": _check_backup_recovery,
|
|
1128
|
+
"MP": _check_media_protection,
|
|
1129
|
+
"SI": _check_system_integrity,
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
# SC-28 and SC-7 are sub-family checks keyed by NIST control prefix
|
|
1133
|
+
CONTROL_CHECKS = {
|
|
1134
|
+
"SC-28": _check_data_encryption,
|
|
1135
|
+
"SC-7": _check_boundary_protection,
|
|
1136
|
+
"AC-17": _check_remote_access,
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
|
|
1140
|
+
def _get_auto_check(control):
|
|
1141
|
+
"""Return the appropriate auto-check function for a FedRAMP control.
|
|
1142
|
+
|
|
1143
|
+
Checks CONTROL_CHECKS first for specific control IDs, then falls
|
|
1144
|
+
back to FAMILY_CHECKS for the control family.
|
|
1145
|
+
|
|
1146
|
+
Args:
|
|
1147
|
+
control: FedRAMP control dict with 'nist_control_id' and 'family' keys.
|
|
1148
|
+
|
|
1149
|
+
Returns:
|
|
1150
|
+
Callable or None.
|
|
1151
|
+
"""
|
|
1152
|
+
nist_id = control.get("nist_control_id", "")
|
|
1153
|
+
|
|
1154
|
+
# Check for specific control prefix match (e.g., SC-28, SC-7, AC-17)
|
|
1155
|
+
for prefix, check_fn in CONTROL_CHECKS.items():
|
|
1156
|
+
if nist_id.startswith(prefix):
|
|
1157
|
+
return check_fn
|
|
1158
|
+
|
|
1159
|
+
# Fall back to family check
|
|
1160
|
+
family = control.get("family", "")
|
|
1161
|
+
return FAMILY_CHECKS.get(family)
|
|
1162
|
+
|
|
1163
|
+
|
|
1164
|
+
# -----------------------------------------------------------------
|
|
1165
|
+
# Core assessment function
|
|
1166
|
+
# -----------------------------------------------------------------
|
|
1167
|
+
|
|
1168
|
+
def run_fedramp_assessment(
|
|
1169
|
+
project_id,
|
|
1170
|
+
baseline="moderate",
|
|
1171
|
+
project_dir=None,
|
|
1172
|
+
gate=False,
|
|
1173
|
+
output_path=None,
|
|
1174
|
+
db_path=None,
|
|
1175
|
+
):
|
|
1176
|
+
"""Run FedRAMP Moderate or High assessment.
|
|
1177
|
+
|
|
1178
|
+
Args:
|
|
1179
|
+
project_id: The project identifier.
|
|
1180
|
+
baseline: "moderate" or "high".
|
|
1181
|
+
project_dir: Project directory for automated file-based checks.
|
|
1182
|
+
gate: If True, evaluate the FedRAMP readiness gate.
|
|
1183
|
+
output_path: Override output directory for the assessment report.
|
|
1184
|
+
db_path: Override database path.
|
|
1185
|
+
|
|
1186
|
+
Returns:
|
|
1187
|
+
Dict with assessment results, summary, gate result, and output file path.
|
|
1188
|
+
"""
|
|
1189
|
+
db = Path(db_path) if db_path else DB_PATH
|
|
1190
|
+
conn = get_connection(db_path=db)
|
|
1191
|
+
try:
|
|
1192
|
+
project = _get_project(conn, project_id)
|
|
1193
|
+
|
|
1194
|
+
# Load FedRAMP baseline catalog
|
|
1195
|
+
metadata, controls = load_fedramp_baseline(baseline)
|
|
1196
|
+
|
|
1197
|
+
# Try to inherit NIST 800-53 implementations via crosswalk
|
|
1198
|
+
inherited = _try_inherit_nist_implementations(
|
|
1199
|
+
project_id, controls, db_path=db
|
|
1200
|
+
)
|
|
1201
|
+
|
|
1202
|
+
# Resolve project directory for auto-checks
|
|
1203
|
+
if project_dir and Path(project_dir).is_dir():
|
|
1204
|
+
can_auto_check = True
|
|
1205
|
+
elif (
|
|
1206
|
+
project.get("directory_path")
|
|
1207
|
+
and Path(project["directory_path"]).is_dir()
|
|
1208
|
+
):
|
|
1209
|
+
project_dir = project["directory_path"]
|
|
1210
|
+
can_auto_check = True
|
|
1211
|
+
else:
|
|
1212
|
+
can_auto_check = False
|
|
1213
|
+
|
|
1214
|
+
now = datetime.now(timezone.utc)
|
|
1215
|
+
results = []
|
|
1216
|
+
family_cache = {} # Cache auto-check results per family/control
|
|
1217
|
+
|
|
1218
|
+
# -- Assess each control --
|
|
1219
|
+
for ctrl in controls:
|
|
1220
|
+
ctrl_id = ctrl["id"]
|
|
1221
|
+
nist_id = ctrl.get("nist_control_id", "")
|
|
1222
|
+
family = ctrl.get("family", "")
|
|
1223
|
+
priority = ctrl.get("priority", "P1")
|
|
1224
|
+
|
|
1225
|
+
status = "not_assessed"
|
|
1226
|
+
evidence = ""
|
|
1227
|
+
details = ""
|
|
1228
|
+
notes = ""
|
|
1229
|
+
implementation_status = ""
|
|
1230
|
+
customer_responsible = ""
|
|
1231
|
+
|
|
1232
|
+
# Step 1: Check if inherited from NIST 800-53 implementation
|
|
1233
|
+
inherit_info = inherited.get(ctrl_id, {})
|
|
1234
|
+
if inherit_info.get("inherited"):
|
|
1235
|
+
nist_status = inherit_info.get("nist_status", "")
|
|
1236
|
+
if nist_status == "implemented":
|
|
1237
|
+
status = "satisfied"
|
|
1238
|
+
evidence = (
|
|
1239
|
+
f"Inherited from NIST 800-53 {nist_id} implementation "
|
|
1240
|
+
f"(status: {nist_status})."
|
|
1241
|
+
)
|
|
1242
|
+
implementation_status = "inherited"
|
|
1243
|
+
notes = "Auto-inherited via crosswalk engine."
|
|
1244
|
+
elif nist_status == "partially_implemented":
|
|
1245
|
+
status = "other_than_satisfied"
|
|
1246
|
+
evidence = (
|
|
1247
|
+
f"Partially inherited from NIST 800-53 {nist_id} "
|
|
1248
|
+
f"(status: {nist_status}). Requires additional FedRAMP "
|
|
1249
|
+
f"parameter verification."
|
|
1250
|
+
)
|
|
1251
|
+
implementation_status = "partially_inherited"
|
|
1252
|
+
notes = (
|
|
1253
|
+
"Inherited partial implementation. Review FedRAMP-specific "
|
|
1254
|
+
"parameters and additional requirements."
|
|
1255
|
+
)
|
|
1256
|
+
|
|
1257
|
+
# Step 2: Run auto-check if not already satisfied
|
|
1258
|
+
if status != "satisfied" and can_auto_check:
|
|
1259
|
+
check_fn = _get_auto_check(ctrl)
|
|
1260
|
+
if check_fn:
|
|
1261
|
+
# Use cache key to avoid re-running same family check
|
|
1262
|
+
cache_key = check_fn.__name__
|
|
1263
|
+
if cache_key not in family_cache:
|
|
1264
|
+
try:
|
|
1265
|
+
family_cache[cache_key] = check_fn(project_dir)
|
|
1266
|
+
except Exception as e:
|
|
1267
|
+
family_cache[cache_key] = {
|
|
1268
|
+
"status": "other_than_satisfied",
|
|
1269
|
+
"evidence": f"Auto-check error: {e}",
|
|
1270
|
+
"details": "Auto-check failed; manual review required.",
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
check_result = family_cache[cache_key]
|
|
1274
|
+
|
|
1275
|
+
# Only upgrade status if auto-check is better
|
|
1276
|
+
if status == "not_assessed" or (
|
|
1277
|
+
status == "other_than_satisfied"
|
|
1278
|
+
and check_result["status"] == "satisfied"
|
|
1279
|
+
):
|
|
1280
|
+
status = check_result["status"]
|
|
1281
|
+
evidence = check_result["evidence"]
|
|
1282
|
+
details = check_result.get("details", "")
|
|
1283
|
+
if check_result["status"] == "satisfied":
|
|
1284
|
+
implementation_status = "auto_verified"
|
|
1285
|
+
notes = f"Auto-checked via {cache_key}."
|
|
1286
|
+
|
|
1287
|
+
# Step 3: If still not assessed, mark for manual review
|
|
1288
|
+
if status == "not_assessed":
|
|
1289
|
+
if not can_auto_check:
|
|
1290
|
+
evidence = "No project directory available for automated checks."
|
|
1291
|
+
notes = "Provide --project-dir to enable auto-checks."
|
|
1292
|
+
else:
|
|
1293
|
+
evidence = "No automated check available for this control."
|
|
1294
|
+
notes = "Manual review required for FedRAMP assessment."
|
|
1295
|
+
|
|
1296
|
+
result_entry = {
|
|
1297
|
+
"control_id": ctrl_id,
|
|
1298
|
+
"family": family,
|
|
1299
|
+
"nist_control_id": nist_id,
|
|
1300
|
+
"title": ctrl.get("title", ""),
|
|
1301
|
+
"description": ctrl.get("description", ""),
|
|
1302
|
+
"priority": priority,
|
|
1303
|
+
"baseline": baseline,
|
|
1304
|
+
"fedramp_parameters": ctrl.get("fedramp_parameters", {}),
|
|
1305
|
+
"fedramp_additional_requirements": ctrl.get(
|
|
1306
|
+
"fedramp_additional_requirements", ""
|
|
1307
|
+
),
|
|
1308
|
+
"status": status,
|
|
1309
|
+
"implementation_status": implementation_status,
|
|
1310
|
+
"customer_responsible": customer_responsible,
|
|
1311
|
+
"evidence": evidence,
|
|
1312
|
+
"details": details,
|
|
1313
|
+
"notes": notes,
|
|
1314
|
+
"inherited": inherit_info.get("inherited", False),
|
|
1315
|
+
}
|
|
1316
|
+
results.append(result_entry)
|
|
1317
|
+
|
|
1318
|
+
# -- Upsert into fedramp_assessments table --
|
|
1319
|
+
try:
|
|
1320
|
+
conn.execute(
|
|
1321
|
+
"""INSERT OR REPLACE INTO fedramp_assessments
|
|
1322
|
+
(project_id, assessment_date, assessor, baseline,
|
|
1323
|
+
control_id, status, implementation_status,
|
|
1324
|
+
customer_responsible, evidence_description,
|
|
1325
|
+
evidence_path, automation_result, notes, updated_at)
|
|
1326
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
|
|
1327
|
+
(
|
|
1328
|
+
project_id,
|
|
1329
|
+
now.isoformat(),
|
|
1330
|
+
"icdev-compliance-engine",
|
|
1331
|
+
baseline,
|
|
1332
|
+
ctrl_id,
|
|
1333
|
+
status,
|
|
1334
|
+
implementation_status,
|
|
1335
|
+
customer_responsible,
|
|
1336
|
+
evidence,
|
|
1337
|
+
details if details else None,
|
|
1338
|
+
json.dumps({
|
|
1339
|
+
"check_function": (
|
|
1340
|
+
_get_auto_check(ctrl).__name__
|
|
1341
|
+
if _get_auto_check(ctrl)
|
|
1342
|
+
else None
|
|
1343
|
+
),
|
|
1344
|
+
"inherited": inherit_info.get("inherited", False),
|
|
1345
|
+
"nist_status": inherit_info.get("nist_status", ""),
|
|
1346
|
+
}),
|
|
1347
|
+
notes if notes else None,
|
|
1348
|
+
now.isoformat(),
|
|
1349
|
+
),
|
|
1350
|
+
)
|
|
1351
|
+
except Exception as e:
|
|
1352
|
+
print(
|
|
1353
|
+
f"Warning: Could not upsert assessment for {ctrl_id}: {e}",
|
|
1354
|
+
file=sys.stderr,
|
|
1355
|
+
)
|
|
1356
|
+
|
|
1357
|
+
conn.commit()
|
|
1358
|
+
|
|
1359
|
+
# -- Build summary by control family --
|
|
1360
|
+
family_order = [
|
|
1361
|
+
"AC", "AT", "AU", "CA", "CM", "CP", "IA", "IR",
|
|
1362
|
+
"MA", "MP", "PE", "PL", "PM", "PS", "PT", "RA",
|
|
1363
|
+
"SA", "SC", "SI", "SR",
|
|
1364
|
+
]
|
|
1365
|
+
family_names = {
|
|
1366
|
+
"AC": "Access Control",
|
|
1367
|
+
"AT": "Awareness and Training",
|
|
1368
|
+
"AU": "Audit and Accountability",
|
|
1369
|
+
"CA": "Assessment, Authorization, Monitoring",
|
|
1370
|
+
"CM": "Configuration Management",
|
|
1371
|
+
"CP": "Contingency Planning",
|
|
1372
|
+
"IA": "Identification and Authentication",
|
|
1373
|
+
"IR": "Incident Response",
|
|
1374
|
+
"MA": "Maintenance",
|
|
1375
|
+
"MP": "Media Protection",
|
|
1376
|
+
"PE": "Physical and Environmental Protection",
|
|
1377
|
+
"PL": "Planning",
|
|
1378
|
+
"PM": "Program Management",
|
|
1379
|
+
"PS": "Personnel Security",
|
|
1380
|
+
"PT": "PII Processing and Transparency",
|
|
1381
|
+
"RA": "Risk Assessment",
|
|
1382
|
+
"SA": "System and Services Acquisition",
|
|
1383
|
+
"SC": "System and Communications Protection",
|
|
1384
|
+
"SI": "System and Information Integrity",
|
|
1385
|
+
"SR": "Supply Chain Risk Management",
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
summary = {}
|
|
1389
|
+
for fam in family_order:
|
|
1390
|
+
summary[fam] = {
|
|
1391
|
+
"name": family_names.get(fam, fam),
|
|
1392
|
+
"total": 0,
|
|
1393
|
+
"satisfied": 0,
|
|
1394
|
+
"other_than_satisfied": 0,
|
|
1395
|
+
"not_assessed": 0,
|
|
1396
|
+
"not_applicable": 0,
|
|
1397
|
+
"risk_accepted": 0,
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
for r in results:
|
|
1401
|
+
fam = r["family"]
|
|
1402
|
+
if fam not in summary:
|
|
1403
|
+
summary[fam] = {
|
|
1404
|
+
"name": family_names.get(fam, fam),
|
|
1405
|
+
"total": 0,
|
|
1406
|
+
"satisfied": 0,
|
|
1407
|
+
"other_than_satisfied": 0,
|
|
1408
|
+
"not_assessed": 0,
|
|
1409
|
+
"not_applicable": 0,
|
|
1410
|
+
"risk_accepted": 0,
|
|
1411
|
+
}
|
|
1412
|
+
summary[fam]["total"] += 1
|
|
1413
|
+
st = r["status"]
|
|
1414
|
+
if st in summary[fam]:
|
|
1415
|
+
summary[fam][st] += 1
|
|
1416
|
+
|
|
1417
|
+
# -- Compute overall scores --
|
|
1418
|
+
total_controls = len(results)
|
|
1419
|
+
satisfied_count = sum(1 for r in results if r["status"] == "satisfied")
|
|
1420
|
+
ots_count = sum(
|
|
1421
|
+
1 for r in results if r["status"] == "other_than_satisfied"
|
|
1422
|
+
)
|
|
1423
|
+
na_count = sum(
|
|
1424
|
+
1 for r in results if r["status"] == "not_applicable"
|
|
1425
|
+
)
|
|
1426
|
+
not_assessed_count = sum(
|
|
1427
|
+
1 for r in results if r["status"] == "not_assessed"
|
|
1428
|
+
)
|
|
1429
|
+
risk_accepted_count = sum(
|
|
1430
|
+
1 for r in results if r["status"] == "risk_accepted"
|
|
1431
|
+
)
|
|
1432
|
+
inherited_count = sum(1 for r in results if r.get("inherited"))
|
|
1433
|
+
|
|
1434
|
+
assessable = total_controls - na_count
|
|
1435
|
+
if assessable > 0:
|
|
1436
|
+
overall_score = round(
|
|
1437
|
+
(satisfied_count + risk_accepted_count * 0.75)
|
|
1438
|
+
/ assessable
|
|
1439
|
+
* 100,
|
|
1440
|
+
1,
|
|
1441
|
+
)
|
|
1442
|
+
else:
|
|
1443
|
+
overall_score = 0.0
|
|
1444
|
+
|
|
1445
|
+
# -- Gate evaluation --
|
|
1446
|
+
# FedRAMP gate: 0 "other_than_satisfied" on critical (P1) controls
|
|
1447
|
+
critical_ots = 0
|
|
1448
|
+
critical_failures = []
|
|
1449
|
+
for r in results:
|
|
1450
|
+
if (
|
|
1451
|
+
r["priority"] == "P1"
|
|
1452
|
+
and r["status"] == "other_than_satisfied"
|
|
1453
|
+
):
|
|
1454
|
+
critical_ots += 1
|
|
1455
|
+
critical_failures.append(
|
|
1456
|
+
f"{r['control_id']} ({r['nist_control_id']}): {r['title']}"
|
|
1457
|
+
)
|
|
1458
|
+
|
|
1459
|
+
gate_passed = critical_ots == 0
|
|
1460
|
+
gate_result = {
|
|
1461
|
+
"evaluated": gate,
|
|
1462
|
+
"passed": gate_passed,
|
|
1463
|
+
"critical_other_than_satisfied": critical_ots,
|
|
1464
|
+
"critical_failures": critical_failures,
|
|
1465
|
+
"reason": (
|
|
1466
|
+
"PASS: 0 P1 controls with status other_than_satisfied"
|
|
1467
|
+
if gate_passed
|
|
1468
|
+
else (
|
|
1469
|
+
f"FAIL: {critical_ots} P1 control(s) other_than_satisfied: "
|
|
1470
|
+
+ ", ".join(critical_failures[:5])
|
|
1471
|
+
+ ("..." if len(critical_failures) > 5 else "")
|
|
1472
|
+
)
|
|
1473
|
+
),
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
# -- Generate Markdown assessment summary --
|
|
1477
|
+
cui_config = _load_cui_config()
|
|
1478
|
+
doc_header = cui_config.get(
|
|
1479
|
+
"document_header", "CUI // SP-CTI"
|
|
1480
|
+
).strip()
|
|
1481
|
+
doc_footer = cui_config.get(
|
|
1482
|
+
"document_footer", "CUI // SP-CTI"
|
|
1483
|
+
).strip()
|
|
1484
|
+
|
|
1485
|
+
lines = [
|
|
1486
|
+
doc_header,
|
|
1487
|
+
"",
|
|
1488
|
+
f"# FedRAMP {baseline.title()} Assessment Report",
|
|
1489
|
+
"",
|
|
1490
|
+
f"**Project:** {project.get('name', project_id)} ({project_id})",
|
|
1491
|
+
f"**Assessment Date:** {now.strftime('%Y-%m-%d %H:%M UTC')}",
|
|
1492
|
+
"**Assessor:** ICDEV Compliance Engine (automated)",
|
|
1493
|
+
f"**Baseline:** FedRAMP {baseline.title()}",
|
|
1494
|
+
"**Classification:** CUI // SP-CTI",
|
|
1495
|
+
"",
|
|
1496
|
+
"---",
|
|
1497
|
+
"",
|
|
1498
|
+
"## Executive Summary",
|
|
1499
|
+
"",
|
|
1500
|
+
f"**Overall Readiness Score:** {overall_score}%",
|
|
1501
|
+
f"**Total Controls:** {total_controls}",
|
|
1502
|
+
f"**Satisfied:** {satisfied_count}",
|
|
1503
|
+
f"**Other Than Satisfied:** {ots_count}",
|
|
1504
|
+
f"**Not Applicable:** {na_count}",
|
|
1505
|
+
f"**Not Assessed:** {not_assessed_count}",
|
|
1506
|
+
f"**Risk Accepted:** {risk_accepted_count}",
|
|
1507
|
+
f"**Inherited from NIST 800-53:** {inherited_count}",
|
|
1508
|
+
"",
|
|
1509
|
+
]
|
|
1510
|
+
|
|
1511
|
+
# Summary table
|
|
1512
|
+
lines.append(
|
|
1513
|
+
"| Family | Name | Total | Satisfied | OTS "
|
|
1514
|
+
"| Not Assessed | N/A | Risk Accepted |"
|
|
1515
|
+
)
|
|
1516
|
+
lines.append(
|
|
1517
|
+
"|--------|------|-------|-----------|-----"
|
|
1518
|
+
"|--------------|-----|---------------|"
|
|
1519
|
+
)
|
|
1520
|
+
|
|
1521
|
+
grand_total = {
|
|
1522
|
+
"total": 0, "satisfied": 0, "other_than_satisfied": 0,
|
|
1523
|
+
"not_assessed": 0, "not_applicable": 0, "risk_accepted": 0,
|
|
1524
|
+
}
|
|
1525
|
+
|
|
1526
|
+
for fam in family_order:
|
|
1527
|
+
s = summary.get(fam, {})
|
|
1528
|
+
if s.get("total", 0) == 0:
|
|
1529
|
+
continue
|
|
1530
|
+
lines.append(
|
|
1531
|
+
f"| {fam} | {s['name']} | {s['total']} | {s['satisfied']} | "
|
|
1532
|
+
f"{s['other_than_satisfied']} | "
|
|
1533
|
+
f"{s['not_assessed']} | {s['not_applicable']} | "
|
|
1534
|
+
f"{s['risk_accepted']} |"
|
|
1535
|
+
)
|
|
1536
|
+
for key in grand_total:
|
|
1537
|
+
grand_total[key] += s.get(key, 0)
|
|
1538
|
+
|
|
1539
|
+
lines.append(
|
|
1540
|
+
f"| **Total** | | **{grand_total['total']}** | "
|
|
1541
|
+
f"**{grand_total['satisfied']}** | "
|
|
1542
|
+
f"**{grand_total['other_than_satisfied']}** | "
|
|
1543
|
+
f"**{grand_total['not_assessed']}** | "
|
|
1544
|
+
f"**{grand_total['not_applicable']}** | "
|
|
1545
|
+
f"**{grand_total['risk_accepted']}** |"
|
|
1546
|
+
)
|
|
1547
|
+
lines.append("")
|
|
1548
|
+
|
|
1549
|
+
# Gate evaluation section
|
|
1550
|
+
if gate:
|
|
1551
|
+
gate_label = (
|
|
1552
|
+
"PASS" if gate_result["passed"] else "**FAIL**"
|
|
1553
|
+
)
|
|
1554
|
+
lines.extend([
|
|
1555
|
+
"## FedRAMP Readiness Gate",
|
|
1556
|
+
"",
|
|
1557
|
+
f"**Gate Result:** {gate_label}",
|
|
1558
|
+
(
|
|
1559
|
+
"**Criteria:** 0 P1 controls with status "
|
|
1560
|
+
"other_than_satisfied"
|
|
1561
|
+
),
|
|
1562
|
+
f"**P1 Failures:** {critical_ots}",
|
|
1563
|
+
"",
|
|
1564
|
+
])
|
|
1565
|
+
if critical_failures:
|
|
1566
|
+
lines.append("**Failed Controls:**")
|
|
1567
|
+
for cf in critical_failures[:10]:
|
|
1568
|
+
lines.append(f"- {cf}")
|
|
1569
|
+
if len(critical_failures) > 10:
|
|
1570
|
+
lines.append(
|
|
1571
|
+
f"- ... and {len(critical_failures) - 10} more"
|
|
1572
|
+
)
|
|
1573
|
+
lines.append("")
|
|
1574
|
+
|
|
1575
|
+
lines.extend(["---", ""])
|
|
1576
|
+
|
|
1577
|
+
# -- Detailed findings per family --
|
|
1578
|
+
lines.append("## Detailed Findings")
|
|
1579
|
+
lines.append("")
|
|
1580
|
+
|
|
1581
|
+
for fam in family_order:
|
|
1582
|
+
fam_results = [r for r in results if r["family"] == fam]
|
|
1583
|
+
if not fam_results:
|
|
1584
|
+
continue
|
|
1585
|
+
|
|
1586
|
+
fam_name = family_names.get(fam, fam)
|
|
1587
|
+
lines.append(f"### {fam}: {fam_name}")
|
|
1588
|
+
lines.append("")
|
|
1589
|
+
|
|
1590
|
+
for r in fam_results:
|
|
1591
|
+
status_display = r["status"].replace("_", " ").title()
|
|
1592
|
+
lines.extend([
|
|
1593
|
+
f"#### {r['control_id']}: {r['title']}",
|
|
1594
|
+
"",
|
|
1595
|
+
f"**NIST Control:** {r['nist_control_id']} ",
|
|
1596
|
+
f"**Priority:** {r['priority']} ",
|
|
1597
|
+
f"**Status:** {status_display} ",
|
|
1598
|
+
f"**Inherited:** {'Yes' if r.get('inherited') else 'No'}",
|
|
1599
|
+
"",
|
|
1600
|
+
f"**Evidence:** {r['evidence']}",
|
|
1601
|
+
"",
|
|
1602
|
+
])
|
|
1603
|
+
if r["details"]:
|
|
1604
|
+
lines.append(f"**Details:** {r['details']}")
|
|
1605
|
+
lines.append("")
|
|
1606
|
+
if r["notes"]:
|
|
1607
|
+
lines.append(f"**Notes:** {r['notes']}")
|
|
1608
|
+
lines.append("")
|
|
1609
|
+
lines.extend(["---", ""])
|
|
1610
|
+
|
|
1611
|
+
# Append CUI footer
|
|
1612
|
+
lines.extend([doc_footer, ""])
|
|
1613
|
+
content = "\n".join(lines)
|
|
1614
|
+
|
|
1615
|
+
# -- Write output file --
|
|
1616
|
+
if output_path:
|
|
1617
|
+
out_dir = Path(output_path)
|
|
1618
|
+
else:
|
|
1619
|
+
dir_path = project.get("directory_path", "")
|
|
1620
|
+
if dir_path:
|
|
1621
|
+
out_dir = Path(dir_path) / "compliance"
|
|
1622
|
+
else:
|
|
1623
|
+
out_dir = BASE_DIR / ".tmp" / "compliance" / project_id
|
|
1624
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
1625
|
+
|
|
1626
|
+
out_file = (
|
|
1627
|
+
out_dir
|
|
1628
|
+
/ f"fedramp_{baseline}_{project_id}_"
|
|
1629
|
+
f"{now.strftime('%Y%m%d_%H%M%S')}.md"
|
|
1630
|
+
)
|
|
1631
|
+
|
|
1632
|
+
with open(out_file, "w", encoding="utf-8") as f:
|
|
1633
|
+
f.write(content)
|
|
1634
|
+
|
|
1635
|
+
# -- Log audit event --
|
|
1636
|
+
_log_audit_event(
|
|
1637
|
+
conn,
|
|
1638
|
+
project_id,
|
|
1639
|
+
f"FedRAMP {baseline} assessment completed",
|
|
1640
|
+
{
|
|
1641
|
+
"baseline": baseline,
|
|
1642
|
+
"controls_assessed": total_controls,
|
|
1643
|
+
"overall_score": overall_score,
|
|
1644
|
+
"satisfied": satisfied_count,
|
|
1645
|
+
"other_than_satisfied": ots_count,
|
|
1646
|
+
"not_assessed": not_assessed_count,
|
|
1647
|
+
"not_applicable": na_count,
|
|
1648
|
+
"inherited_count": inherited_count,
|
|
1649
|
+
"gate_result": gate_result,
|
|
1650
|
+
"output_file": str(out_file),
|
|
1651
|
+
},
|
|
1652
|
+
out_file,
|
|
1653
|
+
)
|
|
1654
|
+
|
|
1655
|
+
# -- Console output --
|
|
1656
|
+
print(f"FedRAMP {baseline.title()} assessment completed:")
|
|
1657
|
+
print(f" File: {out_file}")
|
|
1658
|
+
print(f" Baseline: {baseline.title()}")
|
|
1659
|
+
print(f" Controls assessed: {total_controls}")
|
|
1660
|
+
print(f" Overall readiness: {overall_score}%")
|
|
1661
|
+
print(
|
|
1662
|
+
f" SAT={satisfied_count} OTS={ots_count} "
|
|
1663
|
+
f"NA={na_count} NOT_ASSESSED={not_assessed_count} "
|
|
1664
|
+
f"RISK_ACCEPTED={risk_accepted_count}"
|
|
1665
|
+
)
|
|
1666
|
+
print(f" Inherited from NIST 800-53: {inherited_count}")
|
|
1667
|
+
|
|
1668
|
+
for fam in family_order:
|
|
1669
|
+
s = summary.get(fam, {})
|
|
1670
|
+
if s.get("total", 0) == 0:
|
|
1671
|
+
continue
|
|
1672
|
+
print(
|
|
1673
|
+
f" {fam} ({s['name']}): "
|
|
1674
|
+
f"SAT={s['satisfied']} "
|
|
1675
|
+
f"OTS={s['other_than_satisfied']} "
|
|
1676
|
+
f"NOT_ASSESSED={s['not_assessed']}"
|
|
1677
|
+
)
|
|
1678
|
+
|
|
1679
|
+
if gate:
|
|
1680
|
+
print(f"\n Gate: {gate_result['reason']}")
|
|
1681
|
+
|
|
1682
|
+
return {
|
|
1683
|
+
"output_file": str(out_file),
|
|
1684
|
+
"results": results,
|
|
1685
|
+
"summary": summary,
|
|
1686
|
+
"overall_score": overall_score,
|
|
1687
|
+
"gate_result": gate_result,
|
|
1688
|
+
"metadata": {
|
|
1689
|
+
"baseline": baseline,
|
|
1690
|
+
"total_controls": total_controls,
|
|
1691
|
+
"satisfied": satisfied_count,
|
|
1692
|
+
"other_than_satisfied": ots_count,
|
|
1693
|
+
"not_applicable": na_count,
|
|
1694
|
+
"not_assessed": not_assessed_count,
|
|
1695
|
+
"risk_accepted": risk_accepted_count,
|
|
1696
|
+
"inherited_count": inherited_count,
|
|
1697
|
+
},
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
finally:
|
|
1701
|
+
conn.close()
|
|
1702
|
+
|
|
1703
|
+
|
|
1704
|
+
def assess_project(
|
|
1705
|
+
project_id,
|
|
1706
|
+
baseline="moderate",
|
|
1707
|
+
project_dir=None,
|
|
1708
|
+
gate=False,
|
|
1709
|
+
output_path=None,
|
|
1710
|
+
db_path=None,
|
|
1711
|
+
):
|
|
1712
|
+
"""Alias for run_fedramp_assessment (MCP compatibility)."""
|
|
1713
|
+
return run_fedramp_assessment(
|
|
1714
|
+
project_id,
|
|
1715
|
+
baseline=baseline,
|
|
1716
|
+
project_dir=project_dir,
|
|
1717
|
+
gate=gate,
|
|
1718
|
+
output_path=output_path,
|
|
1719
|
+
db_path=db_path,
|
|
1720
|
+
)
|
|
1721
|
+
|
|
1722
|
+
|
|
1723
|
+
# -----------------------------------------------------------------
|
|
1724
|
+
# CLI entrypoint
|
|
1725
|
+
# -----------------------------------------------------------------
|
|
1726
|
+
|
|
1727
|
+
if __name__ == "__main__":
|
|
1728
|
+
parser = argparse.ArgumentParser(
|
|
1729
|
+
description="Run FedRAMP Moderate/High assessment"
|
|
1730
|
+
)
|
|
1731
|
+
parser.add_argument(
|
|
1732
|
+
"--project-id", required=True, help="Project ID"
|
|
1733
|
+
)
|
|
1734
|
+
parser.add_argument(
|
|
1735
|
+
"--baseline",
|
|
1736
|
+
default="moderate",
|
|
1737
|
+
choices=["moderate", "high"],
|
|
1738
|
+
help="FedRAMP baseline (default: moderate)",
|
|
1739
|
+
)
|
|
1740
|
+
parser.add_argument(
|
|
1741
|
+
"--project-dir",
|
|
1742
|
+
help="Project directory for automated file-based checks",
|
|
1743
|
+
)
|
|
1744
|
+
parser.add_argument(
|
|
1745
|
+
"--gate",
|
|
1746
|
+
action="store_true",
|
|
1747
|
+
help="Evaluate FedRAMP readiness gate (0 P1 other_than_satisfied = pass)",
|
|
1748
|
+
)
|
|
1749
|
+
parser.add_argument(
|
|
1750
|
+
"--output-dir",
|
|
1751
|
+
help="Output directory for the assessment report",
|
|
1752
|
+
)
|
|
1753
|
+
parser.add_argument(
|
|
1754
|
+
"--db-path",
|
|
1755
|
+
type=Path,
|
|
1756
|
+
default=DB_PATH,
|
|
1757
|
+
help="Override database path",
|
|
1758
|
+
)
|
|
1759
|
+
parser.add_argument(
|
|
1760
|
+
"--json",
|
|
1761
|
+
action="store_true",
|
|
1762
|
+
help="Output summary as JSON",
|
|
1763
|
+
)
|
|
1764
|
+
args = parser.parse_args()
|
|
1765
|
+
|
|
1766
|
+
try:
|
|
1767
|
+
result = run_fedramp_assessment(
|
|
1768
|
+
project_id=args.project_id,
|
|
1769
|
+
baseline=args.baseline,
|
|
1770
|
+
project_dir=args.project_dir,
|
|
1771
|
+
gate=args.gate,
|
|
1772
|
+
output_path=args.output_dir,
|
|
1773
|
+
db_path=args.db_path,
|
|
1774
|
+
)
|
|
1775
|
+
|
|
1776
|
+
if args.json:
|
|
1777
|
+
print(
|
|
1778
|
+
json.dumps(
|
|
1779
|
+
{
|
|
1780
|
+
"output_file": result.get("output_file"),
|
|
1781
|
+
"overall_score": result.get("overall_score"),
|
|
1782
|
+
"metadata": result.get("metadata"),
|
|
1783
|
+
"summary": result.get("summary"),
|
|
1784
|
+
"gate_result": result.get("gate_result"),
|
|
1785
|
+
},
|
|
1786
|
+
indent=2,
|
|
1787
|
+
)
|
|
1788
|
+
)
|
|
1789
|
+
|
|
1790
|
+
if args.gate and not result["gate_result"]["passed"]:
|
|
1791
|
+
sys.exit(1)
|
|
1792
|
+
|
|
1793
|
+
except (FileNotFoundError, ValueError) as e:
|
|
1794
|
+
print(f"ERROR: {e}", file=sys.stderr)
|
|
1795
|
+
sys.exit(1)
|