Repository: clouditor/clouditor
Pull request #976 (2023-02-21 20:33:23)

Added `latest_by_resource_id` flag to `ListAssessmentResultsRequest`
This flag allows to list the latest assessment result per resource_id, while still allowing to have the usual filters, such as cloud service, etc.

codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> Merging [#976](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (889487e) into [main](https://codecov.io/gh/clouditor/clouditor/commit/f3ac6d86cdbe80d3d822bbce7f904614bfce758d?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (f3ac6d8) will **decrease** coverage by `0.05%`.
> The diff coverage is `70.83%`.

> :exclamation: Current head 889487e differs from pull request most recent head 7fb2216. Consider uploading reports for the commit 7fb2216 to get more accurate results

```diff
@@            Coverage Diff             @@
##             main     #976      +/-   ##
==========================================
- Coverage   81.91%   81.86%   -0.05%     
==========================================
  Files          89       89              
  Lines        7524     7561      +37     
==========================================
+ Hits         6163     6190      +27     
- Misses       1044     1053       +9     
- Partials      317      318       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `81.86% <70.83%> (-0.05%)` | :arrow_down: |

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/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | Coverage Δ | |
|---|---|---|
| [internal/testutil/orchestratortest/orchestrator.go](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-aW50ZXJuYWwvdGVzdHV0aWwvb3JjaGVzdHJhdG9ydGVzdC9vcmNoZXN0cmF0b3IuZ28=) | `100.00% <ø> (ø)` | |
| [internal/testutil/storage.go](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-aW50ZXJuYWwvdGVzdHV0aWwvc3RvcmFnZS5nbw==) | `56.52% <0.00%> (-5.39%)` | :arrow_down: |
| [persistence/gorm/gorm.go](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-cGVyc2lzdGVuY2UvZ29ybS9nb3JtLmdv) | `83.78% <46.66%> (-3.20%)` | :arrow_down: |
| [service/orchestrator/assessment\_results.go](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9vcmNoZXN0cmF0b3IvYXNzZXNzbWVudF9yZXN1bHRzLmdv) | `89.79% <83.33%> (-0.83%)` | :arrow_down: |
| [internal/util/deref.go](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-aW50ZXJuYWwvdXRpbC9kZXJlZi5nbw==) | `100.00% <100.00%> (ø)` | |
| [persistence/inmemory/inmemory.go](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-cGVyc2lzdGVuY2UvaW5tZW1vcnkvaW5tZW1vcnkuZ28=) | `100.00% <100.00%> (ø)` | |
| [service/assessment/assessment.go](https://codecov.io/gh/clouditor/clouditor/pull/976?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9hc3Nlc3NtZW50L2Fzc2Vzc21lbnQuZ28=) | `89.58% <0.00%> (+0.78%)` | :arrow_up: |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)


Patch:
diff --git a/api/assessment/assessment.pb.go b/api/assessment/assessment.pb.go
index 397b7047..b9cfb73f 100644
--- a/api/assessment/assessment.pb.go
+++ b/api/assessment/assessment.pb.go
@@ -115,10 +115,12 @@ type ListAssessmentResultsRequest struct {
 	FilteredCompliant *bool `protobuf:"varint,2,opt,name=filtered_compliant,json=filteredCompliant,proto3,oneof" json:"filtered_compliant,omitempty"`
 	// Optional. List only assessment results of a specific metric id.
 	FilteredMetricId []string `protobuf:"bytes,3,rep,name=filtered_metric_id,json=filteredMetricId,proto3" json:"filtered_metric_id,omitempty"`
-	PageSize         int32    `protobuf:"varint,10,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
-	PageToken        string   `protobuf:"bytes,11,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"`
-	OrderBy          string   `protobuf:"bytes,12,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
-	Asc              bool     `protobuf:"varint,13,opt,name=asc,proto3" json:"asc,omitempty"`
+	// Optional. Latest results grouped results by resource_id.
+	LatestByResourceId *bool  `protobuf:"varint,4,opt,name=latest_by_resource_id,json=latestByResourceId,proto3,oneof" json:"latest_by_resource_id,omitempty"`
+	PageSize           int32  `protobuf:"varint,10,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
+	PageToken          string `protobuf:"bytes,11,opt,name=page_token,json=pageToken,proto3" json:"page_token,omitempty"`
+	OrderBy            string `protobuf:"bytes,12,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
+	Asc                bool   `protobuf:"varint,13,opt,name=asc,proto3" json:"asc,omitempty"`
 }
 
 func (x *ListAssessmentResultsRequest) Reset() {
@@ -174,6 +176,13 @@ func (x *ListAssessmentResultsRequest) GetFilteredMetricId() []string {
 	return nil
 }
 
+func (x *ListAssessmentResultsRequest) GetLatestByResourceId() bool {
+	if x != nil && x.LatestByResourceId != nil {
+		return *x.LatestByResourceId
+	}
+	return false
+}
+
 func (x *ListAssessmentResultsRequest) GetPageSize() int32 {
 	if x != nil {
 		return x.PageSize
@@ -427,7 +436,9 @@ func (x *AssessEvidenceRequest) GetEvidence() *evidence.Evidence {
 	return nil
 }
 
-// AssessEvidenceResponse belongs to AssessEvidence, which uses a custom unary RPC and therefore requires a response message according to the style convention. Since no return values are required, this is empty.
+// AssessEvidenceResponse belongs to AssessEvidence, which uses a custom unary
+// RPC and therefore requires a response message according to the style
+// convention. Since no return values are required, this is empty.
 type AssessEvidenceResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -466,7 +477,10 @@ func (*AssessEvidenceResponse) Descriptor() ([]byte, []int) {
 	return file_api_assessment_assessment_proto_rawDescGZIP(), []int{6}
 }
 
-// AssessEvidencesResponse belongs to AssessEvidences, which uses a custom bidirectional streaming RPC and therefore requires a response message according to the style convention. The bidirectional streaming needs the status and its message in the response for error handling.
+// AssessEvidencesResponse belongs to AssessEvidences, which uses a custom
+// bidirectional streaming RPC and therefore requires a response message
+// according to the style convention. The bidirectional streaming needs the
+// status and its message in the response for error handling.
 type AssessEvidencesResponse struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -671,8 +685,8 @@ var file_api_assessment_assessment_proto_rawDesc = []byte{
 	0x65, 0x6e, 0x74, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
 	0x1a, 0x13, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2f, 0x74, 0x61, 0x67, 0x67, 0x65, 0x72, 0x2e,
 	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f,
-	0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf6,
-	0x02, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
+	0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc8,
+	0x03, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
 	0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
 	0x48, 0x0a, 0x19, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x6f, 0x75,
 	0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
@@ -685,136 +699,141 @@ var file_api_assessment_assessment_proto_rawDesc = []byte{
 	0x12, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
 	0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0c, 0xfa, 0x42, 0x09, 0x92, 0x01,
 	0x06, 0x22, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x10, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65,
-	0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67,
-	0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61,
-	0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74,
-	0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65,
-	0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62,
-	0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79,
-	0x12, 0x10, 0x0a, 0x03, 0x61, 0x73, 0x63, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61,
-	0x73, 0x63, 0x42, 0x1c, 0x0a, 0x1a, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f,
-	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64,
-	0x42, 0x15, 0x0a, 0x13, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f,
-	0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x22, 0x8c, 0x01, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74,
-	0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74,
-	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x07, 0x72, 0x65, 0x73,
-	0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6c, 0x6f,
-	0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
-	0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52,
-	0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x26,
-	0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65,
-	0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67,
-	0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1c, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
-	0x75, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
-	0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x3b, 0x0a, 0x1a, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65,
-	0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x49, 0x64,
-	0x22, 0x5e, 0x0a, 0x15, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e,
-	0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x65, 0x76, 0x69,
-	0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x63, 0x6c,
-	0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65,
-	0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x08, 0xfa, 0x42,
-	0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65,
-	0x22, 0x18, 0x0a, 0x16, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e,
-	0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, 0x02, 0x0a, 0x17, 0x41,
-	0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65,
-	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
-	0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
-	0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73,
-	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
-	0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6d, 0x65, 0x73, 0x73,
-	0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x68, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21, 0x0a, 0x1d,
-	0x41, 0x53, 0x53, 0x45, 0x53, 0x53, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55,
-	0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12,
-	0x17, 0x0a, 0x13, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x4f, 0x52, 0x5f, 0x52,
-	0x45, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x53, 0x53, 0x45,
-	0x53, 0x53, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c, 0x45, 0x44,
-	0x10, 0x03, 0x22, 0xf4, 0x04, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
-	0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69,
-	0x64, 0x12, 0x6e, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
-	0x42, 0x34, 0xfa, 0x42, 0x05, 0xb2, 0x01, 0x02, 0x08, 0x01, 0x9a, 0x84, 0x9e, 0x03, 0x27, 0x67,
-	0x6f, 0x72, 0x6d, 0x3a, 0x22, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x3a,
-	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x70, 0x62, 0x3b, 0x74, 0x79, 0x70, 0x65,
-	0x3a, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x12, 0x24, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x03,
-	0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x6d,
-	0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x64, 0x12, 0x84, 0x01, 0x0a, 0x14, 0x6d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-	0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
-	0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31,
-	0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x42, 0x23, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x9a, 0x84,
-	0x9e, 0x03, 0x16, 0x67, 0x6f, 0x72, 0x6d, 0x3a, 0x22, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69,
-	0x7a, 0x65, 0x72, 0x3a, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x52, 0x13, 0x6d, 0x65, 0x74, 0x72, 0x69,
-	0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c,
-	0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
-	0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x0b,
-	0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28,
-	0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x65, 0x76, 0x69,
-	0x64, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75,
-	0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42,
-	0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49,
-	0x64, 0x12, 0x4a, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x74, 0x79,
-	0x70, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x42, 0x23, 0xfa, 0x42, 0x05, 0x92, 0x01,
-	0x02, 0x08, 0x01, 0x9a, 0x84, 0x9e, 0x03, 0x16, 0x67, 0x6f, 0x72, 0x6d, 0x3a, 0x22, 0x73, 0x65,
-	0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x52, 0x0d,
-	0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12, 0x36, 0x0a,
-	0x17, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x5f,
-	0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15,
-	0x6e, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x43, 0x6f, 0x6d,
-	0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x10, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73,
-	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x42,
-	0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
-	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x32, 0xb6, 0x04, 0x0a, 0x0a, 0x41, 0x73,
-	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x64, 0x0a, 0x13, 0x43, 0x61, 0x6c, 0x63,
-	0x75, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x12,
-	0x33, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c,
-	0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
-	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x9d,
-	0x01, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63,
-	0x65, 0x12, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73,
-	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73,
-	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x08, 0x65, 0x76, 0x69, 0x64,
-	0x65, 0x6e, 0x63, 0x65, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73,
-	0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x79,
-	0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65,
-	0x73, 0x12, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73,
-	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
-	0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73,
-	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
-	0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0xa6, 0x01, 0x0a, 0x15, 0x4c, 0x69,
-	0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75,
-	0x6c, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
-	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69,
+	0x64, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x15, 0x6c, 0x61, 0x74,
+	0x65, 0x73, 0x74, 0x5f, 0x62, 0x79, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x48, 0x02, 0x52, 0x12, 0x6c, 0x61, 0x74, 0x65,
+	0x73, 0x74, 0x42, 0x79, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x88, 0x01,
+	0x01, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a,
+	0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d,
+	0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x19, 0x0a,
+	0x08, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x5f, 0x62, 0x79, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x07, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x42, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x73, 0x63, 0x18,
+	0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, 0x61, 0x73, 0x63, 0x42, 0x1c, 0x0a, 0x1a, 0x5f, 0x66,
+	0x69, 0x6c, 0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x66, 0x69, 0x6c,
+	0x74, 0x65, 0x72, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x42,
+	0x18, 0x0a, 0x16, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x62, 0x79, 0x5f, 0x72, 0x65,
+	0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x1d, 0x4c, 0x69,
 	0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75,
-	0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63, 0x6c, 0x6f,
-	0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
-	0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
-	0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x76, 0x31, 0x2f,
-	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, 0x73, 0x75, 0x6c,
-	0x74, 0x73, 0x42, 0x27, 0x5a, 0x25, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
-	0x69, 0x6f, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x70, 0x69,
-	0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x33,
+	0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x07, 0x72,
+	0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63,
+	0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
+	0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
+	0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73,
+	0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f,
+	0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50,
+	0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x1c, 0x0a, 0x1a, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x75, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x1d, 0x0a, 0x1b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+	0x75, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x0a, 0x1a, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61,
+	0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x5f, 0x69,
+	0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
+	0x49, 0x64, 0x22, 0x5e, 0x0a, 0x15, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64,
+	0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x08, 0x65,
+	0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
+	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e,
+	0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x42, 0x08,
+	0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e,
+	0x63, 0x65, 0x22, 0x18, 0x0a, 0x16, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64,
+	0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x85, 0x02, 0x0a,
+	0x17, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73,
+	0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x41, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
+	0x76, 0x31, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63,
+	0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73,
+	0x73, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x5f, 0x6d, 0x65,
+	0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x74, 0x61,
+	0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x68, 0x0a, 0x10, 0x41, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x21,
+	0x0a, 0x1d, 0x41, 0x53, 0x53, 0x45, 0x53, 0x53, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x53, 0x54, 0x41,
+	0x54, 0x55, 0x53, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+	0x00, 0x12, 0x17, 0x0a, 0x13, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x46, 0x4f, 0x52,
+	0x5f, 0x52, 0x45, 0x4c, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x41, 0x53,
+	0x53, 0x45, 0x53, 0x53, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x46, 0x41, 0x49, 0x4c,
+	0x45, 0x44, 0x10, 0x03, 0x22, 0xf4, 0x04, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
+	0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52,
+	0x02, 0x69, 0x64, 0x12, 0x6e, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
+	0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x42, 0x34, 0xfa, 0x42, 0x05, 0xb2, 0x01, 0x02, 0x08, 0x01, 0x9a, 0x84, 0x9e, 0x03,
+	0x27, 0x67, 0x6f, 0x72, 0x6d, 0x3a, 0x22, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65,
+	0x72, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x70, 0x62, 0x3b, 0x74, 0x79,
+	0x70, 0x65, 0x3a, 0x74, 0x69, 0x6d, 0x65, 0x22, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52,
+	0x08, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x64, 0x12, 0x84, 0x01, 0x0a, 0x14, 0x6d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+	0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e,
+	0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75,
+	0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x23, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01,
+	0x9a, 0x84, 0x9e, 0x03, 0x16, 0x67, 0x6f, 0x72, 0x6d, 0x3a, 0x22, 0x73, 0x65, 0x72, 0x69, 0x61,
+	0x6c, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x52, 0x13, 0x6d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+	0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x18, 0x05, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x29,
+	0x0a, 0x0b, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0a, 0x65,
+	0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x28, 0x0a, 0x0b, 0x72, 0x65, 0x73,
+	0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07,
+	0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
+	0x65, 0x49, 0x64, 0x12, 0x4a, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f,
+	0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x42, 0x23, 0xfa, 0x42, 0x05,
+	0x92, 0x01, 0x02, 0x08, 0x01, 0x9a, 0x84, 0x9e, 0x03, 0x16, 0x67, 0x6f, 0x72, 0x6d, 0x3a, 0x22,
+	0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x72, 0x3a, 0x6a, 0x73, 0x6f, 0x6e, 0x22,
+	0x52, 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x73, 0x12,
+	0x36, 0x0a, 0x17, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63,
+	0x65, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x15, 0x6e, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x43,
+	0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x10, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28,
+	0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0e, 0x63, 0x6c, 0x6f,
+	0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x32, 0xb6, 0x04, 0x0a, 0x0a,
+	0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x64, 0x0a, 0x13, 0x43, 0x61,
+	0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63,
+	0x65, 0x12, 0x33, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x63,
+	0x75, 0x6c, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00,
+	0x12, 0x9d, 0x01, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65,
+	0x6e, 0x63, 0x65, 0x12, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
+	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
+	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x3a, 0x08, 0x65, 0x76,
+	0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x73, 0x73, 0x65,
+	0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73,
+	0x12, 0x79, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e,
+	0x63, 0x65, 0x73, 0x12, 0x2e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
+	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75,
+	0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
+	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0xa6, 0x01, 0x0a, 0x15,
+	0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x35, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f,
+	0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e,
+	0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x36, 0x2e, 0x63,
+	0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
+	0x65, 0x6e, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73,
+	0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x76,
+	0x31, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, 0x73,
+	0x75, 0x6c, 0x74, 0x73, 0x42, 0x27, 0x5a, 0x25, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f,
+	0x72, 0x2e, 0x69, 0x6f, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2f, 0x61,
+	0x70, 0x69, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
diff --git a/api/assessment/assessment.pb.validate.go b/api/assessment/assessment.pb.validate.go
index 5c2b87bc..a9fbb738 100644
--- a/api/assessment/assessment.pb.validate.go
+++ b/api/assessment/assessment.pb.validate.go
@@ -104,6 +104,10 @@ func (m *ListAssessmentResultsRequest) validate(all bool) error {
 		// no validation rules for FilteredCompliant
 	}
 
+	if m.LatestByResourceId != nil {
+		// no validation rules for LatestByResourceId
+	}
+
 	if len(errors) > 0 {
 		return ListAssessmentResultsRequestMultiError(errors)
 	}
diff --git a/api/assessment/assessment.proto b/api/assessment/assessment.proto
index 65cdddd2..2d89fb7d 100644
--- a/api/assessment/assessment.proto
+++ b/api/assessment/assessment.proto
@@ -84,6 +84,9 @@ message ListAssessmentResultsRequest {
   repeated string filtered_metric_id = 3
       [ (validate.rules).repeated .items.string.min_len = 1 ];
 
+  // Optional. Latest results grouped by resource_id.
+  optional bool latest_by_resource_id = 4;
+
   int32 page_size = 10;
   string page_token = 11;
   string order_by = 12;
@@ -104,10 +107,15 @@ message AssessEvidenceRequest {
       [ (validate.rules).message.required = true ];
 }
 
-// AssessEvidenceResponse belongs to AssessEvidence, which uses a custom unary RPC and therefore requires a response message according to the style convention. Since no return values are required, this is empty.
+// AssessEvidenceResponse belongs to AssessEvidence, which uses a custom unary
+// RPC and therefore requires a response message according to the style
+// convention. Since no return values are required, this is empty.
 message AssessEvidenceResponse {}
 
-// AssessEvidencesResponse belongs to AssessEvidences, which uses a custom bidirectional streaming RPC and therefore requires a response message according to the style convention. The bidirectional streaming needs the status and its message in the response for error handling. 
+// AssessEvidencesResponse belongs to AssessEvidences, which uses a custom
+// bidirectional streaming RPC and therefore requires a response message
+// according to the style convention. The bidirectional streaming needs the
+// status and its message in the response for error handling.
 message AssessEvidencesResponse {
   enum AssessmentStatus {
     ASSESSMENT_STATUS_UNSPECIFIED = 0;
diff --git a/openapi/assessment/openapi.yaml b/openapi/assessment/openapi.yaml
index ad027b81..e9dc5025 100644
--- a/openapi/assessment/openapi.yaml
+++ b/openapi/assessment/openapi.yaml
@@ -65,6 +65,11 @@ paths:
                     type: array
                     items:
                         type: string
+                - name: latestByResourceId
+                  in: query
+                  description: Optional. Latest results grouped results by resource_id.
+                  schema:
+                    type: boolean
                 - name: pageSize
                   in: query
                   schema:
diff --git a/openapi/orchestrator/openapi.yaml b/openapi/orchestrator/openapi.yaml
index 94aa5115..e941d0d9 100644
--- a/openapi/orchestrator/openapi.yaml
+++ b/openapi/orchestrator/openapi.yaml
@@ -31,6 +31,11 @@ paths:
                     type: array
                     items:
                         type: string
+                - name: latestByResourceId
+                  in: query
+                  description: Optional. Latest results grouped results by resource_id.
+                  schema:
+                    type: boolean
                 - name: pageSize
                   in: query
                   schema:
diff --git a/persistence/gorm/gorm.go b/persistence/gorm/gorm.go
index 79317895..88fbe6f0 100644
--- a/persistence/gorm/gorm.go
+++ b/persistence/gorm/gorm.go
@@ -264,6 +264,7 @@ func (s *storage) List(r any, orderBy string, asc bool, offset int, limit int, c
 	if limit != -1 {
 		query = s.db.Limit(limit)
 	}
+
 	// Set direction to "descending"
 	if !asc {
 		orderDirection = "desc"
@@ -280,6 +281,10 @@ func (s *storage) List(r any, orderBy string, asc bool, offset int, limit int, c
 	return query.Order(orderStmt).Find(r, conds...).Error
 }
 
+func (s *storage) Raw(r any, query string, args ...any) error {
+	return s.db.Raw(query, args...).Scan(r).Error
+}
+
 func (s *storage) Count(r any, conds ...any) (count int64, err error) {
 	db := applyWhere(s.db.Model(r), conds...)
 
diff --git a/persistence/persistence.go b/persistence/persistence.go
index 0a681691..d6fa5a22 100644
--- a/persistence/persistence.go
+++ b/persistence/persistence.go
@@ -65,4 +65,7 @@ type Storage interface {
 
 	// Delete deletes the record with given id of the DB
 	Delete(r any, conds ...any) error
+
+	// Raw executes a raw SQL statement and stores the result in r
+	Raw(r any, query string, args ...any) error
 }
diff --git a/service/orchestrator/assessment_results.go b/service/orchestrator/assessment_results.go
index 3e8be114..61a8e198 100644
--- a/service/orchestrator/assessment_results.go
+++ b/service/orchestrator/assessment_results.go
@@ -64,6 +64,8 @@ func (svc *Service) ListAssessmentResults(ctx context.Context, req *assessment.L
 		return nil, service.ErrPermissionDenied
 	}
 
+	res = new(assessment.ListAssessmentResultsResponse)
+
 	var query []string
 	var args []any
 
@@ -91,15 +93,35 @@ func (svc *Service) ListAssessmentResults(ctx context.Context, req *assessment.L
 		args = append(args, allowed)
 	}
 
-	// join query with AND and prepend the query
-	args = append([]any{strings.Join(query, " AND ")}, args...)
+	// If we want to have it grouped by resource ID, we need to do a raw query
+	if req.GetLatestByResourceId() {
+		// In the raw SQL, we need to build the whole WHERE statement
+		var where string
 
-	res = new(assessment.ListAssessmentResultsResponse)
+		if len(query) > 0 {
+			where = "WHERE " + strings.Join(query, " AND ")
+		}
 
-	// Paginate the results according to the request
-	res.Results, res.NextPageToken, err = service.PaginateStorage[*assessment.AssessmentResult](req, svc.storage, service.DefaultPaginationOpts, args...)
-	if err != nil {
-		return nil, status.Errorf(codes.Internal, "could not paginate results: %v", err)
+		// Execute the raw SQL statement
+		err = svc.storage.Raw(&res.Results,
+			fmt.Sprintf(`WITH sorted_results AS (
+				SELECT *, ROW_NUMBER() OVER (PARTITION BY resource_id ORDER BY timestamp DESC) AS row_number
+				FROM assessment_results
+				%s
+		  	)
+		  	SELECT * FROM sorted_results WHERE row_number = 1;`, where), args...)
+		if err != nil {
+			return nil, status.Errorf(codes.Internal, "database error: %v", err)
+		}
+	} else {
+		// Join query with AND and prepend the query
+		args = append([]any{strings.Join(query, " AND ")}, args...)
+
+		// Paginate the results according to the request
+		res.Results, res.NextPageToken, err = service.PaginateStorage[*assessment.AssessmentResult](req, svc.storage, service.DefaultPaginationOpts, args...)
+		if err != nil {
+			return nil, status.Errorf(codes.Internal, "could not paginate results: %v", err)
+		}
 	}
 
 	return


Test patch:
diff --git a/internal/testdata/testdata.go b/internal/testdata/testdata.go
index 8aff2188..2accc55c 100644
--- a/internal/testdata/testdata.go
+++ b/internal/testdata/testdata.go
@@ -63,6 +63,7 @@ const (
 	MockResourceName        = "my-resource-name"
 	MockResourceStorageID   = voc.ResourceID("some-storage-service-id")
 	MockResourceStorageName = "some-storage-service-name"
+	MockAnotherResourceID   = "my-other-resource"
 
 	// Certificate
 	MockCertificateID          = "1234"
diff --git a/internal/testutil/orchestratortest/orchestrator.go b/internal/testutil/orchestratortest/orchestrator.go
index bd142744..fe742bc6 100644
--- a/internal/testutil/orchestratortest/orchestrator.go
+++ b/internal/testutil/orchestratortest/orchestrator.go
@@ -190,7 +190,7 @@ var (
 		MetricId:       testdata.MockAnotherMetricID,
 		Compliant:      false,
 		EvidenceId:     testdata.MockEvidenceID,
-		ResourceId:     testdata.MockResourceID,
+		ResourceId:     testdata.MockAnotherResourceID,
 		ResourceTypes:  []string{"Resource"},
 		MetricConfiguration: &assessment.MetricConfiguration{
 			Operator:       "==",
diff --git a/internal/testutil/storage.go b/internal/testutil/storage.go
index 130b2b73..92662bed 100644
--- a/internal/testutil/storage.go
+++ b/internal/testutil/storage.go
@@ -31,6 +31,7 @@ type StorageWithError struct {
 	UpdateErr error
 	GetErr    error
 	ListErr   error
+	RawErr    error
 	CountErr  error
 	DeleteErr error
 }
@@ -44,6 +45,9 @@ func (s *StorageWithError) Get(_ any, _ ...any) error { return s.GetErr }
 func (s *StorageWithError) List(_ any, _ string, _ bool, _ int, _ int, _ ...any) error {
 	return s.ListErr
 }
+func (s *StorageWithError) Raw(_ any, _ string, _ ...any) error {
+	return s.RawErr
+}
 func (s *StorageWithError) Count(_ any, _ ...any) (int64, error) {
 	return 0, s.CountErr
 }
diff --git a/service/orchestrator/assessment_results_test.go b/service/orchestrator/assessment_results_test.go
index 0f9877bd..47cbe812 100644
--- a/service/orchestrator/assessment_results_test.go
+++ b/service/orchestrator/assessment_results_test.go
@@ -348,6 +348,48 @@ func TestService_ListAssessmentResults(t *testing.T) {
 				return assert.ErrorContains(t, err, "FilteredCloudServiceId: value must be a valid UUID")
 			},
 		},
+		{
+			name: "grouped by resource ID",
+			fields: fields{
+				storage: testutil.NewInMemoryStorage(t, func(s persistence.Storage) {
+					assert.NoError(t, s.Create(orchestratortest.MockAssessmentResults))
+				}),
+				authz: &service.AuthorizationStrategyAllowAll{},
+			},
+			args: args{
+				req: &assessment.ListAssessmentResultsRequest{
+					LatestByResourceId: util.Ref(true),
+				},
+			},
+			wantRes: &assessment.ListAssessmentResultsResponse{
+				Results: []*assessment.AssessmentResult{
+					orchestratortest.MockAssessmentResult4,
+					orchestratortest.MockAssessmentResult1,
+				},
+			},
+			wantErr: assert.NoError,
+		},
+		{
+			name: "grouped by resource ID with filter",
+			fields: fields{
+				storage: testutil.NewInMemoryStorage(t, func(s persistence.Storage) {
+					assert.NoError(t, s.Create(orchestratortest.MockAssessmentResults))
+				}),
+				authz: &service.AuthorizationStrategyAllowAll{},
+			},
+			args: args{
+				req: &assessment.ListAssessmentResultsRequest{
+					LatestByResourceId:     util.Ref(true),
+					FilteredCloudServiceId: util.Ref(testdata.MockCloudServiceID),
+				},
+			},
+			wantRes: &assessment.ListAssessmentResultsResponse{
+				Results: []*assessment.AssessmentResult{
+					orchestratortest.MockAssessmentResult1,
+				},
+			},
+			wantErr: assert.NoError,
+		},
 	}
 
 	for _, tt := range tests {