Repository: clouditor/clouditor
Pull request #660 (2022-05-04 09:41:40)

Quick fix for handling evidences from different collection tools
**Problem**
We have to somehow deal in the evaluation with evidences from different discoverers for the same security feature.  

So far, a rego policy is evaluated if the parent object of an security feature is available (e.g. MalwareProtection). But currently we nil it in the Clouditor since we cannot determine the corresponding security features (e.g. MalwareProtectionEnabled).

**Solution**
For a solution now, we only evaluate evidences with metrics if the corresponding fields (security features, not just parent) are not nil. For example, since the Clouditor is currently not able to fill the MalwareProtection, the evaluation for the metricIDs MalwareProtectionEnabled and MalwareProtectionOutput will not be evaluated. This is done by other tools in the MEDINA context.

For other security features other tools can not discover, we set it it to a default value (false, 0, "" ...).

**Alternatives**
We'll have to figure out how to deal with the problem later #659.

codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/660?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> Merging [#660](https://codecov.io/gh/clouditor/clouditor/pull/660?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (9e82e17) into [main](https://codecov.io/gh/clouditor/clouditor/commit/01f153aa5ec7f5bc778f0172f0d0ab27e3470dcb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (01f153a) will **increase** coverage by `0.09%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##             main     #660      +/-   ##
==========================================
+ Coverage   81.31%   81.40%   +0.09%     
==========================================
  Files          64       64              
  Lines        5737     5744       +7     
==========================================
+ Hits         4665     4676      +11     
+ Misses        830      827       -3     
+ Partials      242      241       -1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `81.40% <100.00%> (+0.09%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/clouditor/clouditor/pull/660?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | Coverage Δ | |
|---|---|---|
| [internal/testutil/storage.go](https://codecov.io/gh/clouditor/clouditor/pull/660/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-aW50ZXJuYWwvdGVzdHV0aWwvc3RvcmFnZS5nbw==) | `47.61% <100.00%> (ø)` | |
| [service/discovery/azure/compute.go](https://codecov.io/gh/clouditor/clouditor/pull/660/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvY29tcHV0ZS5nbw==) | `88.35% <100.00%> (+0.49%)` | :arrow_up: |
| [service/discovery/discovery.go](https://codecov.io/gh/clouditor/clouditor/pull/660/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvZGlzY292ZXJ5Lmdv) | `90.27% <100.00%> (+0.04%)` | :arrow_up: |
| [service/discovery/azure/azure.go](https://codecov.io/gh/clouditor/clouditor/pull/660/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9kaXNjb3ZlcnkvYXp1cmUvYXp1cmUuZ28=) | `84.41% <0.00%> (+5.19%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/clouditor/clouditor/pull/660?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/660?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Last update [01f153a...9e82e17](https://codecov.io/gh/clouditor/clouditor/pull/660?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor).

lebogg: The new approach is:
1) Cached metrics are tied to resource types AND the tool. This allows discovering an entire evidence by splitting the work to different discoverers (e.g. Clouditor and Wazuh in Medina). Such a split can avoid multiple assessment results for the same evidence.
2) For 1) to work, we now check applicability by checking if a security feature is set (not null). This allows a finer granularity for deciding which security features (and therefore metrics) are evaluated by the respective tool. Before the whole parent (e.g. atRestEncryption) was checked instead of a single security feature (atRestEncryption.enabled).

Patch:
diff --git a/go.mod b/go.mod
index d41e4b19..11a0587c 100644
--- a/go.mod
+++ b/go.mod
@@ -36,9 +36,9 @@ require (
 	gorm.io/driver/postgres v1.3.1
 	gorm.io/driver/sqlite v1.3.1
 	gorm.io/gorm v1.23.2
-	k8s.io/api v0.23.4
-	k8s.io/apimachinery v0.23.4
-	k8s.io/client-go v0.23.4
+	k8s.io/api v0.23.6
+	k8s.io/apimachinery v0.23.6
+	k8s.io/client-go v0.23.6
 )
 
 // tools dependencies
diff --git a/go.sum b/go.sum
index f849ae47..8fad7375 100644
--- a/go.sum
+++ b/go.sum
@@ -1758,36 +1758,16 @@ k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
 k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs=
 k8s.io/api v0.23.4 h1:85gnfXQOWbJa1SiWGpE9EEtHs0UVvDyIsSMpEtl2D4E=
 k8s.io/api v0.23.4/go.mod h1:i77F4JfyNNrhOjZF7OwwNJS5Y1S9dpwvb9iYRYRczfI=
-k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
-k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
-k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
-k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U=
+k8s.io/api v0.23.6 h1:yOK34wbYECH4RsJbQ9sfkFK3O7f/DUHRlzFehkqZyVw=
+k8s.io/api v0.23.6/go.mod h1:1kFaYxGCFHYp3qd6a85DAj/yW8aVD6XLZMqJclkoi9g=
 k8s.io/apimachinery v0.23.4 h1:fhnuMd/xUL3Cjfl64j5ULKZ1/J9n8NuQEgNL+WXWfdM=
 k8s.io/apimachinery v0.23.4/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
-k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
-k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
-k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
-k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ=
-k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
-k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
-k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
-k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y=
+k8s.io/apimachinery v0.23.6 h1:RH1UweWJkWNTlFx0D8uxOpaU1tjIOvVVWV/bu5b3/NQ=
+k8s.io/apimachinery v0.23.6/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
 k8s.io/client-go v0.23.4 h1:YVWvPeerA2gpUudLelvsolzH7c2sFoXXR5wM/sWqNFU=
 k8s.io/client-go v0.23.4/go.mod h1:PKnIL4pqLuvYUK1WU7RLTMYKPiIh7MYShLshtRY9cj0=
-k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
-k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
-k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
-k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
-k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI=
-k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
-k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
-k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
-k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
-k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4=
-k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
-k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
+k8s.io/client-go v0.23.6 h1:7h4SctDVQAQbkHQnR4Kzi7EyUyvla5G1pFWf4+Od7hQ=
+k8s.io/client-go v0.23.6/go.mod h1:Umt5icFOMLV/+qbtZ3PR0D+JA6lvvb3syzodv4irpK4=
 k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
 k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
diff --git a/policies/bundles/AnomalyDetectionEnabled/metric.rego b/policies/bundles/AnomalyDetectionEnabled/metric.rego
index 22b82b91..04a753e8 100644
--- a/policies/bundles/AnomalyDetectionEnabled/metric.rego
+++ b/policies/bundles/AnomalyDetectionEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-ad := input.anomalyDetection
+enabled := input.anomalyDetection.enabled
 
 applicable {
-	ad
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, ad.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/AnomalyDetectionOutput/metric.rego b/policies/bundles/AnomalyDetectionOutput/metric.rego
index 74b37ba4..61641ab2 100644
--- a/policies/bundles/AnomalyDetectionOutput/metric.rego
+++ b/policies/bundles/AnomalyDetectionOutput/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-ad := input.anomalyDetection
+output := input.anomalyDetection.applicationLogging.loggingService
 
 applicable {
-	ad
+	output != null
 }
 
 compliant {
-	isIn(data.target_value, ad.output)
+	isIn(data.target_value, output)
 }
diff --git a/policies/bundles/AnonymousAuthentication/metric.rego b/policies/bundles/AnonymousAuthentication/metric.rego
index de45a8e2..88912225 100644
--- a/policies/bundles/AnonymousAuthentication/metric.rego
+++ b/policies/bundles/AnonymousAuthentication/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-cba := input.certificateBasedAuthentication
+enabled := input.certificateBasedAuthentication.enabled
 
 applicable {
-	cba
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, cba.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/AtRestEncryptionAlgorithm/metric.rego b/policies/bundles/AtRestEncryptionAlgorithm/metric.rego
index 0997b509..97c3e122 100644
--- a/policies/bundles/AtRestEncryptionAlgorithm/metric.rego
+++ b/policies/bundles/AtRestEncryptionAlgorithm/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-enc := input.atRestEncryption
+algorithm := input.atRestEncryption.algorithm
 
 applicable {
-	enc
+	algorithm != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, enc.algorithm)
+	compare(data.operator, data.target_value, algorithm)
 }
diff --git a/policies/bundles/AtRestEncryptionEnabled/metric.rego b/policies/bundles/AtRestEncryptionEnabled/metric.rego
index cb6df799..330bd238 100644
--- a/policies/bundles/AtRestEncryptionEnabled/metric.rego
+++ b/policies/bundles/AtRestEncryptionEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-enc := input.atRestEncryption
+enabled := input.atRestEncryption.enabled
 
 applicable {
-	enc
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, enc.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/AutomaticUpdatesEnabled/metric.rego b/policies/bundles/AutomaticUpdatesEnabled/metric.rego
index 5834f1a5..d91e0f0d 100644
--- a/policies/bundles/AutomaticUpdatesEnabled/metric.rego
+++ b/policies/bundles/AutomaticUpdatesEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-autoUpdates := input.automaticUpdates
+enabled := input.automaticUpdates.enabled
 
 applicable {
-	autoUpdates
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, autoUpdates.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/AutomaticUpdatesInterval/metric.rego b/policies/bundles/AutomaticUpdatesInterval/metric.rego
index 486c1fff..7c3e25df 100644
--- a/policies/bundles/AutomaticUpdatesInterval/metric.rego
+++ b/policies/bundles/AutomaticUpdatesInterval/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-autoUpdates := input.automaticUpdates
+interval := input.automaticUpdates.interval
 
 applicable {
-	autoUpdates
+	interval != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, autoUpdates.interval)
+	compare(data.operator, data.target_value, interval)
 }
diff --git a/policies/bundles/AutomaticUpdatesSecurityOnly/metric.rego b/policies/bundles/AutomaticUpdatesSecurityOnly/metric.rego
index ffcd086d..bd354b83 100644
--- a/policies/bundles/AutomaticUpdatesSecurityOnly/metric.rego
+++ b/policies/bundles/AutomaticUpdatesSecurityOnly/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-autoUpdates := input.automaticUpdates
+securityOnly := input.automaticUpdates.securityOnly
 
 applicable {
-	autoUpdates
+	securityOnly != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, autoUpdates.securityOnly)
+	compare(data.operator, data.target_value, securityOnly)
 }
diff --git a/policies/bundles/BootLoggingEnabled/metric.rego b/policies/bundles/BootLoggingEnabled/metric.rego
index a110dcb8..589d99c1 100644
--- a/policies/bundles/BootLoggingEnabled/metric.rego
+++ b/policies/bundles/BootLoggingEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-bootLogging := input.bootLogging
+enabled := input.bootLogging.enabled
 
 applicable {
-	bootLogging
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, bootLogging.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/BootLoggingOutput/metric.rego b/policies/bundles/BootLoggingOutput/metric.rego
index 36525532..a4fd5d62 100644
--- a/policies/bundles/BootLoggingOutput/metric.rego
+++ b/policies/bundles/BootLoggingOutput/metric.rego
@@ -8,12 +8,12 @@ default compliant = false
 
 metricConfiguration := data.target_value
 
-bootLogging := input.bootLogging
+output := input.bootLogging.loggingService
 
 applicable {
-	bootLogging
+	output != null
 }
 
 compliant {
-	isIn(data.target_value, bootLogging.loggingService)
+	isIn(data.target_value, output)
 }
diff --git a/policies/bundles/BootLoggingRetention/metric.rego b/policies/bundles/BootLoggingRetention/metric.rego
index 75210d03..bfc00584 100644
--- a/policies/bundles/BootLoggingRetention/metric.rego
+++ b/policies/bundles/BootLoggingRetention/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-bootLogging := input.bootLogging
+retentionPeriod := input.bootLogging.retentionPeriod
 
 applicable {
-	bootLogging
+	retentionPeriod != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, bootLogging.retentionPeriod)
+	compare(data.operator, data.target_value, retentionPeriod)
 }
diff --git a/policies/bundles/BroadAssignments/metric.rego b/policies/bundles/BroadAssignments/metric.rego
index f91d2eb0..0c47ce48 100644
--- a/policies/bundles/BroadAssignments/metric.rego
+++ b/policies/bundles/BroadAssignments/metric.rego
@@ -7,13 +7,13 @@ default applicable = false
 default compliant = false
 
 # TODO(lebogg): Not yet in VOC. Check if `rBAC` is correct representation in JSON
-rbac := input.rBAC
+broadAssignments := input.rBAC.broadAssignments
 
 applicable {
-	rbac
+	broadAssignments != null
 }
 
 compliant {
 	# TODO(all): Target value ?
-	compare(data.operator, data.target_value, rbac.broadAssignments)
+	compare(data.operator, data.target_value, broadAssignments)
 }
diff --git a/policies/bundles/CustomerKeyEncryption/metric.rego b/policies/bundles/CustomerKeyEncryption/metric.rego
index 314ff1a8..53fa0e02 100644
--- a/policies/bundles/CustomerKeyEncryption/metric.rego
+++ b/policies/bundles/CustomerKeyEncryption/metric.rego
@@ -4,13 +4,13 @@ default applicable = false
 
 default compliant = false
 
-enc := input.atRestEncryption
+keyUrl := input.atRestEncryption.keyUrl
 
 applicable {
-	enc
+	keyUrl != null
 }
 
 compliant {
-	# Check if keyUrl is set. It is only set in the customer key encryption case.
-	enc.keyUrl
+	# Check if keyUrl is set (not an empty string)
+	keyUrl != ""
 }
diff --git a/policies/bundles/L3FirewallEnabled/metric.rego b/policies/bundles/L3FirewallEnabled/metric.rego
index b0196a30..d520cad7 100644
--- a/policies/bundles/L3FirewallEnabled/metric.rego
+++ b/policies/bundles/L3FirewallEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-l3f := input.l3Firewall
+enabled := input.l3Firewall.enabled
 
 applicable {
-	l3f
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, l3f.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/L3FirewallRestrictedPorts/metric.rego b/policies/bundles/L3FirewallRestrictedPorts/metric.rego
index 399e3495..36c25477 100644
--- a/policies/bundles/L3FirewallRestrictedPorts/metric.rego
+++ b/policies/bundles/L3FirewallRestrictedPorts/metric.rego
@@ -6,13 +6,13 @@ default applicable = false
 
 default compliant = false
 
-l3f := input.l3Firewall
+restrictedPorts := input.l3Firewall.restrictedPorts
 
 applicable {
-	l3f
+	restrictedPorts != null
 }
 
 # TODO(all): Maybe change restrictet ports to array of strings. See comment in Ontology.
 compliant {
-	compare(data.operator, data.target_value, l3f.restrictedPorts)
+	compare(data.operator, data.target_value, restrictedPorts)
 }
diff --git a/policies/bundles/MalwareProtectionEnabled/metric.rego b/policies/bundles/MalwareProtectionEnabled/metric.rego
index 71e77296..72cfe5d6 100644
--- a/policies/bundles/MalwareProtectionEnabled/metric.rego
+++ b/policies/bundles/MalwareProtectionEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-mp := input.malwareProtection
+enabled := input.malwareProtection.enabled
 
 applicable {
-	mp
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, mp.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/MalwareProtectionOutput/metric.rego b/policies/bundles/MalwareProtectionOutput/metric.rego
index bc380300..82de26ec 100644
--- a/policies/bundles/MalwareProtectionOutput/metric.rego
+++ b/policies/bundles/MalwareProtectionOutput/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-mp := input.malwareProtection.applicationLogging
+output := input.malwareProtection.applicationLogging.loggingService
 
 applicable {
-	mp
+	output != null
 }
 
 compliant {
-	isIn(data.target_value, mp.loggingService)
+	isIn(data.target_value, output)
 }
diff --git a/policies/bundles/MixedDuties/metric.rego b/policies/bundles/MixedDuties/metric.rego
index 3ac1e76f..b1e89aaf 100644
--- a/policies/bundles/MixedDuties/metric.rego
+++ b/policies/bundles/MixedDuties/metric.rego
@@ -7,13 +7,13 @@ default applicable = false
 default compliant = false
 
 # TODO(lebogg): Check if `rBAC` is correct representation in JSON
-rbac := input.rBAC
+mixedDuties := input.rBAC.mixedDuties
 
 applicable {
-	rbac
+	mixedDuties != null
 }
 
 compliant {
 	# TODO(all): Target value ?
-	compare(data.operator, data.target_value, rbac.mixedDuties)
+	compare(data.operator, data.target_value, mixedDuties)
 }
diff --git a/policies/bundles/MutualAuthentication/metric.rego b/policies/bundles/MutualAuthentication/metric.rego
index 08a3a803..54f2f0c3 100644
--- a/policies/bundles/MutualAuthentication/metric.rego
+++ b/policies/bundles/MutualAuthentication/metric.rego
@@ -6,19 +6,19 @@ default applicable = false
 
 default compliant = false
 
-cba := input.certificateBasedAuthentication
+cbaEnabled := input.certificateBasedAuthentication.enabled
 
-enc := input.httpEndpoint.transportEncryption
+encEnabled := input.httpEndpoint.transportEncryption.enabled
 
 applicable {
-	cba
-	enc
+	cbaEnabled != null
+	encEnabled != null
 }
 
 # TODO(all): Actually, in this case, data.operator and data.target_value are for the overall metric. Not single checks.
 # TODO(cont.): That would mean it is reather compliant = data.targetValue
 # TODO(lebogg): Look if we can access other evaluated metrics within this policy, e.g. TransportEncryptionEnabled
 compliant {
-	compare(data.operator, data.target_value, cba.enabled)
-	compare(data.operator, data.target_value, enc.enabled)
+	compare(data.operator, data.target_value, cbaEnabled)
+	compare(data.operator, data.target_value, encEnabled)
 }
diff --git a/policies/bundles/OSLoggingEnabled/metric.rego b/policies/bundles/OSLoggingEnabled/metric.rego
index 563c3fc1..7e57f88a 100644
--- a/policies/bundles/OSLoggingEnabled/metric.rego
+++ b/policies/bundles/OSLoggingEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-OSLogging := input.oSLogging
+enabled := input.oSLogging.enabled
 
 applicable {
-	OSLogging
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, OSLogging.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/OSLoggingOutput/metric.rego b/policies/bundles/OSLoggingOutput/metric.rego
index 0ae486b4..87d94f53 100644
--- a/policies/bundles/OSLoggingOutput/metric.rego
+++ b/policies/bundles/OSLoggingOutput/metric.rego
@@ -8,12 +8,12 @@ default compliant = false
 
 metricConfiguration := data.target_value
 
-OSLogging := input.oSLogging
+output := input.oSLogging.loggingService
 
 applicable {
-	OSLogging
+	output != null
 }
 
 compliant {
-	isIn(data.target_value, OSLogging.loggingService)
+	isIn(data.target_value, output)
 }
diff --git a/policies/bundles/OSLoggingRetention/metric.rego b/policies/bundles/OSLoggingRetention/metric.rego
index b39b1675..21bc1286 100644
--- a/policies/bundles/OSLoggingRetention/metric.rego
+++ b/policies/bundles/OSLoggingRetention/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-OSLogging := input.oSLogging
+retentionPeriod := input.oSLogging.retentionPeriod
 
 applicable {
-	OSLogging
+	retentionPeriod != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, OSLogging.retentionPeriod)
+	compare(data.operator, data.target_value, retentionPeriod)
 }
diff --git a/policies/bundles/RuntimeVersion/metric.rego b/policies/bundles/RuntimeVersion/metric.rego
index 88b814d1..ffc526be 100644
--- a/policies/bundles/RuntimeVersion/metric.rego
+++ b/policies/bundles/RuntimeVersion/metric.rego
@@ -6,13 +6,13 @@ default applicable = false
 
 default compliant = false
 
-runtimeLanguage := input.runtimeLanguage
+runtimeLanguage := input.runtime.language
 
-runtimeVersion := input.runtimeVersion
+runtimeVersion := input.runtime.version
 
 applicable {
-	runtimeLanguage
-	runtimeVersion
+	runtimeLanguage != null
+	runtimeVersion != null
 }
 
 # TODO(all): Consider to put `operator` into list of target_values for more granularity
diff --git a/policies/bundles/SingleSignOnEnabled/metric.rego b/policies/bundles/SingleSignOnEnabled/metric.rego
index eeabf983..a29ca38c 100644
--- a/policies/bundles/SingleSignOnEnabled/metric.rego
+++ b/policies/bundles/SingleSignOnEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-sso := input.singleSignOn
+enabled := input.singleSignOn.enabled
 
 applicable {
-	sso
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, sso.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/TLSVersion/metric.rego b/policies/bundles/TLSVersion/metric.rego
index 09d16609..37312e0d 100644
--- a/policies/bundles/TLSVersion/metric.rego
+++ b/policies/bundles/TLSVersion/metric.rego
@@ -7,18 +7,18 @@ default compliant = false
 
 default applicable = false
 
-endpoint := input.httpEndpoint
+version := input.httpEndpoint.transportEncryption.tlsVersion
 
 applicable {
-	endpoint
+	version != null
 }
 
 compliant {
 	# If target_value is a list of strings/numbers
-	isIn(data.target_value, endpoint.transportEncryption.tlsVersion)
+	isIn(data.target_value, version)
 }
 
 compliant {
 	# If target_value is the version number represented as int/float
-	compare(data.operator, data.target_value, endpoint.transportEncryption.tlsVersion)
+	compare(data.operator, data.target_value, version)
 }
diff --git a/policies/bundles/TransportEncryptionAlgorithm/metric.rego b/policies/bundles/TransportEncryptionAlgorithm/metric.rego
index 93f56703..59780d64 100644
--- a/policies/bundles/TransportEncryptionAlgorithm/metric.rego
+++ b/policies/bundles/TransportEncryptionAlgorithm/metric.rego
@@ -7,10 +7,12 @@ default compliant = false
 
 default applicable = false
 
+algorithm := endpoint.transportEncryption.algorithm
+
 applicable {
-	endpoint
+	algorithm != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, endpoint.transportEncryption.algorithm)
+	compare(data.operator, data.target_value, algorithm)
 }
diff --git a/policies/bundles/TransportEncryptionEnabled/metric.rego b/policies/bundles/TransportEncryptionEnabled/metric.rego
index 91df0818..a7d86c4c 100644
--- a/policies/bundles/TransportEncryptionEnabled/metric.rego
+++ b/policies/bundles/TransportEncryptionEnabled/metric.rego
@@ -6,13 +6,13 @@ default compliant = false
 
 default applicable = false
 
-endpoint := input.httpEndpoint
+enabled := input.httpEndpoint.transportEncryption.enabled
 
 applicable {
-	endpoint
+	enabled != null
 }
 
 # TODO(all): Alternatively, curly braces can be removed and a single assignment used. But for readability and consistency (having multiple compares, see mutual auth) I let it this way?
 compliant {
-	compare(data.operator, data.target_value, endpoint.transportEncryption.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/bundles/TransportEncryptionEnforced/metric.rego b/policies/bundles/TransportEncryptionEnforced/metric.rego
index 516e541b..ede12640 100644
--- a/policies/bundles/TransportEncryptionEnforced/metric.rego
+++ b/policies/bundles/TransportEncryptionEnforced/metric.rego
@@ -6,12 +6,12 @@ default compliant = false
 
 default applicable = false
 
-endpoint := input.httpEndpoint
+enforced := input.httpEndpoint.transportEncryption.enforced
 
 applicable {
-	endpoint
+	enforced != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, endpoint.transportEncryption.enforced)
+	compare(data.operator, data.target_value, enforced)
 }
diff --git a/policies/bundles/WebApplicationFirewallEnabled/metric.rego b/policies/bundles/WebApplicationFirewallEnabled/metric.rego
index 22f18972..72d5164a 100644
--- a/policies/bundles/WebApplicationFirewallEnabled/metric.rego
+++ b/policies/bundles/WebApplicationFirewallEnabled/metric.rego
@@ -6,12 +6,12 @@ default applicable = false
 
 default compliant = false
 
-waf := input.webApplicationFirewall
+enabled := input.webApplicationFirewall.enabled
 
 applicable {
-	waf
+	enabled != null
 }
 
 compliant {
-	compare(data.operator, data.target_value, waf.enabled)
+	compare(data.operator, data.target_value, enabled)
 }
diff --git a/policies/policies.go b/policies/policies.go
index 5b1bc8a3..bb083291 100644
--- a/policies/policies.go
+++ b/policies/policies.go
@@ -39,8 +39,10 @@ var (
 	log = logrus.WithField("component", "policies")
 )
 
-type metricsResourceTypeCache struct {
+// metricsCache holds all cached metrics for different combinations of Tools with resource types
+type metricsCache struct {
 	sync.RWMutex
+	// Metrics cached in a map. Key is composed of tool id and resource types concatenation
 	m map[string][]string
 }
 
@@ -66,8 +68,10 @@ type MetricsSource interface {
 	MetricImplementation(lang assessment.MetricImplementation_Language, metric string) (*assessment.MetricImplementation, error)
 }
 
-func createKey(types []string) (key string) {
-	key = strings.Join(types, "-")
+// createKey creates a key by concatenating toolID and all types
+func createKey(toolID string, types []string) (key string) {
+	// Merge toolID and types to one slice and concatenate all its elements
+	key = strings.Join(append(types, toolID), "-")
 	key = strings.ReplaceAll(key, " ", "")
 	return
 }
diff --git a/policies/rego.go b/policies/rego.go
index 7bcfc94e..a308fa99 100644
--- a/policies/rego.go
+++ b/policies/rego.go
@@ -44,8 +44,8 @@ type regoEval struct {
 	// qc contains cached Rego queries
 	qc *queryCache
 
-	// mrtc stores a list of applicable metrics per resourceType
-	mrtc *metricsResourceTypeCache
+	// mrtc stores a list of applicable metrics per toolID and resourceType
+	mrtc *metricsCache
 }
 
 type queryCache struct {
@@ -57,7 +57,7 @@ type orElseFunc func(key string) (query *rego.PreparedEvalQuery, err error)
 
 func NewRegoEval() PolicyEval {
 	return &regoEval{
-		mrtc: &metricsResourceTypeCache{m: make(map[string][]string)},
+		mrtc: &metricsCache{m: make(map[string][]string)},
 		qc:   newQueryCache(),
 	}
 }
@@ -91,7 +91,7 @@ func (re *regoEval) Eval(evidence *evidence.Evidence, src MetricsSource) (data [
 		}
 	}
 
-	key := createKey(types)
+	key := createKey(evidence.ToolId, types)
 
 	re.mrtc.RLock()
 	cached := re.mrtc.m[key]
diff --git a/service/discovery/azure/compute.go b/service/discovery/azure/compute.go
index 826b5623..25b12998 100644
--- a/service/discovery/azure/compute.go
+++ b/service/discovery/azure/compute.go
@@ -172,7 +172,13 @@ func (d *azureComputeDiscovery) handleVirtualMachines(vm *compute.VirtualMachine
 			LoggingService:  []voc.ResourceID{voc.ResourceID(bootLogOutput(vmExtended))},
 			RetentionPeriod: 0, // Currently, configuring the retention period for Managed Boot Diagnostics is not available. The logs will be overwritten after 1gb of space according to https://github.com/MicrosoftDocs/azure-docs/issues/69953
 		}},
-		OSLogging:    &voc.OSLogging{}, // TODO(garuppel): Add OSLogging
+		OSLogging: &voc.OSLogging{
+			Logging: &voc.Logging{
+				Enabled:         false,
+				RetentionPeriod: 0,
+				LoggingService:  []voc.ResourceID{},
+			},
+		}, 
 		BlockStorage: []voc.ResourceID{},
 	}
 
diff --git a/service/discovery/discovery.go b/service/discovery/discovery.go
index 715a3de3..62de972f 100644
--- a/service/discovery/discovery.go
+++ b/service/discovery/discovery.go
@@ -223,7 +223,8 @@ func (s *Service) Start(_ context.Context, _ *discovery.StartDiscoveryRequest) (
 				return nil, status.Errorf(codes.FailedPrecondition, "could not authenticate to Azure: %v", err)
 			}
 			discoverer = append(discoverer,
-				azure.NewAzureARMTemplateDiscovery(azure.WithAuthorizer(authorizer)),
+				// For now, we do not want to discover the ARM template
+				// azure.NewAzureARMTemplateDiscovery(azure.WithAuthorizer(authorizer)),
 				azure.NewAzureStorageDiscovery(azure.WithAuthorizer(authorizer)),
 				azure.NewAzureComputeDiscovery(azure.WithAuthorizer(authorizer)),
 				azure.NewAzureNetworkDiscovery(azure.WithAuthorizer(authorizer)))


Test patch:
diff --git a/policies/rego_test.go b/policies/rego_test.go
index 9c6ba7b1..58b59b69 100644
--- a/policies/rego_test.go
+++ b/policies/rego_test.go
@@ -43,7 +43,7 @@ func Test_regoEval_Eval(t *testing.T) {
 		evidenceID string
 
 		qc      *queryCache
-		mrtc    *metricsResourceTypeCache
+		mrtc    *metricsCache
 		storage persistence.Storage
 	}
 	type args struct {
@@ -79,7 +79,7 @@ func Test_regoEval_Eval(t *testing.T) {
 				},
 				evidenceID: mockObjStorage1EvidenceID,
 				qc:         newQueryCache(),
-				mrtc:       &metricsResourceTypeCache{m: make(map[string][]string)},
+				mrtc:       &metricsCache{m: make(map[string][]string)},
 				storage:    testutil.NewInMemoryStorage(t),
 			},
 			args:       args{src: &mockMetricsSource{t: t}},
@@ -105,7 +105,7 @@ func Test_regoEval_Eval(t *testing.T) {
 				},
 				evidenceID: mockObjStorage2EvidenceID,
 				qc:         newQueryCache(),
-				mrtc:       &metricsResourceTypeCache{m: make(map[string][]string)},
+				mrtc:       &metricsCache{m: make(map[string][]string)},
 				storage:    testutil.NewInMemoryStorage(t),
 			},
 			args:       args{src: &mockMetricsSource{t: t}},
@@ -135,7 +135,7 @@ func Test_regoEval_Eval(t *testing.T) {
 				},
 				evidenceID: mockObjStorage2EvidenceID,
 				qc:         newQueryCache(),
-				mrtc:       &metricsResourceTypeCache{m: make(map[string][]string)},
+				mrtc:       &metricsCache{m: make(map[string][]string)},
 				storage:    testutil.NewInMemoryStorage(t),
 			},
 			args:       args{src: &mockMetricsSource{t: t}},
@@ -182,7 +182,7 @@ func Test_regoEval_Eval(t *testing.T) {
 				},
 				evidenceID: mockVM1EvidenceID,
 				qc:         newQueryCache(),
-				mrtc:       &metricsResourceTypeCache{m: make(map[string][]string)},
+				mrtc:       &metricsCache{m: make(map[string][]string)},
 				storage:    testutil.NewInMemoryStorage(t),
 			},
 			args:       args{src: &mockMetricsSource{t: t}},
@@ -217,7 +217,7 @@ func Test_regoEval_Eval(t *testing.T) {
 				},
 				evidenceID: mockVM2EvidenceID,
 				qc:         newQueryCache(),
-				mrtc:       &metricsResourceTypeCache{m: make(map[string][]string)},
+				mrtc:       &metricsCache{m: make(map[string][]string)},
 				storage:    testutil.NewInMemoryStorage(t),
 			},
 			args:       args{src: &mockMetricsSource{t: t}},
diff --git a/service/assessment/assessment_test.go b/service/assessment/assessment_test.go
index 768fe25a..1fe47096 100644
--- a/service/assessment/assessment_test.go
+++ b/service/assessment/assessment_test.go
@@ -949,7 +949,18 @@ func TestHandleEvidence(t *testing.T) {
 					Id:        "11111111-1111-1111-1111-111111111111",
 					ToolId:    "mock",
 					Timestamp: timestamppb.Now(),
-					Resource:  toStruct(voc.VirtualMachine{Compute: &voc.Compute{Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}}}}, t),
+					Resource: toStruct(voc.VirtualMachine{
+						Compute: &voc.Compute{
+							Resource: &voc.Resource{ID: "my-resource-id", Type: []string{"VirtualMachine"}},
+						},
+						BootLogging: &voc.BootLogging{
+							Logging: &voc.Logging{
+								LoggingService:  nil,
+								Enabled:         true,
+								RetentionPeriod: 0,
+							},
+						},
+					}, t),
 				},
 				resourceId: "my-resource-id",
 			},