ventra 1.0.1__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.
- app/__init__.py +8 -0
- app/config.py +88 -0
- app/config_store.py +147 -0
- app/evidence.py +243 -0
- app/export_jobs.py +486 -0
- app/host_check.py +70 -0
- app/main.py +1575 -0
- app/rbac/__init__.py +60 -0
- app/run_service.py +593 -0
- app/run_store.py +245 -0
- app/store.py +2372 -0
- collector/__init__.py +34 -0
- collector/__main__.py +51 -0
- collector/_artifacts/aws/detections/detective.yaml +25 -0
- collector/_artifacts/aws/detections/guardduty.yaml +29 -0
- collector/_artifacts/aws/detections/inspector2.yaml +25 -0
- collector/_artifacts/aws/detections/macie.yaml +26 -0
- collector/_artifacts/aws/detections/securityhub.yaml +26 -0
- collector/_artifacts/aws/identity/account.yaml +27 -0
- collector/_artifacts/aws/identity/iam.yaml +47 -0
- collector/_artifacts/aws/identity/kms.yaml +27 -0
- collector/_artifacts/aws/identity/secrets.yaml +25 -0
- collector/_artifacts/aws/management-plane/cloudtrail.yaml +36 -0
- collector/_artifacts/aws/management-plane/cloudwatch.yaml +41 -0
- collector/_artifacts/aws/management-plane/config.yaml +26 -0
- collector/_artifacts/aws/management-plane/log_posture.yaml +31 -0
- collector/_artifacts/aws/network/apigateway.yaml +25 -0
- collector/_artifacts/aws/network/cloudfront.yaml +28 -0
- collector/_artifacts/aws/network/elb_alb.yaml +28 -0
- collector/_artifacts/aws/network/route53_resolver.yaml +29 -0
- collector/_artifacts/aws/network/vpc_flow.yaml +52 -0
- collector/_artifacts/aws/network/waf.yaml +27 -0
- collector/_artifacts/aws/workloads/ec2.yaml +32 -0
- collector/_artifacts/aws/workloads/eks_audit.yaml +26 -0
- collector/_artifacts/aws/workloads/lambda.yaml +26 -0
- collector/_artifacts/aws/workloads/lambda_logs.yaml +26 -0
- collector/_artifacts/aws/workloads/rds.yaml +25 -0
- collector/_artifacts/aws/workloads/s3.yaml +31 -0
- collector/_artifacts/aws/workloads/s3_access.yaml +28 -0
- collector/_artifacts/azure/detections/defender.yaml +25 -0
- collector/_artifacts/azure/identity/entra_audit.yaml +26 -0
- collector/_artifacts/azure/identity/entra_directory.yaml +27 -0
- collector/_artifacts/azure/identity/entra_signin.yaml +25 -0
- collector/_artifacts/azure/identity/oauth_consent.yaml +25 -0
- collector/_artifacts/azure/identity/rbac.yaml +25 -0
- collector/_artifacts/azure/identity/subscription.yaml +25 -0
- collector/_artifacts/azure/management-plane/activity_log.yaml +25 -0
- collector/_artifacts/azure/management-plane/diag_posture.yaml +26 -0
- collector/_artifacts/azure/management-plane/resource_graph.yaml +24 -0
- collector/_artifacts/azure/network/app_gateway.yaml +26 -0
- collector/_artifacts/azure/network/azure_firewall.yaml +26 -0
- collector/_artifacts/azure/network/dns.yaml +28 -0
- collector/_artifacts/azure/network/front_door.yaml +27 -0
- collector/_artifacts/azure/network/nsg_flow.yaml +25 -0
- collector/_artifacts/azure/network/vnet_flow.yaml +26 -0
- collector/_artifacts/azure/workloads/aks_audit.yaml +26 -0
- collector/_artifacts/azure/workloads/key_vault.yaml +26 -0
- collector/_artifacts/azure/workloads/storage_access.yaml +26 -0
- collector/_artifacts/gcp/data_storage/bigquery_audit.yaml +25 -0
- collector/_artifacts/gcp/data_storage/cloud_sql.yaml +24 -0
- collector/_artifacts/gcp/data_storage/secret_manager.yaml +25 -0
- collector/_artifacts/gcp/detections/cloud_monitoring.yaml +25 -0
- collector/_artifacts/gcp/detections/scc_findings.yaml +24 -0
- collector/_artifacts/gcp/identity/iam_policy.yaml +30 -0
- collector/_artifacts/gcp/identity/login_events.yaml +25 -0
- collector/_artifacts/gcp/identity/project.yaml +24 -0
- collector/_artifacts/gcp/management-plane/cloud_audit_admin.yaml +24 -0
- collector/_artifacts/gcp/management-plane/cloud_audit_data.yaml +26 -0
- collector/_artifacts/gcp/management-plane/cloud_audit_system.yaml +24 -0
- collector/_artifacts/gcp/management-plane/logging_posture.yaml +27 -0
- collector/_artifacts/gcp/network/api_gateway.yaml +24 -0
- collector/_artifacts/gcp/network/cloud_armor.yaml +25 -0
- collector/_artifacts/gcp/network/cloud_cdn.yaml +24 -0
- collector/_artifacts/gcp/network/cloud_dns.yaml +24 -0
- collector/_artifacts/gcp/network/cloud_nat.yaml +24 -0
- collector/_artifacts/gcp/network/firewall_logs.yaml +24 -0
- collector/_artifacts/gcp/network/load_balancer.yaml +24 -0
- collector/_artifacts/gcp/network/network_posture.yaml +29 -0
- collector/_artifacts/gcp/network/vpc_flow.yaml +25 -0
- collector/_artifacts/gcp/workloads/cloud_functions.yaml +24 -0
- collector/_artifacts/gcp/workloads/gce.yaml +26 -0
- collector/_artifacts/gcp/workloads/gke_audit.yaml +25 -0
- collector/_artifacts/gcp/workloads/storage_access.yaml +25 -0
- collector/_artifacts/gcp/workloads/vm_logs.yaml +24 -0
- collector/_artifacts/kubernetes/audit/k8s_apiserver_audit.yaml +30 -0
- collector/_artifacts/kubernetes/audit/k8s_audit_posture.yaml +24 -0
- collector/_artifacts/kubernetes/events/k8s_events.yaml +34 -0
- collector/_artifacts/kubernetes/network/k8s_cni_logs.yaml +22 -0
- collector/_artifacts/kubernetes/node/k8s_container_logs.yaml +25 -0
- collector/_artifacts/kubernetes/node/k8s_etcd.yaml +37 -0
- collector/_artifacts/kubernetes/node/k8s_kubelet_logs.yaml +24 -0
- collector/_artifacts/kubernetes/node/k8s_runtime_logs.yaml +29 -0
- collector/_artifacts/kubernetes/state/k8s_cluster_state.yaml +51 -0
- collector/_artifacts/kubernetes/state/k8s_rbac.yaml +27 -0
- collector/_artifacts/packs/baseline-ir-aws.yaml +11 -0
- collector/_artifacts/packs/baseline-ir-azure.yaml +20 -0
- collector/_artifacts/packs/baseline-ir-gcp.yaml +31 -0
- collector/_artifacts/packs/baseline-ir-kubernetes.yaml +18 -0
- collector/_console_static/404/index.html +1 -0
- collector/_console_static/404.html +1 -0
- collector/_console_static/_next/static/MtMFfGcEnM98E78OauMI0/_buildManifest.js +1 -0
- collector/_console_static/_next/static/MtMFfGcEnM98E78OauMI0/_ssgManifest.js +1 -0
- collector/_console_static/_next/static/chunks/1255-0947d73a7b5cc8f1.js +1 -0
- collector/_console_static/_next/static/chunks/1266-103fab4de22eef44.js +1 -0
- collector/_console_static/_next/static/chunks/1461-a2e332e00c52d6d0.js +1 -0
- collector/_console_static/_next/static/chunks/1468-e6d31bced036f7f3.js +1 -0
- collector/_console_static/_next/static/chunks/1601-20d8f2e10e1bd9cd.js +1 -0
- collector/_console_static/_next/static/chunks/2146-186c87be914470b7.js +1 -0
- collector/_console_static/_next/static/chunks/2619-04bc32f026a0d946.js +1 -0
- collector/_console_static/_next/static/chunks/3007-1a62fdd6aea1c4ca.js +1 -0
- collector/_console_static/_next/static/chunks/3510-a72d6ab06034fc56.js +1 -0
- collector/_console_static/_next/static/chunks/3728-98fd2ba4e7d635b1.js +1 -0
- collector/_console_static/_next/static/chunks/3941-e2240f6908b2ad35.js +1 -0
- collector/_console_static/_next/static/chunks/4748-07689affc96b2fe8.js +1 -0
- collector/_console_static/_next/static/chunks/4bd1b696-100b9d70ed4e49c1.js +1 -0
- collector/_console_static/_next/static/chunks/5147-7ebb875daf2e6bf2.js +1 -0
- collector/_console_static/_next/static/chunks/5239-09682fb347c4abaf.js +1 -0
- collector/_console_static/_next/static/chunks/549-6880f7361258a1b8.js +1 -0
- collector/_console_static/_next/static/chunks/5854-298f1ef2c6686ae6.js +1 -0
- collector/_console_static/_next/static/chunks/641-a5f2fef4bdebe348.js +1 -0
- collector/_console_static/_next/static/chunks/6944-863cf476fca75059.js +1 -0
- collector/_console_static/_next/static/chunks/7490-3e1cd1b34217dcd9.js +1 -0
- collector/_console_static/_next/static/chunks/8400-2a314fd4cb643bf9.js +1 -0
- collector/_console_static/_next/static/chunks/8780-a222f415a2bcef40.js +1 -0
- collector/_console_static/_next/static/chunks/92-f8cbc3ff974e4a52.js +1 -0
- collector/_console_static/_next/static/chunks/9346-05757e302343e5ed.js +1 -0
- collector/_console_static/_next/static/chunks/9455-c8997e5d0baa3c3e.js +1 -0
- collector/_console_static/_next/static/chunks/9957-fb2904da27189f18.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/acquire/page-edef9794fd2e9479.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/cloudtrail/page-cf0e66e4ccea2e6b.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/cloudwatch/page-7918deb8fe178aac.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/collection/page-fd92b7ea856e4ada.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/data-access/page-6c18cffcbeead99b.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/files/page-0218775b330fca1c.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/identity/page-b0e1f100f755e700.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/kubernetes-audit/page-2cd7f2f3a940d7cb.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/layout-6a639a258737efeb.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/network/page-78db9bcb7b5195d0.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/overview/page-0dba5b2cec8f67bc.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/page-fd9f1e9324107213.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/report/page-24e5da3193e7deb0.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/resources/page-1541a4757830de28.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/search/page-c5ffabb83b5f11c1.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/settings/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/[caseId]/web/page-e15dfeaadd3becc0.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/cases/page-bce0fc72e62e7477.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/collection-kits/page-7c8e3a5105c914da.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/config/acquire/page-676aa2404d64c047.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/config/collection/page-c40279b8885b509a.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/config/connections/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/config/log-backends/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/config/profiles/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/config/providers/page-818855b2f0fb77aa.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/[section]/layout-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/[section]/page-38831a7ddd1cea3e.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/collectors/[collector]/layout-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/collectors/[collector]/page-17a41a4b5d8c046c.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/layout-1ca683015f4ff55b.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/docs/[provider]/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/docs/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/export/page-714c75a583c9c6b9.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/layout-50b162154ff6dcb2.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/runs/[runId]/layout-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/runs/[runId]/page-a7e8f34c3afd21ab.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/runs/new/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/runs/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/app/(app)/settings/page-347f0ee57bb85823.js +1 -0
- collector/_console_static/_next/static/chunks/app/_not-found/page-bd13c288a670cf32.js +1 -0
- collector/_console_static/_next/static/chunks/app/layout-4515ba368d27a1a1.js +1 -0
- collector/_console_static/_next/static/chunks/app/page-d4f8bb2a7fc52650.js +1 -0
- collector/_console_static/_next/static/chunks/c15bf2b0-bfa95b308e62c6cc.js +1 -0
- collector/_console_static/_next/static/chunks/framework-5991737ec854c1b5.js +1 -0
- collector/_console_static/_next/static/chunks/main-4e71f9d188d19f9d.js +1 -0
- collector/_console_static/_next/static/chunks/main-app-2b75a469bce105eb.js +1 -0
- collector/_console_static/_next/static/chunks/pages/_app-4b3fb5e477a0267f.js +1 -0
- collector/_console_static/_next/static/chunks/pages/_error-c970d8b55ace1b48.js +1 -0
- collector/_console_static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
- collector/_console_static/_next/static/chunks/webpack-9a54ed35a2898709.js +1 -0
- collector/_console_static/_next/static/css/ec2686d88207223d.css +3 -0
- collector/_console_static/_next/static/css/f9729d2dd4e50ad2.css +1 -0
- collector/_console_static/_next/static/media/e91e1ff17da97c42-s.p.woff2 +0 -0
- collector/_console_static/_next/static/media/f5cb94a89b585f0b.p.woff2 +0 -0
- collector/_console_static/acquire/index.html +1 -0
- collector/_console_static/acquire/index.txt +26 -0
- collector/_console_static/cases/_/cloudtrail/index.html +1 -0
- collector/_console_static/cases/_/cloudtrail/index.txt +27 -0
- collector/_console_static/cases/_/cloudwatch/index.html +1 -0
- collector/_console_static/cases/_/cloudwatch/index.txt +27 -0
- collector/_console_static/cases/_/collection/index.html +1 -0
- collector/_console_static/cases/_/collection/index.txt +27 -0
- collector/_console_static/cases/_/data-access/index.html +1 -0
- collector/_console_static/cases/_/data-access/index.txt +27 -0
- collector/_console_static/cases/_/files/index.html +1 -0
- collector/_console_static/cases/_/files/index.txt +27 -0
- collector/_console_static/cases/_/identity/index.html +1 -0
- collector/_console_static/cases/_/identity/index.txt +27 -0
- collector/_console_static/cases/_/index.html +1 -0
- collector/_console_static/cases/_/index.txt +27 -0
- collector/_console_static/cases/_/kubernetes-audit/index.html +1 -0
- collector/_console_static/cases/_/kubernetes-audit/index.txt +27 -0
- collector/_console_static/cases/_/network/index.html +1 -0
- collector/_console_static/cases/_/network/index.txt +27 -0
- collector/_console_static/cases/_/overview/index.html +1 -0
- collector/_console_static/cases/_/overview/index.txt +27 -0
- collector/_console_static/cases/_/report/index.html +1 -0
- collector/_console_static/cases/_/report/index.txt +27 -0
- collector/_console_static/cases/_/resources/index.html +1 -0
- collector/_console_static/cases/_/resources/index.txt +27 -0
- collector/_console_static/cases/_/search/index.html +1 -0
- collector/_console_static/cases/_/search/index.txt +27 -0
- collector/_console_static/cases/_/settings/index.html +1 -0
- collector/_console_static/cases/_/settings/index.txt +24 -0
- collector/_console_static/cases/_/web/index.html +1 -0
- collector/_console_static/cases/_/web/index.txt +27 -0
- collector/_console_static/cases/index.html +1 -0
- collector/_console_static/cases/index.txt +26 -0
- collector/_console_static/collection-kits/index.html +1 -0
- collector/_console_static/collection-kits/index.txt +26 -0
- collector/_console_static/config/acquire/index.html +1 -0
- collector/_console_static/config/acquire/index.txt +26 -0
- collector/_console_static/config/collection/index.html +1 -0
- collector/_console_static/config/collection/index.txt +26 -0
- collector/_console_static/config/connections/index.html +1 -0
- collector/_console_static/config/connections/index.txt +23 -0
- collector/_console_static/config/log-backends/index.html +1 -0
- collector/_console_static/config/log-backends/index.txt +23 -0
- collector/_console_static/config/profiles/index.html +1 -0
- collector/_console_static/config/profiles/index.txt +23 -0
- collector/_console_static/config/providers/index.html +1 -0
- collector/_console_static/config/providers/index.txt +26 -0
- collector/_console_static/docs/aws/authentication/index.html +1 -0
- collector/_console_static/docs/aws/authentication/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/_/index.html +1 -0
- collector/_console_static/docs/aws/collectors/_/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/account/index.html +1 -0
- collector/_console_static/docs/aws/collectors/account/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/apigateway/index.html +1 -0
- collector/_console_static/docs/aws/collectors/apigateway/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/cloudfront/index.html +1 -0
- collector/_console_static/docs/aws/collectors/cloudfront/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/cloudtrail/index.html +1 -0
- collector/_console_static/docs/aws/collectors/cloudtrail/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/cloudwatch/index.html +1 -0
- collector/_console_static/docs/aws/collectors/cloudwatch/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/config/index.html +1 -0
- collector/_console_static/docs/aws/collectors/config/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/detective/index.html +1 -0
- collector/_console_static/docs/aws/collectors/detective/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/ec2/index.html +1 -0
- collector/_console_static/docs/aws/collectors/ec2/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/eks_audit/index.html +1 -0
- collector/_console_static/docs/aws/collectors/eks_audit/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/elb_alb/index.html +1 -0
- collector/_console_static/docs/aws/collectors/elb_alb/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/guardduty/index.html +1 -0
- collector/_console_static/docs/aws/collectors/guardduty/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/iam/index.html +1 -0
- collector/_console_static/docs/aws/collectors/iam/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/index.html +1 -0
- collector/_console_static/docs/aws/collectors/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/inspector2/index.html +1 -0
- collector/_console_static/docs/aws/collectors/inspector2/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/kms/index.html +1 -0
- collector/_console_static/docs/aws/collectors/kms/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/lambda/index.html +1 -0
- collector/_console_static/docs/aws/collectors/lambda/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/lambda_logs/index.html +1 -0
- collector/_console_static/docs/aws/collectors/lambda_logs/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/log_posture/index.html +1 -0
- collector/_console_static/docs/aws/collectors/log_posture/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/macie/index.html +1 -0
- collector/_console_static/docs/aws/collectors/macie/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/rds/index.html +1 -0
- collector/_console_static/docs/aws/collectors/rds/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/route53_resolver/index.html +1 -0
- collector/_console_static/docs/aws/collectors/route53_resolver/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/s3/index.html +1 -0
- collector/_console_static/docs/aws/collectors/s3/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/s3_access/index.html +1 -0
- collector/_console_static/docs/aws/collectors/s3_access/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/secrets/index.html +1 -0
- collector/_console_static/docs/aws/collectors/secrets/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/securityhub/index.html +1 -0
- collector/_console_static/docs/aws/collectors/securityhub/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/vpc_flow/index.html +1 -0
- collector/_console_static/docs/aws/collectors/vpc_flow/index.txt +27 -0
- collector/_console_static/docs/aws/collectors/waf/index.html +1 -0
- collector/_console_static/docs/aws/collectors/waf/index.txt +27 -0
- collector/_console_static/docs/aws/connections/index.html +1 -0
- collector/_console_static/docs/aws/connections/index.txt +27 -0
- collector/_console_static/docs/aws/index.html +1 -0
- collector/_console_static/docs/aws/index.txt +24 -0
- collector/_console_static/docs/aws/permissions/index.html +1 -0
- collector/_console_static/docs/aws/permissions/index.txt +27 -0
- collector/_console_static/docs/azure/authentication/index.html +1 -0
- collector/_console_static/docs/azure/authentication/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/_/index.html +1 -0
- collector/_console_static/docs/azure/collectors/_/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/activity_log/index.html +1 -0
- collector/_console_static/docs/azure/collectors/activity_log/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/aks_audit/index.html +1 -0
- collector/_console_static/docs/azure/collectors/aks_audit/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/app_gateway/index.html +1 -0
- collector/_console_static/docs/azure/collectors/app_gateway/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/azure_firewall/index.html +1 -0
- collector/_console_static/docs/azure/collectors/azure_firewall/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/defender/index.html +1 -0
- collector/_console_static/docs/azure/collectors/defender/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/diag_posture/index.html +1 -0
- collector/_console_static/docs/azure/collectors/diag_posture/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/dns/index.html +1 -0
- collector/_console_static/docs/azure/collectors/dns/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/entra_audit/index.html +1 -0
- collector/_console_static/docs/azure/collectors/entra_audit/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/entra_directory/index.html +1 -0
- collector/_console_static/docs/azure/collectors/entra_directory/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/entra_signin/index.html +1 -0
- collector/_console_static/docs/azure/collectors/entra_signin/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/front_door/index.html +1 -0
- collector/_console_static/docs/azure/collectors/front_door/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/index.html +1 -0
- collector/_console_static/docs/azure/collectors/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/key_vault/index.html +1 -0
- collector/_console_static/docs/azure/collectors/key_vault/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/nsg_flow/index.html +1 -0
- collector/_console_static/docs/azure/collectors/nsg_flow/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/oauth_consent/index.html +1 -0
- collector/_console_static/docs/azure/collectors/oauth_consent/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/rbac/index.html +1 -0
- collector/_console_static/docs/azure/collectors/rbac/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/resource_graph/index.html +1 -0
- collector/_console_static/docs/azure/collectors/resource_graph/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/storage_access/index.html +1 -0
- collector/_console_static/docs/azure/collectors/storage_access/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/subscription/index.html +1 -0
- collector/_console_static/docs/azure/collectors/subscription/index.txt +27 -0
- collector/_console_static/docs/azure/collectors/vnet_flow/index.html +1 -0
- collector/_console_static/docs/azure/collectors/vnet_flow/index.txt +27 -0
- collector/_console_static/docs/azure/connections/index.html +1 -0
- collector/_console_static/docs/azure/connections/index.txt +27 -0
- collector/_console_static/docs/azure/index.html +1 -0
- collector/_console_static/docs/azure/index.txt +24 -0
- collector/_console_static/docs/azure/permissions/index.html +1 -0
- collector/_console_static/docs/azure/permissions/index.txt +27 -0
- collector/_console_static/docs/deployment/aws/cloudformation/ventra-collector-iam.yaml +219 -0
- collector/_console_static/docs/deployment/aws/terraform/main.tf +265 -0
- collector/_console_static/docs/deployment/azure/terraform/main.tf +96 -0
- collector/_console_static/docs/deployment/gcp/terraform/main.tf +96 -0
- collector/_console_static/docs/gcp/authentication/index.html +1 -0
- collector/_console_static/docs/gcp/authentication/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/_/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/_/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/api_gateway/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/api_gateway/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/bigquery_audit/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/bigquery_audit/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_armor/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_armor/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_audit_admin/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_audit_admin/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_audit_data/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_audit_data/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_audit_system/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_audit_system/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_cdn/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_cdn/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_dns/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_dns/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_functions/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_functions/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_monitoring/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_monitoring/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_nat/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_nat/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/cloud_sql/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/cloud_sql/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/firewall_logs/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/firewall_logs/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/gce/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/gce/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/gke_audit/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/gke_audit/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/iam_policy/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/iam_policy/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/load_balancer/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/load_balancer/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/logging_posture/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/logging_posture/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/login_events/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/login_events/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/network_posture/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/network_posture/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/project/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/project/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/scc_findings/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/scc_findings/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/secret_manager/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/secret_manager/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/storage_access/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/storage_access/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/vm_logs/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/vm_logs/index.txt +27 -0
- collector/_console_static/docs/gcp/collectors/vpc_flow/index.html +1 -0
- collector/_console_static/docs/gcp/collectors/vpc_flow/index.txt +27 -0
- collector/_console_static/docs/gcp/connections/index.html +1 -0
- collector/_console_static/docs/gcp/connections/index.txt +27 -0
- collector/_console_static/docs/gcp/index.html +1 -0
- collector/_console_static/docs/gcp/index.txt +24 -0
- collector/_console_static/docs/gcp/permissions/index.html +1 -0
- collector/_console_static/docs/gcp/permissions/index.txt +27 -0
- collector/_console_static/docs/iam-policies/aws-collector-permissions.txt +182 -0
- collector/_console_static/docs/iam-policies/aws-collector-readonly.json +201 -0
- collector/_console_static/docs/iam-policies/azure-collector-graph.json +35 -0
- collector/_console_static/docs/iam-policies/azure-collector-readonly.json +45 -0
- collector/_console_static/docs/iam-policies/gcp-collector-permissions.txt +120 -0
- collector/_console_static/docs/iam-policies/gcp-collector-readonly.json +31 -0
- collector/_console_static/docs/iam-policies/kubernetes-collector-readonly.json +39 -0
- collector/_console_static/docs/iam-policies/kubernetes-collector-readonly.yaml +90 -0
- collector/_console_static/docs/index.html +1 -0
- collector/_console_static/docs/index.txt +23 -0
- collector/_console_static/docs/kubernetes/authentication/index.html +1 -0
- collector/_console_static/docs/kubernetes/authentication/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/_/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/_/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_apiserver_audit/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_apiserver_audit/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_audit_posture/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_audit_posture/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_cluster_state/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_cluster_state/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_cni_logs/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_cni_logs/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_container_logs/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_container_logs/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_etcd/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_etcd/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_events/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_events/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_kubelet_logs/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_kubelet_logs/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_rbac/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_rbac/index.txt +27 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_runtime_logs/index.html +1 -0
- collector/_console_static/docs/kubernetes/collectors/k8s_runtime_logs/index.txt +27 -0
- collector/_console_static/docs/kubernetes/connections/index.html +1 -0
- collector/_console_static/docs/kubernetes/connections/index.txt +27 -0
- collector/_console_static/docs/kubernetes/index.html +1 -0
- collector/_console_static/docs/kubernetes/index.txt +24 -0
- collector/_console_static/docs/kubernetes/permissions/index.html +1 -0
- collector/_console_static/docs/kubernetes/permissions/index.txt +27 -0
- collector/_console_static/export/index.html +1 -0
- collector/_console_static/export/index.txt +26 -0
- collector/_console_static/icons/aws/account.svg +18 -0
- collector/_console_static/icons/aws/apigateway.svg +18 -0
- collector/_console_static/icons/aws/cloudfront.svg +18 -0
- collector/_console_static/icons/aws/cloudtrail.svg +18 -0
- collector/_console_static/icons/aws/cloudwatch.svg +18 -0
- collector/_console_static/icons/aws/config.svg +18 -0
- collector/_console_static/icons/aws/detective.svg +18 -0
- collector/_console_static/icons/aws/dynamodb_streams.svg +18 -0
- collector/_console_static/icons/aws/ec2.svg +18 -0
- collector/_console_static/icons/aws/eks_audit.svg +18 -0
- collector/_console_static/icons/aws/elb_alb.svg +18 -0
- collector/_console_static/icons/aws/guardduty.svg +18 -0
- collector/_console_static/icons/aws/iam.svg +18 -0
- collector/_console_static/icons/aws/inspector2.svg +18 -0
- collector/_console_static/icons/aws/kms.svg +18 -0
- collector/_console_static/icons/aws/lambda.svg +18 -0
- collector/_console_static/icons/aws/lambda_logs.svg +18 -0
- collector/_console_static/icons/aws/log_posture.svg +18 -0
- collector/_console_static/icons/aws/macie.svg +18 -0
- collector/_console_static/icons/aws/network_firewall.svg +18 -0
- collector/_console_static/icons/aws/opensearch.svg +18 -0
- collector/_console_static/icons/aws/rds.svg +18 -0
- collector/_console_static/icons/aws/route53_resolver.svg +18 -0
- collector/_console_static/icons/aws/s3.svg +18 -0
- collector/_console_static/icons/aws/s3_access.svg +18 -0
- collector/_console_static/icons/aws/secrets.svg +18 -0
- collector/_console_static/icons/aws/securityhub.svg +18 -0
- collector/_console_static/icons/aws/vpc_flow.svg +18 -0
- collector/_console_static/icons/aws/waf.svg +18 -0
- collector/_console_static/icons/azure/activity_log.svg +1 -0
- collector/_console_static/icons/azure/aks_audit.svg +1 -0
- collector/_console_static/icons/azure/app_gateway.svg +1 -0
- collector/_console_static/icons/azure/azure_firewall.svg +1 -0
- collector/_console_static/icons/azure/defender.svg +1 -0
- collector/_console_static/icons/azure/diag_posture.svg +1 -0
- collector/_console_static/icons/azure/dns.svg +1 -0
- collector/_console_static/icons/azure/entra_audit.svg +1 -0
- collector/_console_static/icons/azure/entra_directory.svg +1 -0
- collector/_console_static/icons/azure/entra_signin.svg +1 -0
- collector/_console_static/icons/azure/front_door.svg +1 -0
- collector/_console_static/icons/azure/key_vault.svg +1 -0
- collector/_console_static/icons/azure/nsg_flow.svg +1 -0
- collector/_console_static/icons/azure/oauth_consent.svg +1 -0
- collector/_console_static/icons/azure/rbac.svg +1 -0
- collector/_console_static/icons/azure/resource_graph.svg +1 -0
- collector/_console_static/icons/azure/storage_access.svg +1 -0
- collector/_console_static/icons/azure/subscription.svg +1 -0
- collector/_console_static/icons/azure/vnet_flow.svg +1 -0
- collector/_console_static/icons/gcp/api_gateway.svg +7 -0
- collector/_console_static/icons/gcp/bigquery_audit.svg +1 -0
- collector/_console_static/icons/gcp/cloud_armor.svg +1 -0
- collector/_console_static/icons/gcp/cloud_audit_admin.svg +1 -0
- collector/_console_static/icons/gcp/cloud_audit_data.svg +1 -0
- collector/_console_static/icons/gcp/cloud_audit_system.svg +1 -0
- collector/_console_static/icons/gcp/cloud_cdn.svg +1 -0
- collector/_console_static/icons/gcp/cloud_dns.svg +1 -0
- collector/_console_static/icons/gcp/cloud_functions.svg +1 -0
- collector/_console_static/icons/gcp/cloud_monitoring.svg +1 -0
- collector/_console_static/icons/gcp/cloud_nat.svg +1 -0
- collector/_console_static/icons/gcp/cloud_sql.svg +1 -0
- collector/_console_static/icons/gcp/firewall_logs.svg +1 -0
- collector/_console_static/icons/gcp/gce.svg +1 -0
- collector/_console_static/icons/gcp/gke_audit.svg +1 -0
- collector/_console_static/icons/gcp/iam_policy.svg +1 -0
- collector/_console_static/icons/gcp/load_balancer.svg +1 -0
- collector/_console_static/icons/gcp/logging_posture.svg +1 -0
- collector/_console_static/icons/gcp/login_events.svg +1 -0
- collector/_console_static/icons/gcp/network_posture.svg +1 -0
- collector/_console_static/icons/gcp/project.svg +20 -0
- collector/_console_static/icons/gcp/scc_findings.svg +1 -0
- collector/_console_static/icons/gcp/secret_manager.svg +7 -0
- collector/_console_static/icons/gcp/storage_access.svg +1 -0
- collector/_console_static/icons/gcp/vm_logs.svg +1 -0
- collector/_console_static/icons/gcp/vpc_flow.svg +1 -0
- collector/_console_static/icons/kubernetes/k8s_apiserver_audit.svg +86 -0
- collector/_console_static/icons/kubernetes/k8s_audit_posture.svg +84 -0
- collector/_console_static/icons/kubernetes/k8s_cluster_state.svg +92 -0
- collector/_console_static/icons/kubernetes/k8s_cni_logs.svg +84 -0
- collector/_console_static/icons/kubernetes/k8s_container_logs.svg +103 -0
- collector/_console_static/icons/kubernetes/k8s_control_plane_logs.svg +84 -0
- collector/_console_static/icons/kubernetes/k8s_etcd.svg +89 -0
- collector/_console_static/icons/kubernetes/k8s_events.svg +85 -0
- collector/_console_static/icons/kubernetes/k8s_kubelet_logs.svg +86 -0
- collector/_console_static/icons/kubernetes/k8s_pod_logs.svg +103 -0
- collector/_console_static/icons/kubernetes/k8s_rbac.svg +102 -0
- collector/_console_static/icons/kubernetes/k8s_runtime_logs.svg +84 -0
- collector/_console_static/index.html +1 -0
- collector/_console_static/index.txt +20 -0
- collector/_console_static/logos/aws.png +0 -0
- collector/_console_static/logos/azure.png +0 -0
- collector/_console_static/logos/gcp.png +0 -0
- collector/_console_static/logos/kubernetes.svg +91 -0
- collector/_console_static/runs/_/index.html +1 -0
- collector/_console_static/runs/_/index.txt +26 -0
- collector/_console_static/runs/index.html +1 -0
- collector/_console_static/runs/index.txt +23 -0
- collector/_console_static/runs/new/index.html +1 -0
- collector/_console_static/runs/new/index.txt +23 -0
- collector/_console_static/settings/index.html +1 -0
- collector/_console_static/settings/index.txt +26 -0
- collector/_iam_policies/README.md +28 -0
- collector/_iam_policies/aws-collector-permissions.txt +182 -0
- collector/_iam_policies/aws-collector-readonly.json +201 -0
- collector/_iam_policies/azure-collector-graph.json +35 -0
- collector/_iam_policies/azure-collector-readonly.json +45 -0
- collector/_iam_policies/gcp-collector-permissions.txt +120 -0
- collector/_iam_policies/gcp-collector-readonly.json +31 -0
- collector/_iam_policies/kubernetes-collector-readonly.json +39 -0
- collector/_iam_policies/kubernetes-collector-readonly.yaml +90 -0
- collector/_schemas/artifact.schema.json +88 -0
- collector/_schemas/manifest.schema.json +210 -0
- collector/_schemas/package.schema.json +49 -0
- collector/_schemas/unified-event.schema.json +130 -0
- collector/cli.py +1946 -0
- collector/clouds/__init__.py +1 -0
- collector/clouds/aws/__init__.py +3 -0
- collector/clouds/aws/client_factory.py +183 -0
- collector/clouds/azure/__init__.py +3 -0
- collector/clouds/azure/client_factory.py +544 -0
- collector/clouds/gcp/__init__.py +3 -0
- collector/clouds/gcp/client_factory.py +1079 -0
- collector/clouds/kubernetes/__init__.py +0 -0
- collector/clouds/kubernetes/client_factory.py +447 -0
- collector/clouds/kubernetes/node.py +223 -0
- collector/devgui.py +607 -0
- collector/engine/__init__.py +34 -0
- collector/engine/acquire_platform.py +43 -0
- collector/engine/acquisition.py +287 -0
- collector/engine/api/__init__.py +1 -0
- collector/engine/api/aws/__init__.py +1 -0
- collector/engine/api/aws/common/__init__.py +1 -0
- collector/engine/api/aws/common/cw_logs.py +94 -0
- collector/engine/api/aws/common/s3_logs.py +147 -0
- collector/engine/api/aws/control_plane/__init__.py +1 -0
- collector/engine/api/aws/control_plane/cloudtrail.py +787 -0
- collector/engine/api/aws/control_plane/cloudtrail_s3.py +340 -0
- collector/engine/api/aws/control_plane/cloudtrail_validation.py +213 -0
- collector/engine/api/aws/control_plane/cloudwatch.py +269 -0
- collector/engine/api/aws/control_plane/config.py +97 -0
- collector/engine/api/aws/control_plane/log_posture.py +202 -0
- collector/engine/api/aws/detections/__init__.py +1 -0
- collector/engine/api/aws/detections/detective.py +105 -0
- collector/engine/api/aws/detections/guardduty.py +137 -0
- collector/engine/api/aws/detections/inspector2.py +122 -0
- collector/engine/api/aws/detections/macie.py +119 -0
- collector/engine/api/aws/detections/securityhub.py +116 -0
- collector/engine/api/aws/identity/__init__.py +1 -0
- collector/engine/api/aws/identity/account.py +72 -0
- collector/engine/api/aws/identity/iam.py +392 -0
- collector/engine/api/aws/identity/kms.py +76 -0
- collector/engine/api/aws/identity/secrets.py +60 -0
- collector/engine/api/aws/network/__init__.py +1 -0
- collector/engine/api/aws/network/apigateway.py +224 -0
- collector/engine/api/aws/network/cloudfront.py +214 -0
- collector/engine/api/aws/network/elb_alb.py +242 -0
- collector/engine/api/aws/network/route53_resolver.py +295 -0
- collector/engine/api/aws/network/vpc_flow.py +264 -0
- collector/engine/api/aws/network/vpc_flow_s3.py +215 -0
- collector/engine/api/aws/network/waf.py +156 -0
- collector/engine/api/aws/runner.py +237 -0
- collector/engine/api/aws/workloads/__init__.py +1 -0
- collector/engine/api/aws/workloads/ec2.py +242 -0
- collector/engine/api/aws/workloads/eks_audit.py +172 -0
- collector/engine/api/aws/workloads/lambda_.py +79 -0
- collector/engine/api/aws/workloads/lambda_logs.py +170 -0
- collector/engine/api/aws/workloads/rds_logs.py +169 -0
- collector/engine/api/aws/workloads/s3.py +116 -0
- collector/engine/api/aws/workloads/s3_access.py +212 -0
- collector/engine/api/azure/__init__.py +1 -0
- collector/engine/api/azure/common/__init__.py +32 -0
- collector/engine/api/azure/common/diagnostics.py +165 -0
- collector/engine/api/azure/common/storage_logs.py +127 -0
- collector/engine/api/azure/control_plane/__init__.py +1 -0
- collector/engine/api/azure/control_plane/activity_log.py +335 -0
- collector/engine/api/azure/control_plane/activity_log_common.py +20 -0
- collector/engine/api/azure/control_plane/diag_posture.py +163 -0
- collector/engine/api/azure/control_plane/resource_graph.py +84 -0
- collector/engine/api/azure/detections/__init__.py +1 -0
- collector/engine/api/azure/detections/defender.py +93 -0
- collector/engine/api/azure/identity/__init__.py +1 -0
- collector/engine/api/azure/identity/entra_audit.py +78 -0
- collector/engine/api/azure/identity/entra_directory.py +108 -0
- collector/engine/api/azure/identity/entra_signin.py +85 -0
- collector/engine/api/azure/identity/oauth_consent.py +73 -0
- collector/engine/api/azure/identity/rbac.py +118 -0
- collector/engine/api/azure/identity/subscription.py +65 -0
- collector/engine/api/azure/network/__init__.py +1 -0
- collector/engine/api/azure/network/app_gateway.py +29 -0
- collector/engine/api/azure/network/azure_firewall.py +34 -0
- collector/engine/api/azure/network/dns.py +35 -0
- collector/engine/api/azure/network/flow_common.py +203 -0
- collector/engine/api/azure/network/front_door.py +41 -0
- collector/engine/api/azure/network/nsg_flow.py +26 -0
- collector/engine/api/azure/network/vnet_flow.py +26 -0
- collector/engine/api/azure/runner.py +203 -0
- collector/engine/api/azure/workloads/__init__.py +1 -0
- collector/engine/api/azure/workloads/aks_audit.py +197 -0
- collector/engine/api/azure/workloads/key_vault.py +30 -0
- collector/engine/api/azure/workloads/storage_access.py +32 -0
- collector/engine/api/gcp/__init__.py +1 -0
- collector/engine/api/gcp/common/__init__.py +5 -0
- collector/engine/api/gcp/common/logging_collector.py +292 -0
- collector/engine/api/gcp/control_plane/__init__.py +1 -0
- collector/engine/api/gcp/control_plane/cloud_audit_admin.py +11 -0
- collector/engine/api/gcp/control_plane/cloud_audit_data.py +11 -0
- collector/engine/api/gcp/control_plane/cloud_audit_system.py +11 -0
- collector/engine/api/gcp/control_plane/logging_posture.py +189 -0
- collector/engine/api/gcp/detections/__init__.py +1 -0
- collector/engine/api/gcp/detections/cloud_monitoring.py +15 -0
- collector/engine/api/gcp/detections/scc_findings.py +76 -0
- collector/engine/api/gcp/identity/__init__.py +1 -0
- collector/engine/api/gcp/identity/iam_policy.py +150 -0
- collector/engine/api/gcp/identity/login_events.py +16 -0
- collector/engine/api/gcp/identity/project.py +61 -0
- collector/engine/api/gcp/network/__init__.py +1 -0
- collector/engine/api/gcp/network/api_gateway.py +12 -0
- collector/engine/api/gcp/network/cloud_armor.py +166 -0
- collector/engine/api/gcp/network/cloud_cdn.py +16 -0
- collector/engine/api/gcp/network/cloud_dns.py +12 -0
- collector/engine/api/gcp/network/cloud_nat.py +12 -0
- collector/engine/api/gcp/network/firewall_logs.py +12 -0
- collector/engine/api/gcp/network/load_balancer.py +14 -0
- collector/engine/api/gcp/network/network_posture.py +123 -0
- collector/engine/api/gcp/network/vpc_flow.py +12 -0
- collector/engine/api/gcp/runner.py +537 -0
- collector/engine/api/gcp/workloads/__init__.py +1 -0
- collector/engine/api/gcp/workloads/bigquery_audit.py +17 -0
- collector/engine/api/gcp/workloads/cloud_functions.py +12 -0
- collector/engine/api/gcp/workloads/cloud_sql.py +12 -0
- collector/engine/api/gcp/workloads/gce.py +160 -0
- collector/engine/api/gcp/workloads/gke_audit.py +197 -0
- collector/engine/api/gcp/workloads/secret_manager.py +15 -0
- collector/engine/api/gcp/workloads/storage_access.py +17 -0
- collector/engine/api/gcp/workloads/vm_logs.py +12 -0
- collector/engine/api/kubernetes/__init__.py +0 -0
- collector/engine/api/kubernetes/api_plane/__init__.py +0 -0
- collector/engine/api/kubernetes/api_plane/audit_posture.py +267 -0
- collector/engine/api/kubernetes/api_plane/cluster_state.py +468 -0
- collector/engine/api/kubernetes/api_plane/events.py +251 -0
- collector/engine/api/kubernetes/api_plane/rbac.py +264 -0
- collector/engine/api/kubernetes/common/__init__.py +0 -0
- collector/engine/api/kubernetes/common/analysis.py +165 -0
- collector/engine/api/kubernetes/common/apiserver_flags.py +130 -0
- collector/engine/api/kubernetes/common/distro.py +345 -0
- collector/engine/api/kubernetes/common/journal.py +58 -0
- collector/engine/api/kubernetes/common/nodebase.py +108 -0
- collector/engine/api/kubernetes/common/nodecontext.py +68 -0
- collector/engine/api/kubernetes/common/preflight.py +146 -0
- collector/engine/api/kubernetes/node_plane/__init__.py +0 -0
- collector/engine/api/kubernetes/node_plane/apiserver_audit.py +394 -0
- collector/engine/api/kubernetes/node_plane/cni_logs.py +147 -0
- collector/engine/api/kubernetes/node_plane/container_logs.py +118 -0
- collector/engine/api/kubernetes/node_plane/etcd.py +577 -0
- collector/engine/api/kubernetes/node_plane/kubelet_logs.py +125 -0
- collector/engine/api/kubernetes/node_plane/runtime_logs.py +229 -0
- collector/engine/api/kubernetes/runner.py +287 -0
- collector/engine/api_reporter.py +294 -0
- collector/engine/azure_log_backend.py +77 -0
- collector/engine/executor.py +55 -0
- collector/engine/gcp_collection_summary.py +95 -0
- collector/engine/gcp_export_bulk.py +216 -0
- collector/engine/gcp_log_backend.py +231 -0
- collector/engine/gcp_log_export.py +583 -0
- collector/engine/gcp_log_filter_sql.py +606 -0
- collector/engine/gcp_strategy_resolver.py +411 -0
- collector/engine/loader.py +52 -0
- collector/engine/matrix_state.py +352 -0
- collector/engine/registry/__init__.py +109 -0
- collector/engine/registry/aws.py +74 -0
- collector/engine/registry/azure.py +62 -0
- collector/engine/registry/gcp.py +76 -0
- collector/engine/registry/kubernetes.py +51 -0
- collector/engine/run_common.py +88 -0
- collector/engine/run_finalize.py +61 -0
- collector/engine/run_launcher.py +260 -0
- collector/engine/validate.py +192 -0
- collector/kit/__init__.py +1 -0
- collector/kit/auth_embed.py +38 -0
- collector/kit/build.py +636 -0
- collector/kit/deliver.py +106 -0
- collector/kit/format.py +317 -0
- collector/kit/import_cmd.py +97 -0
- collector/kit/mint.py +707 -0
- collector/kit/preview.py +90 -0
- collector/kit/run.py +658 -0
- collector/kit/run_view.py +232 -0
- collector/kit/templates/README-operator.md +147 -0
- collector/kit/templates/deployment/cloudshell.md +41 -0
- collector/kit/templates/deployment/ec2.md +45 -0
- collector/kit/templates/deployment/workstation.md +52 -0
- collector/kit/templates/ec2-bootstrap.sh +29 -0
- collector/kit/templates/gcp-log-setup-gcs.md +33 -0
- collector/kit/templates/run.sh +5 -0
- collector/kit/templates/ventra.py +491 -0
- collector/lib/__init__.py +1 -0
- collector/lib/auth.py +78 -0
- collector/lib/base.py +300 -0
- collector/lib/chain_of_custody/__init__.py +6 -0
- collector/lib/chain_of_custody/hashing.py +21 -0
- collector/lib/chain_of_custody/signing.py +74 -0
- collector/lib/elevate.py +180 -0
- collector/lib/ingest.py +80 -0
- collector/lib/limits.py +23 -0
- collector/lib/models.py +346 -0
- collector/lib/packaging/__init__.py +5 -0
- collector/lib/packaging/packager.py +129 -0
- collector/lib/params.py +219 -0
- collector/lib/scoping.py +1111 -0
- collector/lib/transport/__init__.py +5 -0
- collector/lib/transport/base.py +132 -0
- collector/lib/uv_util.py +77 -0
- collector/paths.py +122 -0
- collector/runner.py +18 -0
- collector/tools/__init__.py +1 -0
- collector/tools/verify_readonly.py +73 -0
- ventra-1.0.1.dist-info/METADATA +377 -0
- ventra-1.0.1.dist-info/RECORD +813 -0
- ventra-1.0.1.dist-info/WHEEL +4 -0
- ventra-1.0.1.dist-info/entry_points.txt +8 -0
- ventra-1.0.1.dist-info/licenses/LICENSE +202 -0
- ventra_ingester/__init__.py +5 -0
- ventra_ingester/cli.py +126 -0
- ventra_ingester/enrichment/__init__.py +10 -0
- ventra_ingester/enrichment/enrich.py +100 -0
- ventra_ingester/evidence_extract.py +100 -0
- ventra_ingester/exporters/__init__.py +1 -0
- ventra_ingester/exporters/elastic_ndjson.py +572 -0
- ventra_ingester/ingest_watch.py +151 -0
- ventra_ingester/limits.py +11 -0
- ventra_ingester/loaders/__init__.py +5 -0
- ventra_ingester/loaders/casestore.py +340 -0
- ventra_ingester/normalizer/__init__.py +12 -0
- ventra_ingester/normalizer/base.py +106 -0
- ventra_ingester/normalizer/inventory.py +201 -0
- ventra_ingester/normalizer/sources/__init__.py +22 -0
- ventra_ingester/normalizer/sources/access_logs.py +275 -0
- ventra_ingester/normalizer/sources/azure_activity_log.py +89 -0
- ventra_ingester/normalizer/sources/azure_diagnostics.py +285 -0
- ventra_ingester/normalizer/sources/azure_entra.py +119 -0
- ventra_ingester/normalizer/sources/azure_nsg_flow.py +74 -0
- ventra_ingester/normalizer/sources/cloudtrail.py +219 -0
- ventra_ingester/normalizer/sources/cloudwatch.py +54 -0
- ventra_ingester/normalizer/sources/dns_logs.py +50 -0
- ventra_ingester/normalizer/sources/eks_audit.py +90 -0
- ventra_ingester/normalizer/sources/findings.py +298 -0
- ventra_ingester/normalizer/sources/gcp_audit.py +164 -0
- ventra_ingester/normalizer/sources/gcp_findings.py +42 -0
- ventra_ingester/normalizer/sources/k8s_apiserver_audit.py +102 -0
- ventra_ingester/normalizer/sources/k8s_events.py +114 -0
- ventra_ingester/normalizer/sources/k8s_logs.py +261 -0
- ventra_ingester/normalizer/sources/k8s_state.py +283 -0
- ventra_ingester/normalizer/sources/network.py +170 -0
- ventra_ingester/normalizer/sources/waf.py +87 -0
- ventra_ingester/package.py +204 -0
- ventra_ingester/pipeline.py +387 -0
- ventra_ingester/verify/__init__.py +5 -0
- ventra_ingester/verify/integrity.py +131 -0
app/__init__.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Ventra analyst console backend.
|
|
2
|
+
|
|
3
|
+
A thin FastAPI layer over the case store the ingester produces. It never calls out to the
|
|
4
|
+
cloud; it only reads ``cases/<id>/`` (events.parquet via DuckDB + the JSON sidecars). RBAC is
|
|
5
|
+
enforced here, server-side. No telemetry.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "0.1.0"
|
app/config.py
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Backend configuration. Everything is local and offline by design."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def _default_data_root() -> Path:
|
|
10
|
+
env = os.environ.get("VENTRA_HOME", "").strip()
|
|
11
|
+
if env:
|
|
12
|
+
return Path(env).expanduser().resolve()
|
|
13
|
+
# Packaged / pipx installs: keep state under the user data dir, not cwd. Shared with
|
|
14
|
+
# the CLI (`ventra import`, collect auto-ingest) so both use the same case store.
|
|
15
|
+
try:
|
|
16
|
+
from collector.paths import default_data_root
|
|
17
|
+
|
|
18
|
+
return default_data_root()
|
|
19
|
+
except Exception:
|
|
20
|
+
pass
|
|
21
|
+
return Path.cwd().resolve()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _default_artifacts_root() -> Path:
|
|
25
|
+
"""Locate the artifact YAML catalog regardless of the backend's working directory."""
|
|
26
|
+
env = os.environ.get("VENTRA_ARTIFACTS_ROOT")
|
|
27
|
+
if env:
|
|
28
|
+
return Path(env).resolve()
|
|
29
|
+
try:
|
|
30
|
+
from collector.paths import default_artifacts_root
|
|
31
|
+
|
|
32
|
+
return default_artifacts_root()
|
|
33
|
+
except Exception:
|
|
34
|
+
pass
|
|
35
|
+
return Path("artifacts").resolve()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
_DATA = _default_data_root()
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class Settings:
|
|
42
|
+
# Root of the case store the ingester writes to.
|
|
43
|
+
case_store: Path = Path(os.environ.get("VENTRA_CASE_STORE", str(_DATA / "cases"))).resolve()
|
|
44
|
+
# Root of the artifact YAML catalog the Acquire tab and kit builder read.
|
|
45
|
+
artifacts_root: Path = _default_artifacts_root()
|
|
46
|
+
# Where uploaded packages are staged before ingest.
|
|
47
|
+
upload_dir: Path = Path(os.environ.get("VENTRA_UPLOAD_DIR", str(_DATA / ".ventra-uploads"))).resolve()
|
|
48
|
+
# Hard cap on an uploaded evidence package, in MB. Streamed to disk; the request is
|
|
49
|
+
# rejected once the limit is exceeded so a large upload can't exhaust memory or disk.
|
|
50
|
+
max_upload_mb: int = int(os.environ.get("VENTRA_MAX_UPLOAD_MB", "20480"))
|
|
51
|
+
# CORS origins for the frontend dev server.
|
|
52
|
+
cors_origins: list[str] = os.environ.get(
|
|
53
|
+
"VENTRA_CORS", "http://localhost:3000,http://localhost:8080"
|
|
54
|
+
).split(",")
|
|
55
|
+
# Refuse requests whose Host isn't this machine (DNS rebinding; see app.host_check). Add
|
|
56
|
+
# names with VENTRA_ALLOWED_HOSTS rather than turning this off.
|
|
57
|
+
host_check: bool = os.environ.get("VENTRA_HOST_CHECK", "on").strip().lower() not in (
|
|
58
|
+
"0",
|
|
59
|
+
"off",
|
|
60
|
+
"false",
|
|
61
|
+
"no",
|
|
62
|
+
)
|
|
63
|
+
# Telemetry is OFF and not configurable to on. Stated explicitly for auditors.
|
|
64
|
+
telemetry: bool = False
|
|
65
|
+
# S3 prefix polled by Import from S3 in the console (s3://bucket/prefix/).
|
|
66
|
+
ingest_s3_prefix: str = os.environ.get("VENTRA_INGEST_S3_PREFIX", "").strip()
|
|
67
|
+
ingest_download_dir: Path = Path(
|
|
68
|
+
os.environ.get("VENTRA_INGEST_DOWNLOAD_DIR", str(_DATA / ".ventra-ingest-watch"))
|
|
69
|
+
).resolve()
|
|
70
|
+
_ingest_state = os.environ.get("VENTRA_INGEST_STATE_FILE", "").strip()
|
|
71
|
+
ingest_state_file: Path | None = Path(_ingest_state).resolve() if _ingest_state else None
|
|
72
|
+
# Saved connections and collection profiles for the Configuration section.
|
|
73
|
+
config_dir: Path = Path(os.environ.get("VENTRA_CONFIG_DIR", str(_DATA / ".ventra-config"))).resolve()
|
|
74
|
+
# File-backed collection run state (matrix + SSE events).
|
|
75
|
+
runs_dir: Path = Path(os.environ.get("VENTRA_RUNS_DIR", str(_DATA / ".ventra-runs"))).resolve()
|
|
76
|
+
# Optional SIEM drop zone: export writes NDJSON here for Logstash/Filebeat/forwarders.
|
|
77
|
+
# Unset = download-only. Never holds SIEM credentials — shippers watch this path.
|
|
78
|
+
_export_drop = os.environ.get("VENTRA_EXPORT_DROP_DIR", "").strip()
|
|
79
|
+
export_drop_dir: Path | None = Path(_export_drop).resolve() if _export_drop else None
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
settings = Settings()
|
|
83
|
+
settings.upload_dir.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
settings.config_dir.mkdir(parents=True, exist_ok=True)
|
|
85
|
+
settings.runs_dir.mkdir(parents=True, exist_ok=True)
|
|
86
|
+
settings.case_store.mkdir(parents=True, exist_ok=True)
|
|
87
|
+
if settings.export_drop_dir is not None:
|
|
88
|
+
settings.export_drop_dir.mkdir(parents=True, exist_ok=True)
|
app/config_store.py
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""File-backed configuration store for connections and collection profiles."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import uuid
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
# Connection fields that hold credentials. They stay on disk (the collectors need them) but
|
|
12
|
+
# never leave the backend: API responses carry only which ones are set.
|
|
13
|
+
SECRET_FIELDS = (
|
|
14
|
+
"aws_secret_access_key",
|
|
15
|
+
"aws_session_token",
|
|
16
|
+
"azure_client_secret",
|
|
17
|
+
"azure_client_certificate_content",
|
|
18
|
+
"gcp_service_account_json",
|
|
19
|
+
"kubeconfig_content",
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def public_connection(conn: dict[str, Any]) -> dict[str, Any]:
|
|
24
|
+
"""A connection as the API returns it: secrets removed, ``stored_secrets`` lists what is set."""
|
|
25
|
+
out = {k: v for k, v in conn.items() if k not in SECRET_FIELDS}
|
|
26
|
+
out["stored_secrets"] = [k for k in SECRET_FIELDS if conn.get(k)]
|
|
27
|
+
return out
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ConfigNotFound(Exception):
|
|
31
|
+
pass
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class ConfigStore:
|
|
35
|
+
def __init__(self, root: Path) -> None:
|
|
36
|
+
self.root = root
|
|
37
|
+
self.root.mkdir(mode=0o700, parents=True, exist_ok=True)
|
|
38
|
+
self.connections_path = self.root / "connections.json"
|
|
39
|
+
self.profiles_path = self.root / "profiles.json"
|
|
40
|
+
self._restrict_permissions()
|
|
41
|
+
|
|
42
|
+
def _restrict_permissions(self) -> None:
|
|
43
|
+
"""Owner-only access for the store (and files written by older versions)."""
|
|
44
|
+
if os.name != "posix":
|
|
45
|
+
return
|
|
46
|
+
for path, mode in (
|
|
47
|
+
(self.root, 0o700),
|
|
48
|
+
(self.connections_path, 0o600),
|
|
49
|
+
(self.profiles_path, 0o600),
|
|
50
|
+
):
|
|
51
|
+
try:
|
|
52
|
+
if path.exists() and (path.stat().st_mode & 0o777) != mode:
|
|
53
|
+
path.chmod(mode)
|
|
54
|
+
except OSError:
|
|
55
|
+
pass # not ours to change (e.g. read-only mount); nothing more we can do
|
|
56
|
+
|
|
57
|
+
def _read(self, path: Path) -> list[dict[str, Any]]:
|
|
58
|
+
if not path.is_file():
|
|
59
|
+
return []
|
|
60
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
61
|
+
|
|
62
|
+
def _write(self, path: Path, items: list[dict[str, Any]]) -> None:
|
|
63
|
+
"""Write atomically, owner read/write only: the file holds cloud credentials."""
|
|
64
|
+
tmp = path.with_name(f".{path.name}.{uuid.uuid4().hex}.tmp")
|
|
65
|
+
fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
|
66
|
+
try:
|
|
67
|
+
with os.fdopen(fd, "w", encoding="utf-8") as fh:
|
|
68
|
+
json.dump(items, fh, indent=2)
|
|
69
|
+
os.replace(tmp, path)
|
|
70
|
+
except BaseException:
|
|
71
|
+
tmp.unlink(missing_ok=True)
|
|
72
|
+
raise
|
|
73
|
+
|
|
74
|
+
def list_connections(self) -> list[dict[str, Any]]:
|
|
75
|
+
return self._read(self.connections_path)
|
|
76
|
+
|
|
77
|
+
def get_connection(self, conn_id: str) -> dict[str, Any]:
|
|
78
|
+
item = next((c for c in self.list_connections() if c.get("id") == conn_id), None)
|
|
79
|
+
if item is None:
|
|
80
|
+
raise ConfigNotFound(f"Connection not found: {conn_id}")
|
|
81
|
+
return item
|
|
82
|
+
|
|
83
|
+
def create_connection(self, data: dict[str, Any]) -> dict[str, Any]:
|
|
84
|
+
from datetime import datetime, timezone
|
|
85
|
+
|
|
86
|
+
items = self.list_connections()
|
|
87
|
+
entry = {
|
|
88
|
+
"id": str(uuid.uuid4()),
|
|
89
|
+
"created_at": datetime.now(timezone.utc).isoformat(),
|
|
90
|
+
**data,
|
|
91
|
+
}
|
|
92
|
+
items.append(entry)
|
|
93
|
+
self._write(self.connections_path, items)
|
|
94
|
+
return entry
|
|
95
|
+
|
|
96
|
+
def update_connection(self, conn_id: str, patch: dict[str, Any]) -> dict[str, Any]:
|
|
97
|
+
items = self.list_connections()
|
|
98
|
+
for i, item in enumerate(items):
|
|
99
|
+
if item.get("id") == conn_id:
|
|
100
|
+
updated = {**item, **patch, "id": conn_id}
|
|
101
|
+
items[i] = updated
|
|
102
|
+
self._write(self.connections_path, items)
|
|
103
|
+
return updated
|
|
104
|
+
raise ConfigNotFound(f"Connection not found: {conn_id}")
|
|
105
|
+
|
|
106
|
+
def delete_connection(self, conn_id: str) -> None:
|
|
107
|
+
items = [c for c in self.list_connections() if c.get("id") != conn_id]
|
|
108
|
+
if len(items) == len(self._read(self.connections_path)):
|
|
109
|
+
raise ConfigNotFound(f"Connection not found: {conn_id}")
|
|
110
|
+
self._write(self.connections_path, items)
|
|
111
|
+
|
|
112
|
+
def list_profiles(self) -> list[dict[str, Any]]:
|
|
113
|
+
return self._read(self.profiles_path)
|
|
114
|
+
|
|
115
|
+
def get_profile(self, profile_id: str) -> dict[str, Any]:
|
|
116
|
+
item = next((p for p in self.list_profiles() if p.get("id") == profile_id), None)
|
|
117
|
+
if item is None:
|
|
118
|
+
raise ConfigNotFound(f"Profile not found: {profile_id}")
|
|
119
|
+
return item
|
|
120
|
+
|
|
121
|
+
def create_profile(self, data: dict[str, Any]) -> dict[str, Any]:
|
|
122
|
+
items = self.list_profiles()
|
|
123
|
+
entry = {"id": str(uuid.uuid4()), **data}
|
|
124
|
+
items.append(entry)
|
|
125
|
+
self._write(self.profiles_path, items)
|
|
126
|
+
return entry
|
|
127
|
+
|
|
128
|
+
def update_profile(self, profile_id: str, patch: dict[str, Any]) -> dict[str, Any]:
|
|
129
|
+
items = self.list_profiles()
|
|
130
|
+
for i, item in enumerate(items):
|
|
131
|
+
if item.get("id") == profile_id:
|
|
132
|
+
updated = {**item, **patch, "id": profile_id}
|
|
133
|
+
items[i] = updated
|
|
134
|
+
self._write(self.profiles_path, items)
|
|
135
|
+
return updated
|
|
136
|
+
raise ConfigNotFound(f"Profile not found: {profile_id}")
|
|
137
|
+
|
|
138
|
+
def delete_profile(self, profile_id: str) -> None:
|
|
139
|
+
items = [p for p in self.list_profiles() if p.get("id") != profile_id]
|
|
140
|
+
if len(items) == len(self._read(self.profiles_path)):
|
|
141
|
+
raise ConfigNotFound(f"Profile not found: {profile_id}")
|
|
142
|
+
self._write(self.profiles_path, items)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
from .config import settings
|
|
146
|
+
|
|
147
|
+
config_store = ConfigStore(settings.config_dir)
|
app/evidence.py
ADDED
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""Browse raw evidence files extracted from the sealed package into ``cases/<id>/evidence/``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import gzip
|
|
6
|
+
import json
|
|
7
|
+
import re
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from .config import settings
|
|
12
|
+
|
|
13
|
+
_PATH_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._/-]{0,512}$")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class EvidenceError(ValueError):
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class EvidenceNotFound(EvidenceError):
|
|
21
|
+
pass
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _evidence_root(case_dir: Path) -> Path:
|
|
25
|
+
return case_dir / "evidence"
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _resolve_evidence_path(case_dir: Path, rel_path: str) -> Path:
|
|
29
|
+
rel = rel_path.strip().lstrip("/").replace("\\", "/")
|
|
30
|
+
if not rel or ".." in rel.split("/") or not _PATH_RE.fullmatch(rel):
|
|
31
|
+
raise EvidenceError(f"Invalid evidence path: {rel_path!r}")
|
|
32
|
+
root = _evidence_root(case_dir).resolve()
|
|
33
|
+
target = (root / rel).resolve()
|
|
34
|
+
if target != root and root not in target.parents:
|
|
35
|
+
raise EvidenceError(f"Path escapes evidence root: {rel_path!r}")
|
|
36
|
+
return target
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _manifest_source_meta(manifest: dict[str, Any]) -> dict[str, dict[str, Any]]:
|
|
40
|
+
out: dict[str, dict[str, Any]] = {}
|
|
41
|
+
for entry in manifest.get("sources") or []:
|
|
42
|
+
if not isinstance(entry, dict):
|
|
43
|
+
continue
|
|
44
|
+
path = str(entry.get("path") or "").strip()
|
|
45
|
+
if path:
|
|
46
|
+
out[path] = entry
|
|
47
|
+
name = str(entry.get("name") or "").strip()
|
|
48
|
+
if name and name not in out:
|
|
49
|
+
out[name] = entry
|
|
50
|
+
return out
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _classify_file(rel: str) -> str:
|
|
54
|
+
name = rel.rsplit("/", 1)[-1]
|
|
55
|
+
if name.startswith("events"):
|
|
56
|
+
return "events"
|
|
57
|
+
if name == "config.json":
|
|
58
|
+
return "config"
|
|
59
|
+
if name == "snapshot.json":
|
|
60
|
+
return "snapshot"
|
|
61
|
+
if name == "_meta.json":
|
|
62
|
+
return "meta"
|
|
63
|
+
if "credential_report" in name:
|
|
64
|
+
return "credential_report"
|
|
65
|
+
if rel.startswith("errors/"):
|
|
66
|
+
return "error"
|
|
67
|
+
if rel == "collection.log":
|
|
68
|
+
return "collection_log"
|
|
69
|
+
if rel == "manifest.json":
|
|
70
|
+
return "manifest"
|
|
71
|
+
if rel.endswith(".sig"):
|
|
72
|
+
return "signature"
|
|
73
|
+
return "other"
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
# Sidecar / packaging kinds must not display a source-level inherited record_count.
|
|
77
|
+
_NON_DATA_KINDS = frozenset({"config", "meta", "manifest", "signature", "collection_log", "error"})
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _record_count_for_file(kind: str, manifest_entry: dict[str, Any] | None) -> int | None:
|
|
81
|
+
if not manifest_entry:
|
|
82
|
+
return None
|
|
83
|
+
if kind in _NON_DATA_KINDS:
|
|
84
|
+
return None
|
|
85
|
+
raw = manifest_entry.get("record_count")
|
|
86
|
+
if raw is None:
|
|
87
|
+
return None
|
|
88
|
+
try:
|
|
89
|
+
return int(raw)
|
|
90
|
+
except (TypeError, ValueError):
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def ensure_evidence_extracted(case_dir: Path, case_id: str) -> Path:
|
|
95
|
+
"""Return the evidence directory, extracting from a retained package when missing."""
|
|
96
|
+
root = _evidence_root(case_dir)
|
|
97
|
+
if root.is_dir() and any(root.rglob("*")):
|
|
98
|
+
return root
|
|
99
|
+
|
|
100
|
+
from ventra_ingester.evidence_extract import extract_package, find_package_for_case
|
|
101
|
+
|
|
102
|
+
pkg_dir = case_dir / "package"
|
|
103
|
+
package = find_package_for_case(case_id, pkg_dir, settings.upload_dir)
|
|
104
|
+
if package is None:
|
|
105
|
+
raise EvidenceNotFound(f"No raw evidence files for case {case_id!r}. Re-import the sealed package.")
|
|
106
|
+
extract_package(package, root)
|
|
107
|
+
return root
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def list_evidence_files(case_dir: Path, manifest: dict[str, Any]) -> dict[str, Any]:
|
|
111
|
+
case_id = str(manifest.get("case_id") or case_dir.name)
|
|
112
|
+
root = ensure_evidence_extracted(case_dir, case_id)
|
|
113
|
+
meta_by_path = _manifest_source_meta(manifest)
|
|
114
|
+
files: list[dict[str, Any]] = []
|
|
115
|
+
total_bytes = 0
|
|
116
|
+
for path in sorted(root.rglob("*")):
|
|
117
|
+
if not path.is_file():
|
|
118
|
+
continue
|
|
119
|
+
rel = path.relative_to(root).as_posix()
|
|
120
|
+
size = path.stat().st_size
|
|
121
|
+
total_bytes += size
|
|
122
|
+
source_name = ""
|
|
123
|
+
if rel.startswith("sources/"):
|
|
124
|
+
parts = rel.split("/")
|
|
125
|
+
if len(parts) >= 2:
|
|
126
|
+
source_name = parts[1]
|
|
127
|
+
# Prefer exact path, then source name (collector-level entry), then first path segment.
|
|
128
|
+
manifest_entry = (
|
|
129
|
+
meta_by_path.get(rel)
|
|
130
|
+
or (meta_by_path.get(source_name) if source_name else None)
|
|
131
|
+
or meta_by_path.get(rel.split("/", 1)[0])
|
|
132
|
+
)
|
|
133
|
+
kind = _classify_file(rel)
|
|
134
|
+
files.append(
|
|
135
|
+
{
|
|
136
|
+
"path": rel,
|
|
137
|
+
"size": size,
|
|
138
|
+
"kind": kind,
|
|
139
|
+
"source": source_name or None,
|
|
140
|
+
"sha256": (manifest_entry or {}).get("sha256"),
|
|
141
|
+
"record_count": _record_count_for_file(kind, manifest_entry),
|
|
142
|
+
"status": (manifest_entry or {}).get("status"),
|
|
143
|
+
"notes": (manifest_entry or {}).get("notes"),
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
return {
|
|
147
|
+
"case_id": case_id,
|
|
148
|
+
"root": "evidence",
|
|
149
|
+
"files": files,
|
|
150
|
+
"total_files": len(files),
|
|
151
|
+
"total_bytes": total_bytes,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def read_evidence_text(case_dir: Path, rel_path: str, *, max_bytes: int | None = None) -> dict[str, Any]:
|
|
156
|
+
target = _resolve_evidence_path(case_dir, rel_path)
|
|
157
|
+
if not target.is_file():
|
|
158
|
+
raise EvidenceNotFound(f"No evidence file at {rel_path!r}")
|
|
159
|
+
size = target.stat().st_size
|
|
160
|
+
cap = max_bytes if max_bytes is not None else size
|
|
161
|
+
raw = target.read_bytes()[:cap]
|
|
162
|
+
truncated = len(raw) < size
|
|
163
|
+
if rel_path.endswith(".gz") and not rel_path.endswith(".tar.gz"):
|
|
164
|
+
try:
|
|
165
|
+
raw = gzip.decompress(raw)
|
|
166
|
+
truncated = truncated or len(raw) >= cap
|
|
167
|
+
except OSError:
|
|
168
|
+
pass
|
|
169
|
+
text = raw.decode("utf-8", errors="replace")
|
|
170
|
+
content_type = "json" if rel_path.endswith(".json") else "text"
|
|
171
|
+
if content_type == "json":
|
|
172
|
+
try:
|
|
173
|
+
parsed = json.loads(text)
|
|
174
|
+
return {
|
|
175
|
+
"path": rel_path,
|
|
176
|
+
"size": size,
|
|
177
|
+
"truncated": truncated,
|
|
178
|
+
"content_type": "json",
|
|
179
|
+
"json": parsed,
|
|
180
|
+
}
|
|
181
|
+
except json.JSONDecodeError:
|
|
182
|
+
content_type = "text"
|
|
183
|
+
return {
|
|
184
|
+
"path": rel_path,
|
|
185
|
+
"size": size,
|
|
186
|
+
"truncated": truncated,
|
|
187
|
+
"content_type": content_type,
|
|
188
|
+
"text": text,
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def read_evidence_lines(
|
|
193
|
+
case_dir: Path,
|
|
194
|
+
rel_path: str,
|
|
195
|
+
*,
|
|
196
|
+
offset: int = 0,
|
|
197
|
+
limit: int | None = None,
|
|
198
|
+
) -> dict[str, Any]:
|
|
199
|
+
"""Return JSON-lines records from an events file with optional pagination."""
|
|
200
|
+
target = _resolve_evidence_path(case_dir, rel_path)
|
|
201
|
+
if not target.is_file():
|
|
202
|
+
raise EvidenceNotFound(f"No evidence file at {rel_path!r}")
|
|
203
|
+
|
|
204
|
+
if limit is None:
|
|
205
|
+
limit = 10_000_000
|
|
206
|
+
|
|
207
|
+
data = target.read_bytes()
|
|
208
|
+
if rel_path.endswith(".gz"):
|
|
209
|
+
data = gzip.decompress(data)
|
|
210
|
+
lines = data.decode("utf-8", errors="replace").splitlines()
|
|
211
|
+
total_lines = len(lines)
|
|
212
|
+
slice_lines = lines[offset : offset + limit]
|
|
213
|
+
records: list[Any] = []
|
|
214
|
+
for line in slice_lines:
|
|
215
|
+
line = line.strip()
|
|
216
|
+
if not line:
|
|
217
|
+
continue
|
|
218
|
+
try:
|
|
219
|
+
records.append(json.loads(line))
|
|
220
|
+
except json.JSONDecodeError:
|
|
221
|
+
records.append({"_raw": line})
|
|
222
|
+
return {
|
|
223
|
+
"path": rel_path,
|
|
224
|
+
"total_lines": total_lines,
|
|
225
|
+
"offset": offset,
|
|
226
|
+
"count": len(records),
|
|
227
|
+
"has_more": offset + len(slice_lines) < total_lines,
|
|
228
|
+
"records": records,
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def read_evidence_bytes(case_dir: Path, rel_path: str) -> tuple[Path, str]:
|
|
233
|
+
target = _resolve_evidence_path(case_dir, rel_path)
|
|
234
|
+
if not target.is_file():
|
|
235
|
+
raise EvidenceNotFound(f"No evidence file at {rel_path!r}")
|
|
236
|
+
media = "application/octet-stream"
|
|
237
|
+
if rel_path.endswith(".json"):
|
|
238
|
+
media = "application/json"
|
|
239
|
+
elif rel_path.endswith(".log"):
|
|
240
|
+
media = "text/plain"
|
|
241
|
+
elif rel_path.endswith(".gz"):
|
|
242
|
+
media = "application/gzip"
|
|
243
|
+
return target, media
|