regscale-cli 6.16.0.0__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.
Potentially problematic release.
This version of regscale-cli might be problematic. Click here for more details.
- regscale/__init__.py +1 -0
- regscale/airflow/__init__.py +9 -0
- regscale/airflow/azure/__init__.py +9 -0
- regscale/airflow/azure/cli.py +89 -0
- regscale/airflow/azure/upload_dags.py +116 -0
- regscale/airflow/click_dags.py +127 -0
- regscale/airflow/click_mixins.py +82 -0
- regscale/airflow/config.py +25 -0
- regscale/airflow/factories/__init__.py +0 -0
- regscale/airflow/factories/connections.py +58 -0
- regscale/airflow/factories/workflows.py +78 -0
- regscale/airflow/hierarchy.py +88 -0
- regscale/airflow/operators/__init__.py +0 -0
- regscale/airflow/operators/click.py +36 -0
- regscale/airflow/sensors/__init__.py +0 -0
- regscale/airflow/sensors/sql.py +107 -0
- regscale/airflow/sessions/__init__.py +0 -0
- regscale/airflow/sessions/sql/__init__.py +3 -0
- regscale/airflow/sessions/sql/queries.py +64 -0
- regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
- regscale/airflow/tasks/__init__.py +0 -0
- regscale/airflow/tasks/branches.py +22 -0
- regscale/airflow/tasks/cli.py +116 -0
- regscale/airflow/tasks/click.py +73 -0
- regscale/airflow/tasks/debugging.py +9 -0
- regscale/airflow/tasks/groups.py +116 -0
- regscale/airflow/tasks/init.py +60 -0
- regscale/airflow/tasks/states.py +47 -0
- regscale/airflow/tasks/workflows.py +36 -0
- regscale/ansible/__init__.py +9 -0
- regscale/core/__init__.py +0 -0
- regscale/core/app/__init__.py +3 -0
- regscale/core/app/api.py +571 -0
- regscale/core/app/application.py +665 -0
- regscale/core/app/internal/__init__.py +136 -0
- regscale/core/app/internal/admin_actions.py +230 -0
- regscale/core/app/internal/assessments_editor.py +873 -0
- regscale/core/app/internal/catalog.py +316 -0
- regscale/core/app/internal/comparison.py +459 -0
- regscale/core/app/internal/control_editor.py +571 -0
- regscale/core/app/internal/encrypt.py +79 -0
- regscale/core/app/internal/evidence.py +1240 -0
- regscale/core/app/internal/file_uploads.py +151 -0
- regscale/core/app/internal/healthcheck.py +66 -0
- regscale/core/app/internal/login.py +305 -0
- regscale/core/app/internal/migrations.py +240 -0
- regscale/core/app/internal/model_editor.py +1701 -0
- regscale/core/app/internal/poam_editor.py +632 -0
- regscale/core/app/internal/workflow.py +105 -0
- regscale/core/app/logz.py +74 -0
- regscale/core/app/utils/XMLIR.py +258 -0
- regscale/core/app/utils/__init__.py +0 -0
- regscale/core/app/utils/api_handler.py +358 -0
- regscale/core/app/utils/app_utils.py +1110 -0
- regscale/core/app/utils/catalog_utils/__init__.py +0 -0
- regscale/core/app/utils/catalog_utils/common.py +91 -0
- regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
- regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
- regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
- regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
- regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
- regscale/core/app/utils/file_utils.py +238 -0
- regscale/core/app/utils/parser_utils.py +81 -0
- regscale/core/app/utils/pickle_file_handler.py +57 -0
- regscale/core/app/utils/regscale_utils.py +319 -0
- regscale/core/app/utils/report_utils.py +119 -0
- regscale/core/app/utils/variables.py +226 -0
- regscale/core/decorators.py +31 -0
- regscale/core/lazy_group.py +65 -0
- regscale/core/login.py +63 -0
- regscale/core/server/__init__.py +0 -0
- regscale/core/server/flask_api.py +473 -0
- regscale/core/server/helpers.py +373 -0
- regscale/core/server/rest.py +64 -0
- regscale/core/server/static/css/bootstrap.css +6030 -0
- regscale/core/server/static/css/bootstrap.min.css +6 -0
- regscale/core/server/static/css/main.css +176 -0
- regscale/core/server/static/images/regscale-cli.svg +49 -0
- regscale/core/server/static/images/regscale.svg +38 -0
- regscale/core/server/templates/base.html +74 -0
- regscale/core/server/templates/index.html +43 -0
- regscale/core/server/templates/login.html +28 -0
- regscale/core/server/templates/make_base64.html +22 -0
- regscale/core/server/templates/upload_STIG.html +109 -0
- regscale/core/server/templates/upload_STIG_result.html +26 -0
- regscale/core/server/templates/upload_ssp.html +144 -0
- regscale/core/server/templates/upload_ssp_result.html +128 -0
- regscale/core/static/__init__.py +0 -0
- regscale/core/static/regex.py +14 -0
- regscale/core/utils/__init__.py +117 -0
- regscale/core/utils/click_utils.py +13 -0
- regscale/core/utils/date.py +238 -0
- regscale/core/utils/graphql.py +254 -0
- regscale/core/utils/urls.py +23 -0
- regscale/dev/__init__.py +6 -0
- regscale/dev/analysis.py +454 -0
- regscale/dev/cli.py +235 -0
- regscale/dev/code_gen.py +492 -0
- regscale/dev/dirs.py +69 -0
- regscale/dev/docs.py +384 -0
- regscale/dev/monitoring.py +26 -0
- regscale/dev/profiling.py +216 -0
- regscale/exceptions/__init__.py +4 -0
- regscale/exceptions/license_exception.py +7 -0
- regscale/exceptions/validation_exception.py +9 -0
- regscale/integrations/__init__.py +1 -0
- regscale/integrations/commercial/__init__.py +486 -0
- regscale/integrations/commercial/ad.py +433 -0
- regscale/integrations/commercial/amazon/__init__.py +0 -0
- regscale/integrations/commercial/amazon/common.py +106 -0
- regscale/integrations/commercial/aqua/__init__.py +0 -0
- regscale/integrations/commercial/aqua/aqua.py +91 -0
- regscale/integrations/commercial/aws/__init__.py +6 -0
- regscale/integrations/commercial/aws/cli.py +322 -0
- regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
- regscale/integrations/commercial/aws/inventory/base.py +64 -0
- regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
- regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
- regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
- regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
- regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
- regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
- regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
- regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
- regscale/integrations/commercial/aws/scanner.py +823 -0
- regscale/integrations/commercial/azure/__init__.py +0 -0
- regscale/integrations/commercial/azure/common.py +32 -0
- regscale/integrations/commercial/azure/intune.py +488 -0
- regscale/integrations/commercial/azure/scanner.py +49 -0
- regscale/integrations/commercial/burp.py +78 -0
- regscale/integrations/commercial/cpe.py +144 -0
- regscale/integrations/commercial/crowdstrike.py +1117 -0
- regscale/integrations/commercial/defender.py +1511 -0
- regscale/integrations/commercial/dependabot.py +210 -0
- regscale/integrations/commercial/durosuite/__init__.py +0 -0
- regscale/integrations/commercial/durosuite/api.py +1546 -0
- regscale/integrations/commercial/durosuite/process_devices.py +101 -0
- regscale/integrations/commercial/durosuite/scanner.py +637 -0
- regscale/integrations/commercial/durosuite/variables.py +21 -0
- regscale/integrations/commercial/ecr.py +90 -0
- regscale/integrations/commercial/gcp/__init__.py +237 -0
- regscale/integrations/commercial/gcp/auth.py +96 -0
- regscale/integrations/commercial/gcp/control_tests.py +238 -0
- regscale/integrations/commercial/gcp/variables.py +18 -0
- regscale/integrations/commercial/gitlab.py +332 -0
- regscale/integrations/commercial/grype.py +165 -0
- regscale/integrations/commercial/ibm.py +90 -0
- regscale/integrations/commercial/import_all/__init__.py +0 -0
- regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
- regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
- regscale/integrations/commercial/jira.py +1046 -0
- regscale/integrations/commercial/mappings/__init__.py +0 -0
- regscale/integrations/commercial/mappings/csf_controls.json +713 -0
- regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
- regscale/integrations/commercial/nessus/__init__.py +0 -0
- regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
- regscale/integrations/commercial/nessus/scanner.py +416 -0
- regscale/integrations/commercial/nexpose.py +90 -0
- regscale/integrations/commercial/okta.py +798 -0
- regscale/integrations/commercial/opentext/__init__.py +0 -0
- regscale/integrations/commercial/opentext/click.py +99 -0
- regscale/integrations/commercial/opentext/scanner.py +143 -0
- regscale/integrations/commercial/prisma.py +91 -0
- regscale/integrations/commercial/qualys.py +1462 -0
- regscale/integrations/commercial/salesforce.py +980 -0
- regscale/integrations/commercial/sap/__init__.py +0 -0
- regscale/integrations/commercial/sap/click.py +31 -0
- regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
- regscale/integrations/commercial/sap/sysdig/click.py +57 -0
- regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
- regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
- regscale/integrations/commercial/sap/tenable/click.py +49 -0
- regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
- regscale/integrations/commercial/servicenow.py +1756 -0
- regscale/integrations/commercial/sicura/__init__.py +0 -0
- regscale/integrations/commercial/sicura/api.py +855 -0
- regscale/integrations/commercial/sicura/commands.py +73 -0
- regscale/integrations/commercial/sicura/scanner.py +481 -0
- regscale/integrations/commercial/sicura/variables.py +16 -0
- regscale/integrations/commercial/snyk.py +90 -0
- regscale/integrations/commercial/sonarcloud.py +260 -0
- regscale/integrations/commercial/sqlserver.py +369 -0
- regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
- regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
- regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
- regscale/integrations/commercial/stigv2/__init__.py +0 -0
- regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
- regscale/integrations/commercial/stigv2/click_commands.py +95 -0
- regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
- regscale/integrations/commercial/synqly/__init__.py +0 -0
- regscale/integrations/commercial/synqly/assets.py +46 -0
- regscale/integrations/commercial/synqly/ticketing.py +132 -0
- regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
- regscale/integrations/commercial/synqly_jira.py +840 -0
- regscale/integrations/commercial/tenablev2/__init__.py +0 -0
- regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
- regscale/integrations/commercial/tenablev2/click.py +1584 -0
- regscale/integrations/commercial/tenablev2/scanner.py +504 -0
- regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
- regscale/integrations/commercial/tenablev2/utils.py +78 -0
- regscale/integrations/commercial/tenablev2/variables.py +17 -0
- regscale/integrations/commercial/trivy.py +162 -0
- regscale/integrations/commercial/veracode.py +96 -0
- regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
- regscale/integrations/commercial/wizv2/__init__.py +0 -0
- regscale/integrations/commercial/wizv2/click.py +429 -0
- regscale/integrations/commercial/wizv2/constants.py +1001 -0
- regscale/integrations/commercial/wizv2/issue.py +361 -0
- regscale/integrations/commercial/wizv2/models.py +112 -0
- regscale/integrations/commercial/wizv2/parsers.py +339 -0
- regscale/integrations/commercial/wizv2/sbom.py +115 -0
- regscale/integrations/commercial/wizv2/scanner.py +416 -0
- regscale/integrations/commercial/wizv2/utils.py +796 -0
- regscale/integrations/commercial/wizv2/variables.py +39 -0
- regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
- regscale/integrations/commercial/xray.py +91 -0
- regscale/integrations/integration/__init__.py +2 -0
- regscale/integrations/integration/integration.py +26 -0
- regscale/integrations/integration/inventory.py +17 -0
- regscale/integrations/integration/issue.py +100 -0
- regscale/integrations/integration_override.py +149 -0
- regscale/integrations/public/__init__.py +103 -0
- regscale/integrations/public/cisa.py +641 -0
- regscale/integrations/public/criticality_updater.py +70 -0
- regscale/integrations/public/emass.py +411 -0
- regscale/integrations/public/emass_slcm_import.py +697 -0
- regscale/integrations/public/fedramp/__init__.py +0 -0
- regscale/integrations/public/fedramp/appendix_parser.py +548 -0
- regscale/integrations/public/fedramp/click.py +479 -0
- regscale/integrations/public/fedramp/components.py +714 -0
- regscale/integrations/public/fedramp/docx_parser.py +259 -0
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
- regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
- regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
- regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
- regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
- regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
- regscale/integrations/public/fedramp/import_workbook.py +495 -0
- regscale/integrations/public/fedramp/inventory_items.py +244 -0
- regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
- regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
- regscale/integrations/public/fedramp/mappings/user.py +175 -0
- regscale/integrations/public/fedramp/mappings/values.py +141 -0
- regscale/integrations/public/fedramp/markdown_parser.py +150 -0
- regscale/integrations/public/fedramp/metadata.py +689 -0
- regscale/integrations/public/fedramp/models/__init__.py +59 -0
- regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
- regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
- regscale/integrations/public/fedramp/parts_mapper.py +107 -0
- regscale/integrations/public/fedramp/poam/__init__.py +0 -0
- regscale/integrations/public/fedramp/poam/scanner.py +851 -0
- regscale/integrations/public/fedramp/properties.py +201 -0
- regscale/integrations/public/fedramp/reporting.py +84 -0
- regscale/integrations/public/fedramp/resources.py +496 -0
- regscale/integrations/public/fedramp/rosetta.py +110 -0
- regscale/integrations/public/fedramp/ssp_logger.py +87 -0
- regscale/integrations/public/fedramp/system_characteristics.py +922 -0
- regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
- regscale/integrations/public/fedramp/system_implementation.py +190 -0
- regscale/integrations/public/fedramp/xml_utils.py +87 -0
- regscale/integrations/public/nist_catalog.py +275 -0
- regscale/integrations/public/oscal.py +1946 -0
- regscale/integrations/public/otx.py +169 -0
- regscale/integrations/scanner_integration.py +2692 -0
- regscale/integrations/variables.py +25 -0
- regscale/models/__init__.py +7 -0
- regscale/models/app_models/__init__.py +5 -0
- regscale/models/app_models/catalog_compare.py +213 -0
- regscale/models/app_models/click.py +252 -0
- regscale/models/app_models/datetime_encoder.py +21 -0
- regscale/models/app_models/import_validater.py +321 -0
- regscale/models/app_models/mapping.py +260 -0
- regscale/models/app_models/pipeline.py +37 -0
- regscale/models/click_models.py +413 -0
- regscale/models/config.py +154 -0
- regscale/models/email_style.css +67 -0
- regscale/models/hierarchy.py +8 -0
- regscale/models/inspect_models.py +79 -0
- regscale/models/integration_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/inspector.py +262 -0
- regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
- regscale/models/integration_models/aqua.py +247 -0
- regscale/models/integration_models/azure_alerts.py +255 -0
- regscale/models/integration_models/base64.py +23 -0
- regscale/models/integration_models/burp.py +433 -0
- regscale/models/integration_models/burp_models.py +128 -0
- regscale/models/integration_models/cisa_kev_data.json +19333 -0
- regscale/models/integration_models/defender_data.py +93 -0
- regscale/models/integration_models/defenderimport.py +143 -0
- regscale/models/integration_models/drf.py +443 -0
- regscale/models/integration_models/ecr_models/__init__.py +0 -0
- regscale/models/integration_models/ecr_models/data.py +69 -0
- regscale/models/integration_models/ecr_models/ecr.py +239 -0
- regscale/models/integration_models/flat_file_importer.py +1079 -0
- regscale/models/integration_models/grype_import.py +247 -0
- regscale/models/integration_models/ibm.py +126 -0
- regscale/models/integration_models/implementation_results.py +85 -0
- regscale/models/integration_models/nexpose.py +140 -0
- regscale/models/integration_models/prisma.py +202 -0
- regscale/models/integration_models/qualys.py +720 -0
- regscale/models/integration_models/qualys_scanner.py +160 -0
- regscale/models/integration_models/sbom/__init__.py +0 -0
- regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
- regscale/models/integration_models/send_reminders.py +620 -0
- regscale/models/integration_models/snyk.py +155 -0
- regscale/models/integration_models/synqly_models/__init__.py +0 -0
- regscale/models/integration_models/synqly_models/capabilities.json +1 -0
- regscale/models/integration_models/synqly_models/connector_types.py +22 -0
- regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
- regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
- regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
- regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
- regscale/models/integration_models/synqly_models/param.py +72 -0
- regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
- regscale/models/integration_models/synqly_models/tenants.py +39 -0
- regscale/models/integration_models/tenable_models/__init__.py +0 -0
- regscale/models/integration_models/tenable_models/integration.py +187 -0
- regscale/models/integration_models/tenable_models/models.py +513 -0
- regscale/models/integration_models/trivy_import.py +231 -0
- regscale/models/integration_models/veracode.py +217 -0
- regscale/models/integration_models/xray.py +135 -0
- regscale/models/locking.py +100 -0
- regscale/models/platform.py +110 -0
- regscale/models/regscale_models/__init__.py +67 -0
- regscale/models/regscale_models/assessment.py +570 -0
- regscale/models/regscale_models/assessment_plan.py +52 -0
- regscale/models/regscale_models/asset.py +567 -0
- regscale/models/regscale_models/asset_mapping.py +190 -0
- regscale/models/regscale_models/case.py +42 -0
- regscale/models/regscale_models/catalog.py +261 -0
- regscale/models/regscale_models/cci.py +46 -0
- regscale/models/regscale_models/change.py +167 -0
- regscale/models/regscale_models/checklist.py +372 -0
- regscale/models/regscale_models/comment.py +49 -0
- regscale/models/regscale_models/compliance_settings.py +112 -0
- regscale/models/regscale_models/component.py +412 -0
- regscale/models/regscale_models/component_mapping.py +65 -0
- regscale/models/regscale_models/control.py +38 -0
- regscale/models/regscale_models/control_implementation.py +1128 -0
- regscale/models/regscale_models/control_objective.py +261 -0
- regscale/models/regscale_models/control_parameter.py +100 -0
- regscale/models/regscale_models/control_test.py +34 -0
- regscale/models/regscale_models/control_test_plan.py +75 -0
- regscale/models/regscale_models/control_test_result.py +52 -0
- regscale/models/regscale_models/custom_field.py +245 -0
- regscale/models/regscale_models/data.py +109 -0
- regscale/models/regscale_models/data_center.py +40 -0
- regscale/models/regscale_models/deviation.py +203 -0
- regscale/models/regscale_models/email.py +97 -0
- regscale/models/regscale_models/evidence.py +47 -0
- regscale/models/regscale_models/evidence_mapping.py +40 -0
- regscale/models/regscale_models/facility.py +59 -0
- regscale/models/regscale_models/file.py +382 -0
- regscale/models/regscale_models/filetag.py +37 -0
- regscale/models/regscale_models/form_field_value.py +94 -0
- regscale/models/regscale_models/group.py +169 -0
- regscale/models/regscale_models/implementation_objective.py +335 -0
- regscale/models/regscale_models/implementation_option.py +275 -0
- regscale/models/regscale_models/implementation_role.py +33 -0
- regscale/models/regscale_models/incident.py +177 -0
- regscale/models/regscale_models/interconnection.py +43 -0
- regscale/models/regscale_models/issue.py +1176 -0
- regscale/models/regscale_models/leveraged_authorization.py +125 -0
- regscale/models/regscale_models/line_of_inquiry.py +52 -0
- regscale/models/regscale_models/link.py +205 -0
- regscale/models/regscale_models/meta_data.py +64 -0
- regscale/models/regscale_models/mixins/__init__.py +0 -0
- regscale/models/regscale_models/mixins/parent_cache.py +124 -0
- regscale/models/regscale_models/module.py +224 -0
- regscale/models/regscale_models/modules.py +191 -0
- regscale/models/regscale_models/objective.py +14 -0
- regscale/models/regscale_models/parameter.py +87 -0
- regscale/models/regscale_models/ports_protocol.py +81 -0
- regscale/models/regscale_models/privacy.py +89 -0
- regscale/models/regscale_models/profile.py +50 -0
- regscale/models/regscale_models/profile_link.py +68 -0
- regscale/models/regscale_models/profile_mapping.py +124 -0
- regscale/models/regscale_models/project.py +63 -0
- regscale/models/regscale_models/property.py +278 -0
- regscale/models/regscale_models/question.py +85 -0
- regscale/models/regscale_models/questionnaire.py +87 -0
- regscale/models/regscale_models/questionnaire_instance.py +177 -0
- regscale/models/regscale_models/rbac.py +132 -0
- regscale/models/regscale_models/reference.py +86 -0
- regscale/models/regscale_models/regscale_model.py +1643 -0
- regscale/models/regscale_models/requirement.py +29 -0
- regscale/models/regscale_models/risk.py +274 -0
- regscale/models/regscale_models/sbom.py +54 -0
- regscale/models/regscale_models/scan_history.py +436 -0
- regscale/models/regscale_models/search.py +53 -0
- regscale/models/regscale_models/security_control.py +132 -0
- regscale/models/regscale_models/security_plan.py +204 -0
- regscale/models/regscale_models/software_inventory.py +159 -0
- regscale/models/regscale_models/stake_holder.py +64 -0
- regscale/models/regscale_models/stig.py +647 -0
- regscale/models/regscale_models/supply_chain.py +152 -0
- regscale/models/regscale_models/system_role.py +188 -0
- regscale/models/regscale_models/system_role_external_assignment.py +40 -0
- regscale/models/regscale_models/tag.py +37 -0
- regscale/models/regscale_models/tag_mapping.py +19 -0
- regscale/models/regscale_models/task.py +133 -0
- regscale/models/regscale_models/threat.py +196 -0
- regscale/models/regscale_models/user.py +175 -0
- regscale/models/regscale_models/user_group.py +55 -0
- regscale/models/regscale_models/vulnerability.py +242 -0
- regscale/models/regscale_models/vulnerability_mapping.py +162 -0
- regscale/models/regscale_models/workflow.py +55 -0
- regscale/models/regscale_models/workflow_action.py +34 -0
- regscale/models/regscale_models/workflow_instance.py +269 -0
- regscale/models/regscale_models/workflow_instance_step.py +114 -0
- regscale/models/regscale_models/workflow_template.py +58 -0
- regscale/models/regscale_models/workflow_template_step.py +45 -0
- regscale/regscale.py +815 -0
- regscale/utils/__init__.py +7 -0
- regscale/utils/b64conversion.py +14 -0
- regscale/utils/click_utils.py +118 -0
- regscale/utils/decorators.py +48 -0
- regscale/utils/dict_utils.py +59 -0
- regscale/utils/files.py +79 -0
- regscale/utils/fxns.py +30 -0
- regscale/utils/graphql_client.py +113 -0
- regscale/utils/lists.py +16 -0
- regscale/utils/numbers.py +12 -0
- regscale/utils/shell.py +148 -0
- regscale/utils/string.py +121 -0
- regscale/utils/synqly_utils.py +165 -0
- regscale/utils/threading/__init__.py +8 -0
- regscale/utils/threading/threadhandler.py +131 -0
- regscale/utils/threading/threadsafe_counter.py +47 -0
- regscale/utils/threading/threadsafe_dict.py +242 -0
- regscale/utils/threading/threadsafe_list.py +83 -0
- regscale/utils/version.py +104 -0
- regscale/validation/__init__.py +0 -0
- regscale/validation/address.py +37 -0
- regscale/validation/record.py +48 -0
- regscale/visualization/__init__.py +5 -0
- regscale/visualization/click.py +34 -0
- regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
- regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
- regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
- regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
- regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
- regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
- tests/fixtures/__init__.py +2 -0
- tests/fixtures/api.py +87 -0
- tests/fixtures/models.py +91 -0
- tests/fixtures/test_fixture.py +144 -0
- tests/mocks/__init__.py +0 -0
- tests/mocks/objects.py +3 -0
- tests/mocks/response.py +32 -0
- tests/mocks/xml.py +13 -0
- tests/regscale/__init__.py +0 -0
- tests/regscale/core/__init__.py +0 -0
- tests/regscale/core/test_api.py +232 -0
- tests/regscale/core/test_app.py +406 -0
- tests/regscale/core/test_login.py +37 -0
- tests/regscale/core/test_logz.py +66 -0
- tests/regscale/core/test_sbom_generator.py +87 -0
- tests/regscale/core/test_validation_utils.py +163 -0
- tests/regscale/core/test_version.py +78 -0
- tests/regscale/models/__init__.py +0 -0
- tests/regscale/models/test_asset.py +71 -0
- tests/regscale/models/test_config.py +26 -0
- tests/regscale/models/test_control_implementation.py +27 -0
- tests/regscale/models/test_import.py +97 -0
- tests/regscale/models/test_issue.py +36 -0
- tests/regscale/models/test_mapping.py +52 -0
- tests/regscale/models/test_platform.py +31 -0
- tests/regscale/models/test_regscale_model.py +346 -0
- tests/regscale/models/test_report.py +32 -0
- tests/regscale/models/test_tenable_integrations.py +118 -0
- tests/regscale/models/test_user_model.py +121 -0
- tests/regscale/test_about.py +19 -0
- tests/regscale/test_authorization.py +65 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""ECR RegScale integration"""
|
|
4
|
+
import os
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
|
|
10
|
+
from regscale.models.integration_models.ecr_models.ecr import ECR
|
|
11
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.group()
|
|
15
|
+
def ecr():
|
|
16
|
+
"""Performs actions on ECR Scanner artifacts."""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@ecr.command(name="import_ecr")
|
|
20
|
+
@FlatFileImporter.common_scanner_options(
|
|
21
|
+
message="File path to the folder containing ECR files to process to RegScale.",
|
|
22
|
+
prompt="File path for ECR files",
|
|
23
|
+
import_name="ecr",
|
|
24
|
+
)
|
|
25
|
+
def import_ecr(
|
|
26
|
+
folder_path: os.PathLike[str],
|
|
27
|
+
regscale_ssp_id: click.INT,
|
|
28
|
+
scan_date: datetime,
|
|
29
|
+
mappings_path: os.PathLike[str],
|
|
30
|
+
disable_mapping: click.BOOL,
|
|
31
|
+
s3_bucket: str,
|
|
32
|
+
s3_prefix: str,
|
|
33
|
+
aws_profile: str,
|
|
34
|
+
upload_file: bool,
|
|
35
|
+
):
|
|
36
|
+
"""
|
|
37
|
+
Import ECR scans, vulnerabilities and assets to RegScale from ECR JSON files
|
|
38
|
+
"""
|
|
39
|
+
import_ecr_scans(
|
|
40
|
+
folder_path=folder_path,
|
|
41
|
+
regscale_ssp_id=regscale_ssp_id,
|
|
42
|
+
scan_date=scan_date,
|
|
43
|
+
mappings_path=mappings_path,
|
|
44
|
+
disable_mapping=disable_mapping,
|
|
45
|
+
s3_bucket=s3_bucket,
|
|
46
|
+
s3_prefix=s3_prefix,
|
|
47
|
+
aws_profile=aws_profile,
|
|
48
|
+
upload_file=upload_file,
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def import_ecr_scans(
|
|
53
|
+
folder_path: os.PathLike[str],
|
|
54
|
+
regscale_ssp_id: click.INT,
|
|
55
|
+
scan_date: datetime,
|
|
56
|
+
mappings_path: os.PathLike[str],
|
|
57
|
+
disable_mapping: click.BOOL,
|
|
58
|
+
s3_bucket: str,
|
|
59
|
+
s3_prefix: str,
|
|
60
|
+
aws_profile: str,
|
|
61
|
+
upload_file: Optional[bool] = True,
|
|
62
|
+
) -> None:
|
|
63
|
+
"""
|
|
64
|
+
Function to import ECR scans to RegScale as assets and vulnerabilities
|
|
65
|
+
|
|
66
|
+
:param os.PathLike[str] folder_path: Path to the folder containing ECR files
|
|
67
|
+
:param int regscale_ssp_id: RegScale System Security Plan ID
|
|
68
|
+
:param datetime scan_date: Date of the scan
|
|
69
|
+
:param click.Path mappings_path: Path to the header mapping file
|
|
70
|
+
:param bool disable_mapping: Disable header mapping
|
|
71
|
+
:param str s3_bucket: S3 bucket name
|
|
72
|
+
:param str s3_prefix: S3 prefix
|
|
73
|
+
:param str aws_profile: AWS profile
|
|
74
|
+
:param bool upload_file: Whether to upload the file to RegScale after processing, defaults to True
|
|
75
|
+
:rtype: None
|
|
76
|
+
"""
|
|
77
|
+
FlatFileImporter.import_files(
|
|
78
|
+
import_type=ECR,
|
|
79
|
+
import_name="ECR",
|
|
80
|
+
file_types=[".csv", ".json"],
|
|
81
|
+
folder_path=folder_path,
|
|
82
|
+
regscale_ssp_id=regscale_ssp_id,
|
|
83
|
+
scan_date=scan_date,
|
|
84
|
+
mappings_path=mappings_path,
|
|
85
|
+
disable_mapping=disable_mapping,
|
|
86
|
+
s3_bucket=s3_bucket,
|
|
87
|
+
s3_prefix=s3_prefix,
|
|
88
|
+
aws_profile=aws_profile,
|
|
89
|
+
upload_file=upload_file,
|
|
90
|
+
)
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""RegScale GCP Package"""
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from google.cloud.securitycenter_v1 import Finding
|
|
8
|
+
from google.cloud.securitycenter_v1.services.security_center.pagers import ListFindingsPager
|
|
9
|
+
from google.cloud import asset_v1
|
|
10
|
+
|
|
11
|
+
import copy
|
|
12
|
+
from typing import List, Optional
|
|
13
|
+
|
|
14
|
+
import click
|
|
15
|
+
|
|
16
|
+
from regscale.core.utils.date import default_date_format
|
|
17
|
+
from regscale.integrations.commercial.gcp.auth import (
|
|
18
|
+
get_gcp_security_center_client,
|
|
19
|
+
get_gcp_asset_service_client,
|
|
20
|
+
)
|
|
21
|
+
from regscale.integrations.commercial.gcp.control_tests import gcp_control_tests
|
|
22
|
+
from regscale.integrations.commercial.gcp.variables import GcpVariables
|
|
23
|
+
from regscale.integrations.scanner_integration import (
|
|
24
|
+
logger,
|
|
25
|
+
IntegrationFinding,
|
|
26
|
+
ScannerIntegration,
|
|
27
|
+
IntegrationAsset,
|
|
28
|
+
)
|
|
29
|
+
from regscale.models import regscale_models
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@click.group()
|
|
33
|
+
def gcp():
|
|
34
|
+
"""GCP Integrations"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@gcp.command(name="sync_findings")
|
|
38
|
+
@click.option(
|
|
39
|
+
"--regscale_ssp_id",
|
|
40
|
+
type=click.INT,
|
|
41
|
+
help="The ID number from RegScale of the System Security Plan",
|
|
42
|
+
prompt="Enter RegScale System Security Plan ID",
|
|
43
|
+
required=True,
|
|
44
|
+
)
|
|
45
|
+
def sync_findings(regscale_ssp_id):
|
|
46
|
+
"""Sync GCP Findings to RegScale."""
|
|
47
|
+
GCPScannerIntegration.sync_findings(plan_id=regscale_ssp_id)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@gcp.command(name="sync_assets")
|
|
51
|
+
@click.option(
|
|
52
|
+
"--regscale_ssp_id",
|
|
53
|
+
type=click.INT,
|
|
54
|
+
help="The ID number from RegScale of the System Security Plan",
|
|
55
|
+
prompt="Enter RegScale System Security Plan ID",
|
|
56
|
+
required=True,
|
|
57
|
+
)
|
|
58
|
+
def sync_assets(regscale_ssp_id):
|
|
59
|
+
"""Sync GCP Assets to RegScale."""
|
|
60
|
+
GCPScannerIntegration.sync_assets(plan_id=regscale_ssp_id)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class GCPScannerIntegration(ScannerIntegration):
|
|
64
|
+
title = "GCP Scanner Integration"
|
|
65
|
+
asset_identifier_field = "googleIdentifier"
|
|
66
|
+
gcp_control_tests: dict[str, dict[str, dict[str, str]]] = {}
|
|
67
|
+
finding_severity_map = {
|
|
68
|
+
0: regscale_models.IssueSeverity.Low,
|
|
69
|
+
1: regscale_models.IssueSeverity.Critical,
|
|
70
|
+
2: regscale_models.IssueSeverity.High,
|
|
71
|
+
3: regscale_models.IssueSeverity.Moderate,
|
|
72
|
+
4: regscale_models.IssueSeverity.Low,
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@staticmethod
|
|
76
|
+
def get_failed_findings() -> "ListFindingsPager":
|
|
77
|
+
"""
|
|
78
|
+
Fetches GCP findings using the SecurityCenterClient
|
|
79
|
+
|
|
80
|
+
:raises NameError: If gcpFindingSources is set incorrectly
|
|
81
|
+
:return: A list of parsed findings
|
|
82
|
+
:rtype: ListFindingsPager
|
|
83
|
+
"""
|
|
84
|
+
from google.api_core.exceptions import InvalidArgument # Optimize import performance
|
|
85
|
+
|
|
86
|
+
logger.info("Fetching GCP findings...")
|
|
87
|
+
|
|
88
|
+
if str(GcpVariables.gcpScanType) == "project": # type: ignore
|
|
89
|
+
sources = f"projects/{GcpVariables.gcpProjectId}/sources/-"
|
|
90
|
+
else:
|
|
91
|
+
sources = f"organizations/{GcpVariables.gcpOrganizationId}/sources/-"
|
|
92
|
+
try:
|
|
93
|
+
client = get_gcp_security_center_client()
|
|
94
|
+
gcp_findings = client.list_findings(request={"parent": sources})
|
|
95
|
+
logger.info("Fetched GCP findings.")
|
|
96
|
+
return gcp_findings
|
|
97
|
+
except InvalidArgument:
|
|
98
|
+
error_msg = f"gcpFindingSources is set incorrectly: {sources}."
|
|
99
|
+
logger.error(error_msg)
|
|
100
|
+
raise NameError(error_msg)
|
|
101
|
+
|
|
102
|
+
def get_passed_findings(self) -> List[IntegrationFinding]:
|
|
103
|
+
"""
|
|
104
|
+
Gets passed findings for from the GCP control tests
|
|
105
|
+
|
|
106
|
+
:return: A list of passed findings
|
|
107
|
+
:rtype: List[IntegrationFinding]
|
|
108
|
+
"""
|
|
109
|
+
passed_findings = []
|
|
110
|
+
self.gcp_control_tests = copy.copy(gcp_control_tests)
|
|
111
|
+
|
|
112
|
+
for control_label, categories in self.gcp_control_tests.items():
|
|
113
|
+
for category, control_test in categories.items():
|
|
114
|
+
if control_test.get("status", "") == "Failed":
|
|
115
|
+
logger.debug(
|
|
116
|
+
f"Control {control_label} had findings in category {category}, "
|
|
117
|
+
f"skipping passed control test creation"
|
|
118
|
+
)
|
|
119
|
+
continue
|
|
120
|
+
passed_findings.append(
|
|
121
|
+
IntegrationFinding(
|
|
122
|
+
control_labels=[control_label.lower()],
|
|
123
|
+
title=f"{self.title} Control Assessment",
|
|
124
|
+
category=category,
|
|
125
|
+
description=control_test.get("description", ""),
|
|
126
|
+
severity=regscale_models.IssueSeverity.Low,
|
|
127
|
+
status=regscale_models.ControlTestResultStatus.PASS,
|
|
128
|
+
impact=regscale_models.IssueSeverity.Low,
|
|
129
|
+
plugin_name=category,
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
return passed_findings
|
|
133
|
+
|
|
134
|
+
def fetch_findings(self, **kwargs) -> List[IntegrationFinding]:
|
|
135
|
+
"""
|
|
136
|
+
Fetches GCP findings using the SecurityCenterClient
|
|
137
|
+
|
|
138
|
+
:return: A list of parsed findings
|
|
139
|
+
:rtype: List[IntegrationFinding]
|
|
140
|
+
"""
|
|
141
|
+
gcp_findings = self.get_failed_findings()
|
|
142
|
+
|
|
143
|
+
self.gcp_control_tests = copy.copy(gcp_control_tests)
|
|
144
|
+
failed_findings = list(filter(None, [self.parse_finding(finding.finding) for finding in gcp_findings]))
|
|
145
|
+
passed_findings = self.get_passed_findings()
|
|
146
|
+
return failed_findings + passed_findings
|
|
147
|
+
|
|
148
|
+
def parse_finding(self, gcp_finding: "Finding") -> Optional[IntegrationFinding]:
|
|
149
|
+
"""
|
|
150
|
+
Parses GCP findings
|
|
151
|
+
|
|
152
|
+
:param Finding gcp_finding: The GCP finding to parse
|
|
153
|
+
:return: The parsed IntegrationFinding
|
|
154
|
+
:rtype: Optional[IntegrationFinding]
|
|
155
|
+
"""
|
|
156
|
+
from google.cloud.securitycenter_v1 import Finding # Optimize import performance
|
|
157
|
+
|
|
158
|
+
if any(
|
|
159
|
+
control_labels := [
|
|
160
|
+
label.lower() for c in gcp_finding.compliances if c.standard == "nist" for label in c.ids
|
|
161
|
+
]
|
|
162
|
+
):
|
|
163
|
+
control_labels = [label.lower() for label in control_labels]
|
|
164
|
+
|
|
165
|
+
# Set control test status to failed since we found a finding for it
|
|
166
|
+
for control_label in control_labels:
|
|
167
|
+
# Ensure control_id is a string when used as a key
|
|
168
|
+
control_label = str(control_label)
|
|
169
|
+
if self.gcp_control_tests.get(control_label, {}).get(gcp_finding.category):
|
|
170
|
+
self.gcp_control_tests[control_label][gcp_finding.category]["status"] = "Failed"
|
|
171
|
+
|
|
172
|
+
severity = self.finding_severity_map.get(
|
|
173
|
+
gcp_finding.severity, regscale_models.IssueSeverity.Low
|
|
174
|
+
) # Default to Low
|
|
175
|
+
return IntegrationFinding(
|
|
176
|
+
control_labels=control_labels,
|
|
177
|
+
title=f"{self.title} Control Assessment",
|
|
178
|
+
category=gcp_finding.category,
|
|
179
|
+
description=gcp_finding.description,
|
|
180
|
+
severity=severity,
|
|
181
|
+
status=regscale_models.ControlTestResultStatus.FAIL,
|
|
182
|
+
external_id=gcp_finding.external_uri,
|
|
183
|
+
gaps=f"Resource out of compliance: {gcp_finding.resource_name}\n"
|
|
184
|
+
f"Recommendation: {gcp_finding.source_properties.get('Recommendation', '')}",
|
|
185
|
+
observations=gcp_finding.source_properties.get("Explanation", ""),
|
|
186
|
+
evidence=Finding.to_json(gcp_finding),
|
|
187
|
+
identified_risk=gcp_finding.source_properties.get("Explanation", ""),
|
|
188
|
+
impact=severity,
|
|
189
|
+
recommendation_for_mitigation=gcp_finding.source_properties.get("Recommendation", ""),
|
|
190
|
+
plugin_name=gcp_finding.category,
|
|
191
|
+
)
|
|
192
|
+
logger.info(f"Finding {gcp_finding.name} has no NIST controls.")
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
def fetch_assets(self):
|
|
196
|
+
"""
|
|
197
|
+
Fetches GCP assets using the AssetServiceClient
|
|
198
|
+
|
|
199
|
+
:yields: Iterator[IntegrationAsset]
|
|
200
|
+
"""
|
|
201
|
+
from google.cloud import asset_v1 # Optimize import performance
|
|
202
|
+
|
|
203
|
+
logger.info("Fetching GCP assets...")
|
|
204
|
+
client = get_gcp_asset_service_client()
|
|
205
|
+
if str(GcpVariables.gcpScanType) == "project": # type: ignore
|
|
206
|
+
sources = f"projects/{GcpVariables.gcpProjectId}"
|
|
207
|
+
else:
|
|
208
|
+
sources = f"organizations/{GcpVariables.gcpOrganizationId}"
|
|
209
|
+
request = asset_v1.ListAssetsRequest(parent=sources) # type: ignore
|
|
210
|
+
logger.info("Fetched GCP assets.")
|
|
211
|
+
self.num_assets_to_process = 0
|
|
212
|
+
for asset in client.list_assets(request=request):
|
|
213
|
+
self.num_assets_to_process += 1
|
|
214
|
+
yield self.parse_asset(asset)
|
|
215
|
+
|
|
216
|
+
def parse_asset(self, asset: "asset_v1.Asset") -> IntegrationAsset:
|
|
217
|
+
"""
|
|
218
|
+
Parses GCP assets
|
|
219
|
+
|
|
220
|
+
:param asset_v1.Asset asset: The GCP asset to parse
|
|
221
|
+
:return: The parsed IntegrationAsset
|
|
222
|
+
:rtype: IntegrationAsset
|
|
223
|
+
"""
|
|
224
|
+
from google.cloud import asset_v1 # type: ignore # Optimize import performance
|
|
225
|
+
|
|
226
|
+
return IntegrationAsset(
|
|
227
|
+
name=asset.name,
|
|
228
|
+
identifier=asset.name,
|
|
229
|
+
asset_type=asset.asset_type,
|
|
230
|
+
asset_owner_id=self.assessor_id,
|
|
231
|
+
parent_id=self.plan_id,
|
|
232
|
+
parent_module=regscale_models.SecurityPlan.get_module_slug(),
|
|
233
|
+
asset_category="GCP",
|
|
234
|
+
date_last_updated=asset.update_time.strftime(default_date_format),
|
|
235
|
+
component_names=[asset.asset_type],
|
|
236
|
+
status="Active (On Network)",
|
|
237
|
+
)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Sync GCP Authentication and Checks"""
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
5
|
+
|
|
6
|
+
if TYPE_CHECKING:
|
|
7
|
+
from google.cloud import securitycenter
|
|
8
|
+
from google.cloud import asset_v1
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
from regscale.core.app.utils.app_utils import error_and_exit
|
|
14
|
+
from regscale.integrations.commercial.gcp.variables import GcpVariables
|
|
15
|
+
|
|
16
|
+
logger = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def ensure_gcp_credentials() -> None:
|
|
20
|
+
"""
|
|
21
|
+
Ensures that the GCP credentials are set in the environment
|
|
22
|
+
|
|
23
|
+
:rtype: None
|
|
24
|
+
"""
|
|
25
|
+
if not os.environ.get("GOOGLE_APPLICATION_CREDENTIALS"):
|
|
26
|
+
os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = GcpVariables.gcpCredentials
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def ensure_gcp_api_enabled(service_name: str) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Ensures that the Security Center API is enabled
|
|
32
|
+
Checks if the API is enabled and raises an exception or prints a message if it is not
|
|
33
|
+
|
|
34
|
+
:param str service_name: The name of the service to check
|
|
35
|
+
:raises RuntimeError: If the API is not enabled or any other error occurs
|
|
36
|
+
:rtype: None
|
|
37
|
+
"""
|
|
38
|
+
from google.auth.exceptions import GoogleAuthError # Optimize import performance
|
|
39
|
+
from googleapiclient.discovery import build # Optimize import performance
|
|
40
|
+
|
|
41
|
+
ensure_gcp_credentials() # Assuming this function sets up authentication
|
|
42
|
+
project_id = GcpVariables.gcpProjectId
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
service = build("serviceusage", "v1")
|
|
46
|
+
request = service.services().get(name=f"projects/{project_id}/services/{service_name}")
|
|
47
|
+
response = request.execute()
|
|
48
|
+
|
|
49
|
+
if response and response.get("state") == "ENABLED":
|
|
50
|
+
logger.info(f"{service_name} api is enabled for project {project_id}.")
|
|
51
|
+
else:
|
|
52
|
+
error_and_exit(
|
|
53
|
+
f"{service_name} api is not enabled for project {project_id}. Please enable it.\n"
|
|
54
|
+
f"Run the following command:\n"
|
|
55
|
+
f"gcloud services enable {service_name} --project {project_id}"
|
|
56
|
+
)
|
|
57
|
+
except GoogleAuthError as e:
|
|
58
|
+
raise RuntimeError(f"Authentication error: {e}")
|
|
59
|
+
except Exception as e:
|
|
60
|
+
raise RuntimeError(f"An error occurred: {e}")
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def ensure_security_center_api_enabled() -> None:
|
|
64
|
+
"""
|
|
65
|
+
Ensures that the Security Center API is enabled
|
|
66
|
+
|
|
67
|
+
:rtype: None
|
|
68
|
+
"""
|
|
69
|
+
ensure_gcp_credentials()
|
|
70
|
+
os.system(f"gcloud services enable securitycenter.googleapis.com --project {GcpVariables.gcpProjectId}")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def get_gcp_security_center_client() -> "securitycenter.SecurityCenterClient":
|
|
74
|
+
"""
|
|
75
|
+
Gets the GCP Security Center client
|
|
76
|
+
|
|
77
|
+
:return: The GCP client
|
|
78
|
+
:rtype: securitycenter.SecurityCenterClient
|
|
79
|
+
"""
|
|
80
|
+
from google.cloud import securitycenter # Optimize import performance
|
|
81
|
+
|
|
82
|
+
ensure_gcp_api_enabled("securitycenter.googleapis.com")
|
|
83
|
+
return securitycenter.SecurityCenterClient()
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def get_gcp_asset_service_client() -> "asset_v1.AssetServiceClient":
|
|
87
|
+
"""
|
|
88
|
+
Gets the GCP Asset Service client
|
|
89
|
+
|
|
90
|
+
:return: The GCP client
|
|
91
|
+
:rtype: asset_v1.AssetServiceClient
|
|
92
|
+
"""
|
|
93
|
+
from google.cloud import asset_v1 # Optimize import performance
|
|
94
|
+
|
|
95
|
+
ensure_gcp_api_enabled("cloudasset.googleapis.com")
|
|
96
|
+
return asset_v1.AssetServiceClient()
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
gcp_control_tests = {
|
|
2
|
+
"ac-2": {
|
|
3
|
+
"PUBLIC_BUCKET_ACL": {
|
|
4
|
+
"severity": "HIGH",
|
|
5
|
+
"description": "Cloud Storage buckets should not be anonymously or publicly accessible",
|
|
6
|
+
},
|
|
7
|
+
"PUBLIC_DATASET": {
|
|
8
|
+
"severity": "HIGH",
|
|
9
|
+
"description": "Datasets should not be publicly accessible by anyone on the internet",
|
|
10
|
+
},
|
|
11
|
+
"AUDIT_LOGGING_DISABLED": {
|
|
12
|
+
"severity": "LOW",
|
|
13
|
+
"description": "Cloud Audit Logging should be configured properly across all services and all users from a "
|
|
14
|
+
"project",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
"au-2": {
|
|
18
|
+
"AUDIT_LOGGING_DISABLED": {
|
|
19
|
+
"severity": "LOW",
|
|
20
|
+
"description": "Cloud Audit Logging should be configured properly across all services and all users from a "
|
|
21
|
+
"project",
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"ac-3": {
|
|
25
|
+
"NON_ORG_IAM_MEMBER": {
|
|
26
|
+
"severity": "HIGH",
|
|
27
|
+
"description": "Corporate login credentials should be used instead of Gmail accounts",
|
|
28
|
+
},
|
|
29
|
+
"SQL_NO_ROOT_PASSWORD": {
|
|
30
|
+
"severity": "HIGH",
|
|
31
|
+
"description": "MySQL database instance should not allow anyone to connect with administrative privileges.",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
"ac-5": {
|
|
35
|
+
"KMS_ROLE_SEPARATION": {
|
|
36
|
+
"severity": "MEDIUM",
|
|
37
|
+
"description": "Separation of duties should be enforced while assigning KMS related roles to users",
|
|
38
|
+
},
|
|
39
|
+
"SERVICE_ACCOUNT_ROLE_SEPARATION": {
|
|
40
|
+
"severity": "MEDIUM",
|
|
41
|
+
"description": "Separation of duties should be enforced while assigning service account related roles to "
|
|
42
|
+
"users",
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
"ac-6": {
|
|
46
|
+
"FULL_API_ACCESS": {
|
|
47
|
+
"severity": "MEDIUM",
|
|
48
|
+
"description": "Instances should not be configured to use the default service account with full access to "
|
|
49
|
+
"all Cloud APIs",
|
|
50
|
+
},
|
|
51
|
+
"OVER_PRIVILEGED_SERVICE_ACCOUNT_USER": {
|
|
52
|
+
"severity": "MEDIUM",
|
|
53
|
+
"description": "The iam.serviceAccountUser and iam.serviceAccountTokenCreator roles should not be assigned "
|
|
54
|
+
"to a user at the project level",
|
|
55
|
+
},
|
|
56
|
+
"PRIMITIVE_ROLES_USED": {
|
|
57
|
+
"severity": "MEDIUM",
|
|
58
|
+
"description": "Basic roles (Owner, Writer, Reader) are too permissive and should not be used",
|
|
59
|
+
},
|
|
60
|
+
"OVER_PRIVILEGED_ACCOUNT": {
|
|
61
|
+
"severity": "MEDIUM",
|
|
62
|
+
"description": "Default Service account should not used for Project access in Kubernetes Clusters",
|
|
63
|
+
},
|
|
64
|
+
"KMS_PROJECT_HAS_OWNER": {
|
|
65
|
+
"severity": "MEDIUM",
|
|
66
|
+
"description": 'Users should not have "Owner" permissions on a project that has cryptographic keys',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
"au-9": {
|
|
70
|
+
"PUBLIC_LOG_BUCKET": {
|
|
71
|
+
"severity": "HIGH",
|
|
72
|
+
"description": "Storage buckets used as log sinks should not be publicly accessible",
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"au-11": {
|
|
76
|
+
"LOCKED_RETENTION_POLICY_NOT_SET": {
|
|
77
|
+
"severity": "LOW",
|
|
78
|
+
"description": "A locked retention policy should be configured for Cloud Storage buckets",
|
|
79
|
+
},
|
|
80
|
+
"OBJECT_VERSIONING_DISABLED": {
|
|
81
|
+
"severity": "LOW",
|
|
82
|
+
"description": "Log-buckets should have Object Versioning enabled",
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
"ca-3": {
|
|
86
|
+
"PUBLIC_IP_ADDRESS": {
|
|
87
|
+
"severity": "HIGH",
|
|
88
|
+
"description": "VMs should not be assigned public IP addresses",
|
|
89
|
+
},
|
|
90
|
+
"PUBLIC_SQL_INSTANCE": {
|
|
91
|
+
"severity": "HIGH",
|
|
92
|
+
"description": "Cloud SQL database instances should not be publicly accessible by anyone on the internet",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
"cp-9": {
|
|
96
|
+
"AUTO_BACKUP_DISABLED": {
|
|
97
|
+
"severity": "MEDIUM",
|
|
98
|
+
"description": "Automated backups should be Enabled",
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"ia-2": {
|
|
102
|
+
"MFA_NOT_ENFORCED": {
|
|
103
|
+
"severity": "HIGH",
|
|
104
|
+
"description": "Multi-factor authentication should be enabled for all users in your org unit",
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
"sc-7": {
|
|
108
|
+
"OVER_PRIVILEGED_ACCOUNT": {
|
|
109
|
+
"severity": "MEDIUM",
|
|
110
|
+
"description": "Default Service account should not used for Project access in Kubernetes Clusters",
|
|
111
|
+
},
|
|
112
|
+
"PUBLIC_IP_ADDRESS": {
|
|
113
|
+
"severity": "HIGH",
|
|
114
|
+
"description": "VMs should not be assigned public IP addresses",
|
|
115
|
+
},
|
|
116
|
+
"PUBLIC_SQL_INSTANCE": {
|
|
117
|
+
"severity": "HIGH",
|
|
118
|
+
"description": "Cloud SQL database instances should not be publicly accessible by anyone on the internet",
|
|
119
|
+
},
|
|
120
|
+
"NETWORK_POLICY_DISABLED": {
|
|
121
|
+
"severity": "MEDIUM",
|
|
122
|
+
"description": "Network policy should be Enabled on Kubernetes Engine Clusters",
|
|
123
|
+
},
|
|
124
|
+
"OPEN_CASSANDRA_PORT": {
|
|
125
|
+
"severity": "HIGH",
|
|
126
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP ports 7000-7001, "
|
|
127
|
+
"7199, 8888, 9042, 9160, 61620-61621",
|
|
128
|
+
},
|
|
129
|
+
"OPEN_CISCOSECURE_WEBSM_PORT": {
|
|
130
|
+
"severity": "HIGH",
|
|
131
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 9090",
|
|
132
|
+
},
|
|
133
|
+
"OPEN_DIRECTORY_SERVICES_PORT": {
|
|
134
|
+
"severity": "HIGH",
|
|
135
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP or UDP port 445",
|
|
136
|
+
},
|
|
137
|
+
"OPEN_DNS_PORT": {
|
|
138
|
+
"severity": "HIGH",
|
|
139
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP or UDP port 53",
|
|
140
|
+
},
|
|
141
|
+
"OPEN_ELASTICSEARCH_PORT": {
|
|
142
|
+
"severity": "HIGH",
|
|
143
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP ports 9200, 9300",
|
|
144
|
+
},
|
|
145
|
+
"OPEN_FTP_PORT": {
|
|
146
|
+
"severity": "HIGH",
|
|
147
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 21",
|
|
148
|
+
},
|
|
149
|
+
"OPEN_HTTP_PORT": {
|
|
150
|
+
"severity": "HIGH",
|
|
151
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 80",
|
|
152
|
+
},
|
|
153
|
+
"OPEN_LDAP_PORT": {
|
|
154
|
+
"severity": "HIGH",
|
|
155
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP ports 389, 636"
|
|
156
|
+
" or UDP port 389",
|
|
157
|
+
},
|
|
158
|
+
"OPEN_MEMCACHED_PORT": {
|
|
159
|
+
"severity": "HIGH",
|
|
160
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP ports 11211, "
|
|
161
|
+
"11214-11215 or UDP ports 11211, 11214-11215",
|
|
162
|
+
},
|
|
163
|
+
"OPEN_MONGODB_PORT": {
|
|
164
|
+
"severity": "HIGH",
|
|
165
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP ports 27017-27019",
|
|
166
|
+
},
|
|
167
|
+
"OPEN_MYSQL_PORT": {
|
|
168
|
+
"severity": "HIGH",
|
|
169
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 3306",
|
|
170
|
+
},
|
|
171
|
+
"OPEN_NETBIOS_PORT": {
|
|
172
|
+
"severity": "HIGH",
|
|
173
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP or UDP ports "
|
|
174
|
+
"137-139",
|
|
175
|
+
},
|
|
176
|
+
"OPEN_ORACLEDB_PORT": {
|
|
177
|
+
"severity": "HIGH",
|
|
178
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP ports 1521, "
|
|
179
|
+
"2483-2484 or UDP ports 2483-2484",
|
|
180
|
+
},
|
|
181
|
+
"OPEN_POP3_PORT": {
|
|
182
|
+
"severity": "HIGH",
|
|
183
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 110",
|
|
184
|
+
},
|
|
185
|
+
"OPEN_POSTGRESQL_PORT": {
|
|
186
|
+
"severity": "HIGH",
|
|
187
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP or UDP port 5432",
|
|
188
|
+
},
|
|
189
|
+
"OPEN_RDP_PORT": {
|
|
190
|
+
"severity": "HIGH",
|
|
191
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP or UDP port 3389",
|
|
192
|
+
},
|
|
193
|
+
"OPEN_REDIS_PORT": {
|
|
194
|
+
"severity": "HIGH",
|
|
195
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 6379",
|
|
196
|
+
},
|
|
197
|
+
"OPEN_SMTP_PORT": {
|
|
198
|
+
"severity": "HIGH",
|
|
199
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 25",
|
|
200
|
+
},
|
|
201
|
+
"OPEN_SSH_PORT": {
|
|
202
|
+
"severity": "HIGH",
|
|
203
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP or SCTP port 22",
|
|
204
|
+
},
|
|
205
|
+
"OPEN_TELNET_PORT": {
|
|
206
|
+
"severity": "HIGH",
|
|
207
|
+
"description": "Firewall rules should not allow connections from all IP addresses on TCP port 23",
|
|
208
|
+
},
|
|
209
|
+
"SSL_NOT_ENFORCED": {
|
|
210
|
+
"severity": "HIGH",
|
|
211
|
+
"description": "Cloud SQL database instance should require all incoming connections to use SSL",
|
|
212
|
+
},
|
|
213
|
+
"WEAK_SSL_POLICY": {
|
|
214
|
+
"severity": "MEDIUM",
|
|
215
|
+
"description": "Weak or insecure SSL Policys should not be used",
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
"sc-12": {
|
|
219
|
+
"KMS_PROJECT_HAS_OWNER": {
|
|
220
|
+
"severity": "MEDIUM",
|
|
221
|
+
"description": 'Users should not have "Owner" permissions on a project that has cryptographic keys',
|
|
222
|
+
},
|
|
223
|
+
"KMS_KEY_NOT_ROTATED": {
|
|
224
|
+
"severity": "MEDIUM",
|
|
225
|
+
"description": "Encryption keys should be rotated within a period of 90 days",
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
"si-4": {
|
|
229
|
+
"FIREWALL_RULE_LOGGING_DISABLED": {
|
|
230
|
+
"severity": "MEDIUM",
|
|
231
|
+
"description": "Firewall rule logging should be enabled so you can audit network access",
|
|
232
|
+
},
|
|
233
|
+
"FLOW_LOGS_DISABLED": {
|
|
234
|
+
"severity": "LOW",
|
|
235
|
+
"description": "VPC Flow logs should be Enabled for every subnet in VPC Network",
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""GCP Variables"""
|
|
4
|
+
|
|
5
|
+
from regscale.core.app.utils.variables import RsVariableType, RsVariablesMeta
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GcpVariables(metaclass=RsVariablesMeta):
|
|
9
|
+
"""
|
|
10
|
+
GCP Variables class to define class-level attributes with type annotations and examples
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# Define class-level attributes with type annotations and examples
|
|
14
|
+
gcpProjectId: RsVariableType(str, "000000000000") # type: ignore
|
|
15
|
+
gcpOrganizationId: RsVariableType(str, "000000000000") # type: ignore
|
|
16
|
+
gcpScanType: RsVariableType(str, "organization | project") # type: ignore # noqa: F821
|
|
17
|
+
gcpCredentials: RsVariableType(str, "path/to/credentials.json") # type: ignore # noqa: F821
|
|
18
|
+
# gcpOrganizationId: RsVariableTypeWithExample(str, "000000000000", required=False)
|