From 22cca0f38668c38c763867dd7cd07c12e72db55e Mon Sep 17 00:00:00 2001 From: "william.lin" Date: Wed, 27 Nov 2024 10:36:46 -0800 Subject: [PATCH] NVSHAS-9669: Overall security score through REST API --- controller/api/apis.go | 84 +++++++++ controller/api/apis.yaml | 291 ++++++++++++++++++++------------ controller/api/internal_apis.go | 69 -------- controller/cache/compliance.go | 4 +- controller/cache/interface.go | 2 +- controller/rest/rest.go | 1 + controller/rest/system.go | 166 ++++++++++++++++++ 7 files changed, 440 insertions(+), 177 deletions(-) diff --git a/controller/api/apis.go b/controller/api/apis.go index 9db398a65..d131f5421 100644 --- a/controller/api/apis.go +++ b/controller/api/apis.go @@ -1711,6 +1711,90 @@ type RESTSystemStatsData struct { Stats *RESTSystemStats `json:"stats"` } +type RESTRiskScoreMetricsWL struct { + RunningPods int `json:"running_pods"` + PrivilegedWLs int `json:"privileged_wls"` + RootWLs int `json:"root_wls"` + DiscoverExtEPs int `json:"discover_ext_eps"` + MonitorExtEPs int `json:"monitor_ext_eps"` + ProtectExtEPs int `json:"protect_ext_eps"` + ThrtExtEPs int `json:"threat_ext_eps"` + VioExtEPs int `json:"violate_ext_eps"` +} + +type RESTRiskScoreMetricsGroup struct { + Groups int `json:"groups"` + DiscoverGroups int `json:"discover_groups"` + MonitorGroups int `json:"monitor_groups"` + ProtectGroups int `json:"protect_groups"` + ProfileDiscoverGroups int `json:"profile_discover_groups"` + ProfileMonitorGroups int `json:"profile_monitor_groups"` + ProfileProtectGroups int `json:"profile_protect_groups"` + DiscoverGroupsZD int `json:"discover_groups_zero_drift"` + MonitorGroupsZD int `json:"monitor_groups_zero_drift"` + ProtectGroupsZD int `json:"protect_groups_zero_drift"` +} + +type RESTRiskScoreMetricsCVE struct { + DiscoverCVEs int `json:"discover_cves"` + MonitorCVEs int `json:"monitor_cves"` + ProtectCVEs int `json:"protect_cves"` + PlatformCVEs int `json:"platform_cves"` + HostCVEs int `json:"host_cves"` +} + +type RESTRiskScoreMetrics struct { + Platform string `json:"platform"` + K8sVersion string `json:"kube_version"` + OCVersion string `json:"openshift_version"` + NewServiceMode string `json:"new_service_policy_mode"` + NewProfileMode string `json:"new_service_profile_mode"` + DenyAdmCtrlRules int `json:"deny_adm_ctrl_rules"` + Hosts int `json:"hosts"` + WLs RESTRiskScoreMetricsWL `json:"workloads"` + Groups RESTRiskScoreMetricsGroup `json:"groups"` + CVEs RESTRiskScoreMetricsCVE `json:"cves"` +} + +type RESTExposedEndpoint struct { + ID string `json:"id"` + Name string `json:"name"` + DisplayName string `json:"display_name"` + PodName string `json:"pod_name"` + Service string `json:"service"` + ThreatSeverity string `json:"severity"` + CriticalVuls int `json:"critical"` + HighVuls int `json:"high"` + MedVuls int `json:"medium"` + PolicyMode string `json:"policy_mode"` + PolicyAction string `json:"policy_action"` + Protos []string `json:"protocols,omitempty"` + Apps []string `json:"applications,omitempty"` + Ports []string `json:"ports,omitempty"` + Entries []*RESTConversationReportEntry `json:"entries"` +} + +type RESTSecurityScores struct { + NewServiceModeScore int `json:"new_service_mode_score"` + ServiceModeScore int `json:"service_mode_score"` + ServiceModeScoreBy100 int `json:"service_mode_score_by_100"` + ExposureScore int `json:"exposure_score"` + ExposureScoreBy100 int `json:"exposure_score_by_100"` + PrivilegedContainerScore int `json:"privileged_container_score"` + RunAsRootScore int `json:"run_as_root_score"` + AdmissionRuleScore int `json:"admission_rule_score"` + VulnerabilityScore int `json:"vulnerability_score"` + VulnerabilityScoreBy100 int `json:"vulnerability_score_by_100"` + SecurityRiskScore int `json:"security_risk_score"` +} + +type RESTScoreMetricsData struct { + Metrics *RESTRiskScoreMetrics `json:"metrics"` + Ingress []*RESTExposedEndpoint `json:"ingress"` + Egress []*RESTExposedEndpoint `json:"egress"` + SecurityScores *RESTSecurityScores `json:"security_scores"` +} + type RESTProxy struct { URL string `json:"url"` Username string `json:"username"` diff --git a/controller/api/apis.yaml b/controller/api/apis.yaml index cba33c205..dd54325db 100644 --- a/controller/api/apis.yaml +++ b/controller/api/apis.yaml @@ -5,7 +5,7 @@ swagger: '2.0' ################################################################################ info: description: Secure Docker and Kubernetes based container deployments with the NeuVector run-time security solution. - version: '5.4' + version: '5.4.2' license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html @@ -3679,11 +3679,11 @@ paths: responses: '200': description: Success - /v1/system/license: + /v1/system/score/metrics: get: tags: - System - summary: Show license + summary: Get system score metrics data security: - ApiKeyAuth: [] - TokenAuth: [] @@ -3693,37 +3693,7 @@ paths: '200': description: Success schema: - $ref: '#/definitions/RESTLicenseShowData' - delete: - tags: - - System - summary: Delete license - security: - - ApiKeyAuth: [] - - TokenAuth: [] - responses: - '200': - description: Success - /v1/system/license/update: - post: - tags: - - System - summary: License update - security: - - ApiKeyAuth: [] - - TokenAuth: [] - consumes: - - application/json - parameters: - - in: body - name: body - description: License key - required: true - schema: - $ref: '#/definitions/RESTLicenseKey' - responses: - '200': - description: Success + $ref: '#/definitions/RESTScoreMetricsData' /v1/user: get: tags: @@ -7550,77 +7520,6 @@ definitions: type: string format: password example: password - RESTLicenseInfo: - type: object - required: - - name - - email - - phone - - installation_id - properties: - name: - type: string - example: name - email: - type: string - format: email - example: user@mail.com - phone: - type: string - example: "" - id: - type: string - example: "" - id_type: - type: string - example: "" - installation_id: - type: string - example: ae2049871b8dd5b002fb7980f3a8c59f - RESTLicenseKey: - type: object - properties: - license_key: - type: string - example: "" - RESTLicenseRequest: - type: object - required: - - name - - email - - phone - properties: - name: - type: string - example: name - email: - type: string - format: email - example: user@mail.com - phone: - type: string - example: "" - RESTLicenseRequestData: - type: object - required: - - license_request - properties: - license_request: - $ref: '#/definitions/RESTLicenseRequest' - RESTLicenseShow: - type: object - required: - - info - properties: - info: - $ref: '#/definitions/RESTLicenseInfo' - RESTLicenseShowData: - type: object - required: - - license - properties: - license: - $ref: '#/definitions/RESTLicenseShow' RESTMappableRoles: type: object required: @@ -14189,3 +14088,185 @@ definitions: items: type: string example: "" + RESTRiskScoreMetricsWL: + type: object + properties: + running_pods: + type: integer + privileged_wls: + type: integer + root_wls: + type: integer + discover_ext_eps: + type: integer + monitor_ext_eps: + type: integer + protect_ext_eps: + type: integer + threat_ext_eps: + type: integer + violate_ext_eps: + type: integer + RESTRiskScoreMetricsGroup: + type: object + properties: + groups: + type: integer + discover_groups: + type: integer + monitor_groups: + type: integer + protect_groups: + type: integer + profile_discover_groups: + type: integer + profile_monitor_groups: + type: integer + profile_protect_groups: + type: integer + discover_groups_zero_drift: + type: integer + monitor_groups_zero_drift: + type: integer + protect_groups_zero_drift: + type: integer + RESTRiskScoreMetricsCVE: + type: object + properties: + discover_cves: + type: integer + monitor_cves: + type: integer + protect_cves: + type: integer + platform_cves: + type: integer + host_cves: + type: integer + RESTRiskScoreMetrics: + type: object + properties: + platform: + type: string + kube_version: + type: string + openshift_version: + type: string + new_service_policy_mode: + type: string + new_service_profile_mode: + type: string + deny_adm_ctrl_rules: + type: integer + hosts: + type: integer + workloads: + $ref: '#/definitions/RESTRiskScoreMetricsWL' + groups: + $ref: '#/definitions/RESTRiskScoreMetricsGroup' + cves: + $ref: '#/definitions/RESTRiskScoreMetricsCVE' + RESTExposedEndpoint: + type: object + properties: + id: + type: string + name: + type: string + display_name: + type: string + pod_name: + type: string + service: + type: string + severity: + type: string + critical: + type: integer + high: + type: integer + medium: + type: integer + policy_mode: + type: string + policy_action: + type: string + protocols: + type: array + items: + type: string + applications: + type: array + items: + type: string + ports: + type: array + items: + type: string + entries: + type: array + items: + $ref: '#/definitions/RESTConversationReportEntry' + RESTConversationReportEntry: + type: object + properties: + bytes: + type: integer + format: uint64 + sessions: + type: integer + format: uint32 + port: + type: string + application: + type: string + policy_action: + type: string + client_ip: + type: string + server_ip: + type: string + fqdn: + type: string + RESTSecurityScores: + type: object + properties: + new_service_mode_score: + type: integer + service_mode_score: + type: integer + service_mode_score_by_100: + type: integer + exposure_score: + type: integer + exposure_score_by_100: + type: integer + privileged_container_score: + type: integer + run_as_root_score: + type: integer + admission_rule_score: + type: integer + vulnerability_score: + type: integer + vulnerability_score_by_100: + type: integer + security_risk_score: + type: integer + RESTScoreMetricsData: + type: object + properties: + metrics: + type: array + items: + $ref: '#/definitions/RESTComplianceProfileConfig' + ingress: + type: array + items: + $ref: '#/definitions/RESTExposedEndpoint' + egress: + type: array + items: + $ref: '#/definitions/RESTExposedEndpoint' + security_scores: + $ref: '#/definitions/RESTSecurityScores' \ No newline at end of file diff --git a/controller/api/internal_apis.go b/controller/api/internal_apis.go index 908ba413b..914208fc7 100644 --- a/controller/api/internal_apis.go +++ b/controller/api/internal_apis.go @@ -139,75 +139,6 @@ type RESTProfilingData struct { Profiling *RESTProfiling `json:"profiling"` } -type RESTRiskScoreMetricsWL struct { - RunningPods int `json:"running_pods"` - PrivilegedWLs int `json:"privileged_wls"` - RootWLs int `json:"root_wls"` - DiscoverExtEPs int `json:"discover_ext_eps"` - MonitorExtEPs int `json:"monitor_ext_eps"` - ProtectExtEPs int `json:"protect_ext_eps"` - ThrtExtEPs int `json:"threat_ext_eps"` - VioExtEPs int `json:"violate_ext_eps"` -} - -type RESTRiskScoreMetricsGroup struct { - Groups int `json:"groups"` - DiscoverGroups int `json:"discover_groups"` - MonitorGroups int `json:"monitor_groups"` - ProtectGroups int `json:"protect_groups"` - ProfileDiscoverGroups int `json:"profile_discover_groups"` - ProfileMonitorGroups int `json:"profile_monitor_groups"` - ProfileProtectGroups int `json:"profile_protect_groups"` - DiscoverGroupsZD int `json:"discover_groups_zero_drift"` - MonitorGroupsZD int `json:"monitor_groups_zero_drift"` - ProtectGroupsZD int `json:"protect_groups_zero_drift"` -} - -type RESTRiskScoreMetricsCVE struct { - DiscoverCVEs int `json:"discover_cves"` - MonitorCVEs int `json:"monitor_cves"` - ProtectCVEs int `json:"protect_cves"` - PlatformCVEs int `json:"platform_cves"` - HostCVEs int `json:"host_cves"` -} - -type RESTRiskScoreMetrics struct { - Platform string `json:"platform"` - K8sVersion string `json:"kube_version"` - OCVersion string `json:"openshift_version"` - NewServiceMode string `json:"new_service_policy_mode"` - NewProfileMode string `json:"new_service_profile_mode"` - DenyAdmCtrlRules int `json:"deny_adm_ctrl_rules"` - Hosts int `json:"hosts"` - WLs RESTRiskScoreMetricsWL `json:"workloads"` - Groups RESTRiskScoreMetricsGroup `json:"groups"` - CVEs RESTRiskScoreMetricsCVE `json:"cves"` -} - -type RESTExposedEndpoint struct { - ID string `json:"id"` - Name string `json:"name"` - DisplayName string `json:"display_name"` - PodName string `json:"pod_name"` - Service string `json:"service"` - ThreatSeverity string `json:"severity"` - CriticalVuls int `json:"critical"` - HighVuls int `json:"high"` - MedVuls int `json:"medium"` - PolicyMode string `json:"policy_mode"` - PolicyAction string `json:"policy_action"` - Protos []string `json:"protocols,omitempty"` - Apps []string `json:"applications,omitempty"` - Ports []string `json:"ports,omitempty"` - Entries []*RESTConversationReportEntry `json:"entries"` -} - -type RESTInternalSystemData struct { - Metrics *RESTRiskScoreMetrics `json:"metrics"` - Ingress []*RESTExposedEndpoint `json:"ingress"` - Egress []*RESTExposedEndpoint `json:"egress"` -} - type RESTK8sNvRbacStatus struct { ClusterRoleErrors []string `json:"clusterrole_errors,omitempty"` // obsolete ClusterRoleBindingErrors []string `json:"clusterrolebinding_errors,omitempty"` // obsolete diff --git a/controller/cache/compliance.go b/controller/cache/compliance.go index 80000faf8..f6bcac2f0 100644 --- a/controller/cache/compliance.go +++ b/controller/cache/compliance.go @@ -203,7 +203,7 @@ type podVuls struct { MedVuls int } -func (m CacheMethod) GetRiskScoreMetrics(acc, accCaller *access.AccessControl) *api.RESTInternalSystemData { +func (m CacheMethod) GetRiskScoreMetrics(acc, accCaller *access.AccessControl) *api.RESTScoreMetricsData { var s api.RESTRiskScoreMetrics s.Platform, s.K8sVersion, s.OCVersion = m.GetPlatform() @@ -513,7 +513,7 @@ func (m CacheMethod) GetRiskScoreMetrics(acc, accCaller *access.AccessControl) * } cacheMutexRUnlock() - return &api.RESTInternalSystemData{Metrics: &s, Ingress: ins, Egress: outs} + return &api.RESTScoreMetricsData{Metrics: &s, Ingress: ins, Egress: outs} } // --- diff --git a/controller/cache/interface.go b/controller/cache/interface.go index b9f8ac15c..7f2656c28 100644 --- a/controller/cache/interface.go +++ b/controller/cache/interface.go @@ -13,7 +13,7 @@ import ( ) type CacheInterface interface { - GetRiskScoreMetrics(acc, accCaller *access.AccessControl) *api.RESTInternalSystemData + GetRiskScoreMetrics(acc, accCaller *access.AccessControl) *api.RESTScoreMetricsData GetAllHosts(acc *access.AccessControl) []*api.RESTHost GetAllHostsRisk(acc *access.AccessControl) []*common.WorkloadRisk diff --git a/controller/rest/rest.go b/controller/rest/rest.go index c5e840201..3c3aededc 100644 --- a/controller/rest/rest.go +++ b/controller/rest/rest.go @@ -1654,6 +1654,7 @@ func StartRESTServer(isNewCluster bool, isLead bool) { r.GET("/v1/system/config", handlerSystemGetConfig) // supported 'scope' query parameter values: ""(all, default)/"fed"/"local". no payload r.GET("/v2/system/config", handlerSystemGetConfigV2) // supported 'scope' query parameter values: ""(all, default)/"fed"/"local". no payload. starting from 5.0, rest client should call this api. r.GET("/v1/system/alerts", handlerSystemGetAlerts) + r.GET("/v1/system/score/metrics", handlerGetSystemScoreMetrics) r.PATCH("/v1/system/config", handlerSystemConfig) r.PATCH("/v2/system/config", handlerSystemConfigV2) r.POST("/v1/system/config/webhook", handlerSystemWebhookCreate) diff --git a/controller/rest/system.go b/controller/rest/system.go index a65c527c1..ef460f74e 100644 --- a/controller/rest/system.go +++ b/controller/rest/system.go @@ -14,6 +14,7 @@ import ( "errors" "fmt" "io" + "math" "mime" "mime/multipart" "net" @@ -219,6 +220,171 @@ func handlerSystemSummary(w http.ResponseWriter, r *http.Request, ps httprouter. restRespSuccess(w, r, &resp, acc, login, nil, "Get system summary") } +func handlerGetSystemScoreMetrics(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + log.WithFields(log.Fields{"URL": r.URL.String()}).Debug("") + defer r.Body.Close() + + acc, login := getAccessControl(w, r, "") + if acc == nil { + return + } + + // any user can call this API to get system summary, but only users with global 'config' permission can see non-zero host/controller/agent/scanner counters + accSysConfig := acc.BoostPermissions(share.PERM_SYSTEM_CONFIG) + isGlobalUser := true + if r := login.domainRoles[access.AccessDomainGlobal]; r == "" { + if permits := login.extraDomainPermits[access.AccessDomainGlobal]; permits.IsEmpty() { + isGlobalUser = false + } + } + + resp := cacher.GetRiskScoreMetrics(accSysConfig, acc) + metrics := resp.Metrics + + const MAX_SERVICE_MODE_SCORE = 26 + const MAX_NEW_SERVICE_MODE_SCORE = 2 + const MAX_PRIVILEGED_CONTAINER_SCORE = 4 + const MAX_RUN_AS_ROOT_CONTAINER_SCORE = 4 + const MAX_ADMISSION_RULE_SCORE = 4 + const MAX_PLATFORM_VUL_SCORE = 2 + const MAX_HOST_VUL_SCORE = 6 + const MAX_POD_VUL_SCORE = 8 + const MAX_MODE_EXPOSURE = 10.0 + const MAX_VIOLATE_EXPOSURE = 12.0 + const MAX_THREAT_EXPOSURE = 20.0 + const THRESHOLD_EXPOSURE_100 = 5.0 + const THRESHOLD_EXPOSURE_1000 = 25.0 + const THRESHOLD_EXPOSURE_10000 = 62.5 + const RATIO_DISCOVER_VUL = 1.0 / 15 + const RATIO_MONITOR_VUL = 1.0 / 60 + const RATIO_PROTECT_VUL = 1.0 / 120 + const RATIO_HOST_VUL = 1.0 / 20 + const RATIO_PROTECT_MONITOR_EXPOSURE = 1 + const RATIO_DISCOVER_EXPOSURE = 3 + const RATIO_VIOLATED_EXPOSURE = 4 + const RATIO_THREATENED_EXPOSURE = 8 + + // Formula for security risk score: + // Good: 0 <= Score < 21 + // Fair: 21 <= Score < 51 + // Poor: 51 <= Score + + // Service connection risk (New service mode score). Max newServiceModeScore: 4 + newServiceModeScore := 0 + if metrics.NewServiceMode == share.PolicyModeLearn { + newServiceModeScore += MAX_NEW_SERVICE_MODE_SCORE + } + if metrics.NewProfileMode == share.PolicyModeLearn { + newServiceModeScore += MAX_NEW_SERVICE_MODE_SCORE + } + + // Service connection risk (Service mode score). Max serviceModeScore: 26 + var serviceModeScoreBy100 int + if metrics.Groups.Groups != 0 { + serviceModeScoreBy100 = int(math.Ceil( + (float64(metrics.Groups.DiscoverGroups+metrics.Groups.ProfileDiscoverGroups)*0.5 - float64(metrics.Groups.DiscoverGroupsZD)*0.3) / + float64(metrics.Groups.Groups) * 100)) + } + serviceModeScore := int(math.Ceil(float64(serviceModeScoreBy100) / 100.0 * MAX_SERVICE_MODE_SCORE)) + + // Ingress/Egress exposure risk. Max: 42 + var exposureScore int + totalRunningPods := float64(metrics.WLs.RunningPods) + if totalRunningPods > 0 { + var exposureDensity float64 + if totalRunningPods > 10000 { + exposureDensity = 1.0 / THRESHOLD_EXPOSURE_10000 + } else if totalRunningPods > 1000 { + exposureDensity = 1.0 / (THRESHOLD_EXPOSURE_1000 + ((THRESHOLD_EXPOSURE_10000 - THRESHOLD_EXPOSURE_1000) * totalRunningPods / 10000.0)) + } else if totalRunningPods > 100 { + exposureDensity = 1.0 / (THRESHOLD_EXPOSURE_100 + ((THRESHOLD_EXPOSURE_1000 - THRESHOLD_EXPOSURE_100) * totalRunningPods / 1000.0)) + } else { + exposureDensity = 1.0 / (1.0 + (THRESHOLD_EXPOSURE_100 * totalRunningPods / 100.0)) + } + modeScore := float64(metrics.WLs.ProtectExtEPs+metrics.WLs.MonitorExtEPs)*exposureDensity*RATIO_PROTECT_MONITOR_EXPOSURE + + float64(metrics.WLs.DiscoverExtEPs)*exposureDensity*RATIO_DISCOVER_EXPOSURE + violationScore := float64(metrics.WLs.VioExtEPs) * exposureDensity * RATIO_VIOLATED_EXPOSURE + threatScore := float64(metrics.WLs.ThrtExtEPs) * exposureDensity * RATIO_THREATENED_EXPOSURE + if modeScore > MAX_MODE_EXPOSURE { + modeScore = MAX_MODE_EXPOSURE + } + if violationScore > MAX_VIOLATE_EXPOSURE { + violationScore = MAX_VIOLATE_EXPOSURE + } + if threatScore > MAX_THREAT_EXPOSURE { + threatScore = MAX_THREAT_EXPOSURE + } + exposureScore = int(math.Ceil(modeScore + violationScore + threatScore)) + } + exposureScoreBy100 := int(math.Ceil(float64(exposureScore) * 100 / (MAX_MODE_EXPOSURE + MAX_VIOLATE_EXPOSURE + MAX_THREAT_EXPOSURE))) + + // Max: 4, 4, 4 + var privilegedContainerScore int + var runAsRootScore int + var admissionRuleScore int + if metrics.WLs.PrivilegedWLs > 0 { + privilegedContainerScore = MAX_PRIVILEGED_CONTAINER_SCORE + } + if metrics.WLs.RootWLs > 0 { + runAsRootScore = MAX_RUN_AS_ROOT_CONTAINER_SCORE + } + if metrics.DenyAdmCtrlRules > 0 { + admissionRuleScore = MAX_ADMISSION_RULE_SCORE + } + + // Vulnerability exploit risk (Only PodScore). Max: 16 + var podScore float64 + if totalRunningPods > 0 { + podScore = float64(metrics.CVEs.DiscoverCVEs)/totalRunningPods*RATIO_DISCOVER_VUL + + float64(metrics.CVEs.MonitorCVEs)/totalRunningPods*RATIO_MONITOR_VUL + + float64(metrics.CVEs.ProtectCVEs)/totalRunningPods*RATIO_PROTECT_VUL + if podScore > MAX_POD_VUL_SCORE { + podScore = MAX_POD_VUL_SCORE + } + } + var hostScore float64 + if metrics.Hosts > 0 { + hostScore = (float64(metrics.CVEs.HostCVEs) / float64(metrics.Hosts)) * RATIO_HOST_VUL + if hostScore > MAX_HOST_VUL_SCORE { + hostScore = MAX_HOST_VUL_SCORE + } + } + var platformScore float64 + if metrics.CVEs.PlatformCVEs > 0 { + platformScore = MAX_PLATFORM_VUL_SCORE + } + + vulnerabilityScore := int(math.Ceil(podScore + hostScore + platformScore)) + vulnerabilityScoreBy100 := int(math.Ceil(float64(vulnerabilityScore) * 100 / (MAX_POD_VUL_SCORE + MAX_HOST_VUL_SCORE + MAX_PLATFORM_VUL_SCORE))) + + var securityRiskScore int + if isGlobalUser { + securityRiskScore = newServiceModeScore + serviceModeScore + exposureScore + privilegedContainerScore + + runAsRootScore + admissionRuleScore + vulnerabilityScore + } else { + _score := float64(serviceModeScore+exposureScore+privilegedContainerScore+runAsRootScore+vulnerabilityScore) / + (MAX_MODE_EXPOSURE + MAX_VIOLATE_EXPOSURE + MAX_THREAT_EXPOSURE + MAX_PRIVILEGED_CONTAINER_SCORE + + MAX_RUN_AS_ROOT_CONTAINER_SCORE + MAX_POD_VUL_SCORE + MAX_HOST_VUL_SCORE + MAX_PLATFORM_VUL_SCORE) + securityRiskScore = int(_score * 100) + } + + resp.SecurityScores = &api.RESTSecurityScores{ + NewServiceModeScore: newServiceModeScore, + ServiceModeScore: serviceModeScore, + ServiceModeScoreBy100: serviceModeScoreBy100, + ExposureScore: exposureScore, + ExposureScoreBy100: exposureScoreBy100, + PrivilegedContainerScore: privilegedContainerScore, + RunAsRootScore: runAsRootScore, + AdmissionRuleScore: admissionRuleScore, + VulnerabilityScore: vulnerabilityScore, + VulnerabilityScoreBy100: vulnerabilityScoreBy100, + SecurityRiskScore: securityRiskScore, + } + + restRespSuccess(w, r, resp, acc, login, nil, "Get system internal data") +} + func handlerSystemGetConfigBase(apiVer string, w http.ResponseWriter, r *http.Request, ps httprouter.Params) { log.WithFields(log.Fields{"URL": r.URL.String()}).Debug() defer r.Body.Close()