Repository: clouditor/clouditor
Pull request #399 (2021-12-02 18:55:27)

Added API for managing certification target cloud services
Added API for managing certification target cloud services:

- [x] Registration of new services
- [x] Listing all services
- [x] Retrieve a specific service
- [x] Update a specific service
- [x] Remove a service
- [x] Updating target cloud service metric configuration
- [x] Database persistance 
- [x] Added adequate tests

Closes https://github.com/clouditor/clouditor/issues/387

This PR *intentionally* does *not* combine the metric configurations with the assessment yet, as we need to untangle certain things in the Rego evaluation first.

codecov[bot]: # [Codecov](https://codecov.io/gh/clouditor/clouditor/pull/399?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) Report
> Merging [#399](https://codecov.io/gh/clouditor/clouditor/pull/399?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (18badf9) into [main](https://codecov.io/gh/clouditor/clouditor/commit/ee5e6a79dcb5e4eea14cb2ff303b9cf290519248?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) (ee5e6a7) will **decrease** coverage by `1.95%`.
> The diff coverage is `0.00%`.

[![Impacted file tree graph](https://codecov.io/gh/clouditor/clouditor/pull/399/graphs/tree.svg?width=650&height=150&src=pr&token=syrXsw5LTX&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)](https://codecov.io/gh/clouditor/clouditor/pull/399?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor)

```diff
@@            Coverage Diff             @@
##             main     #399      +/-   ##
==========================================
- Coverage   65.22%   63.26%   -1.96%     
==========================================
  Files          36       38       +2     
  Lines        2979     3071      +92     
==========================================
  Hits         1943     1943              
- Misses        924     1016      +92     
  Partials      112      112              
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `63.26% <0.00%> (-1.96%)` | :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/399?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor) | Coverage Δ | |
|---|---|---|
| [cli/commands/cloud/cloud.go](https://codecov.io/gh/clouditor/clouditor/pull/399/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-Y2xpL2NvbW1hbmRzL2Nsb3VkL2Nsb3VkLmdv) | `0.00% <0.00%> (ø)` | |
| [cli/commands/commands.go](https://codecov.io/gh/clouditor/clouditor/pull/399/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-Y2xpL2NvbW1hbmRzL2NvbW1hbmRzLmdv) | `0.00% <0.00%> (ø)` | |
| [service/orchestrator/cloud\_service.go](https://codecov.io/gh/clouditor/clouditor/pull/399/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor#diff-c2VydmljZS9vcmNoZXN0cmF0b3IvY2xvdWRfc2VydmljZS5nbw==) | `0.00% <0.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/clouditor/clouditor/pull/399?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/399?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=clouditor). Last update [ee5e6a7...18badf9](https://codecov.io/gh/clouditor/clouditor/pull/399?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).


Patch:
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..7bcb224e
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,6 @@
+{
+    "recommendations": [
+        "streetsidesoftware.code-spell-checker",
+        "golang.go"
+    ]
+}
\ No newline at end of file
diff --git a/api/assessment/assessment.pb.go b/api/assessment/assessment.pb.go
index 14c86ae7..d976232f 100644
--- a/api/assessment/assessment.pb.go
+++ b/api/assessment/assessment.pb.go
@@ -38,7 +38,6 @@ import (
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 	emptypb "google.golang.org/protobuf/types/known/emptypb"
-	structpb "google.golang.org/protobuf/types/known/structpb"
 	timestamppb "google.golang.org/protobuf/types/known/timestamppb"
 	reflect "reflect"
 	sync "sync"
@@ -291,7 +290,7 @@ type Result struct {
 	// Reference to the metric the assessment was based on
 	MetricId string `protobuf:"bytes,3,opt,name=metric_id,json=metricId,proto3" json:"metric_id,omitempty"`
 	// Data corresponding to the metric by the given metric id
-	MetricData *MetricData `protobuf:"bytes,4,opt,name=metric_data,json=metricData,proto3" json:"metric_data,omitempty"`
+	MetricData *MetricConfiguration `protobuf:"bytes,4,opt,name=metric_data,json=metricData,proto3" json:"metric_data,omitempty"`
 	// Compliant case: true or false
 	Compliant bool `protobuf:"varint,5,opt,name=compliant,proto3" json:"compliant,omitempty"`
 	// Reference to the assessed evidence
@@ -355,7 +354,7 @@ func (x *Result) GetMetricId() string {
 	return ""
 }
 
-func (x *Result) GetMetricData() *MetricData {
+func (x *Result) GetMetricData() *MetricConfiguration {
 	if x != nil {
 		return x.MetricData
 	}
@@ -390,61 +389,6 @@ func (x *Result) GetNonComplianceComments() string {
 	return ""
 }
 
-type MetricData struct {
-	state         protoimpl.MessageState
-	sizeCache     protoimpl.SizeCache
-	unknownFields protoimpl.UnknownFields
-
-	TargetValue *structpb.Value `protobuf:"bytes,1,opt,name=target_value,json=targetValue,proto3" json:"target_value,omitempty"` // target value, e.g. string, number, array, ...
-	Operator    string          `protobuf:"bytes,2,opt,name=operator,proto3" json:"operator,omitempty"`                          // the operator, e.g. "=="
-}
-
-func (x *MetricData) Reset() {
-	*x = MetricData{}
-	if protoimpl.UnsafeEnabled {
-		mi := &file_assessment_proto_msgTypes[6]
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		ms.StoreMessageInfo(mi)
-	}
-}
-
-func (x *MetricData) String() string {
-	return protoimpl.X.MessageStringOf(x)
-}
-
-func (*MetricData) ProtoMessage() {}
-
-func (x *MetricData) ProtoReflect() protoreflect.Message {
-	mi := &file_assessment_proto_msgTypes[6]
-	if protoimpl.UnsafeEnabled && x != nil {
-		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
-		if ms.LoadMessageInfo() == nil {
-			ms.StoreMessageInfo(mi)
-		}
-		return ms
-	}
-	return mi.MessageOf(x)
-}
-
-// Deprecated: Use MetricData.ProtoReflect.Descriptor instead.
-func (*MetricData) Descriptor() ([]byte, []int) {
-	return file_assessment_proto_rawDescGZIP(), []int{6}
-}
-
-func (x *MetricData) GetTargetValue() *structpb.Value {
-	if x != nil {
-		return x.TargetValue
-	}
-	return nil
-}
-
-func (x *MetricData) GetOperator() string {
-	if x != nil {
-		return x.Operator
-	}
-	return ""
-}
-
 var File_assessment_proto protoreflect.FileDescriptor
 
 var file_assessment_proto_rawDesc = []byte{
@@ -453,12 +397,11 @@ var file_assessment_proto_rawDesc = []byte{
 	0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
 	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f,
 	0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70,
-	0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
-	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74,
-	0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0e, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63,
-	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3a, 0x0a, 0x18, 0x54, 0x72, 0x69, 0x67, 0x67,
+	0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
+	0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0e, 0x65, 0x76, 0x69, 0x64, 0x65,
+	0x6e, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x0c, 0x6d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3a, 0x0a, 0x18, 0x54, 0x72, 0x69, 0x67, 0x67,
 	0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75,
 	0x65, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f,
 	0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x70, 0x74,
@@ -476,7 +419,7 @@ var file_assessment_proto_rawDesc = []byte{
 	0x65, 0x52, 0x08, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x30, 0x0a, 0x16, 0x41,
 	0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73,
 	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
-	0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xbf, 0x02,
+	0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xc8, 0x02,
 	0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
 	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
 	0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
@@ -484,54 +427,49 @@ var file_assessment_proto_rawDesc = []byte{
 	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
 	0x6d, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x18,
 	0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x64, 0x12,
-	0x36, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04,
-	0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
-	0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 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, 0x1f, 0x0a, 0x0b, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63,
-	0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x76, 0x69, 0x64,
-	0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
-	0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73,
-	0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 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, 0x08, 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, 0x22,
-	0x63, 0x0a, 0x0a, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a,
-	0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
-	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x72,
-	0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72,
-	0x61, 0x74, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72,
-	0x61, 0x74, 0x6f, 0x72, 0x32, 0xae, 0x03, 0x0a, 0x0a, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
-	0x65, 0x6e, 0x74, 0x12, 0x52, 0x0a, 0x11, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x73,
-	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
-	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x41, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 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, 0x8d, 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, 0x27, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 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, 0x28, 0x2e, 0x63, 0x6c, 0x6f,
-	0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 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, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x22, 0x16, 0x2f, 0x76,
-	0x31, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x72, 0x65, 0x73,
-	0x75, 0x6c, 0x74, 0x73, 0x62, 0x01, 0x2a, 0x12, 0x7a, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x73,
-	0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x2e, 0x63, 0x6c, 0x6f, 0x75,
-	0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64,
-	0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x63, 0x6c,
-	0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76,
-	0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23,
-	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 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,
-	0x62, 0x01, 0x2a, 0x12, 0x40, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69,
-	0x64, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
-	0x6f, 0x72, 0x2e, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f,
-	0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d,
-	0x70, 0x74, 0x79, 0x28, 0x01, 0x42, 0x10, 0x5a, 0x0e, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x73, 0x73,
-	0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x3f, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
+	0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x44, 0x61, 0x74, 0x61,
+	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, 0x1f,
+	0x0a, 0x0b, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20,
+	0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12,
+	0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x07,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64,
+	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, 0x08, 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, 0x32, 0xae, 0x03, 0x0a, 0x0a, 0x41, 0x73, 0x73,
+	0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x52, 0x0a, 0x11, 0x54, 0x72, 0x69, 0x67, 0x67,
+	0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x23, 0x2e, 0x63,
+	0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72,
+	0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 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, 0x8d, 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, 0x27, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f,
+	0x72, 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, 0x28,
+	0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 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, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b,
+	0x22, 0x16, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74,
+	0x2f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x62, 0x01, 0x2a, 0x12, 0x7a, 0x0a, 0x0e, 0x41,
+	0x73, 0x73, 0x65, 0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x20, 0x2e,
+	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73,
+	0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x21, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65,
+	0x73, 0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+	0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 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, 0x62, 0x01, 0x2a, 0x12, 0x40, 0x0a, 0x0f, 0x41, 0x73, 0x73, 0x65, 0x73,
+	0x73, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x13, 0x2e, 0x63, 0x6c, 0x6f,
+	0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x45, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x1a,
+	0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x42, 0x10, 0x5a, 0x0e, 0x61, 0x70, 0x69,
+	0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x33,
 }
 
 var (
@@ -546,7 +484,7 @@ func file_assessment_proto_rawDescGZIP() []byte {
 	return file_assessment_proto_rawDescData
 }
 
-var file_assessment_proto_msgTypes = make([]protoimpl.MessageInfo, 7)
+var file_assessment_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
 var file_assessment_proto_goTypes = []interface{}{
 	(*TriggerAssessmentRequest)(nil),      // 0: clouditor.TriggerAssessmentRequest
 	(*ListAssessmentResultsRequest)(nil),  // 1: clouditor.ListAssessmentResultsRequest
@@ -554,31 +492,29 @@ var file_assessment_proto_goTypes = []interface{}{
 	(*AssessEvidenceRequest)(nil),         // 3: clouditor.AssessEvidenceRequest
 	(*AssessEvidenceResponse)(nil),        // 4: clouditor.AssessEvidenceResponse
 	(*Result)(nil),                        // 5: clouditor.Result
-	(*MetricData)(nil),                    // 6: clouditor.MetricData
-	(*evidence.Evidence)(nil),             // 7: clouditor.Evidence
-	(*timestamppb.Timestamp)(nil),         // 8: google.protobuf.Timestamp
-	(*structpb.Value)(nil),                // 9: google.protobuf.Value
-	(*emptypb.Empty)(nil),                 // 10: google.protobuf.Empty
+	(*evidence.Evidence)(nil),             // 6: clouditor.Evidence
+	(*timestamppb.Timestamp)(nil),         // 7: google.protobuf.Timestamp
+	(*MetricConfiguration)(nil),           // 8: clouditor.MetricConfiguration
+	(*emptypb.Empty)(nil),                 // 9: google.protobuf.Empty
 }
 var file_assessment_proto_depIdxs = []int32{
-	5,  // 0: clouditor.ListAssessmentResultsResponse.results:type_name -> clouditor.Result
-	7,  // 1: clouditor.AssessEvidenceRequest.evidence:type_name -> clouditor.Evidence
-	8,  // 2: clouditor.Result.timestamp:type_name -> google.protobuf.Timestamp
-	6,  // 3: clouditor.Result.metric_data:type_name -> clouditor.MetricData
-	9,  // 4: clouditor.MetricData.target_value:type_name -> google.protobuf.Value
-	0,  // 5: clouditor.Assessment.TriggerAssessment:input_type -> clouditor.TriggerAssessmentRequest
-	1,  // 6: clouditor.Assessment.ListAssessmentResults:input_type -> clouditor.ListAssessmentResultsRequest
-	3,  // 7: clouditor.Assessment.AssessEvidence:input_type -> clouditor.AssessEvidenceRequest
-	7,  // 8: clouditor.Assessment.AssessEvidences:input_type -> clouditor.Evidence
-	10, // 9: clouditor.Assessment.TriggerAssessment:output_type -> google.protobuf.Empty
-	2,  // 10: clouditor.Assessment.ListAssessmentResults:output_type -> clouditor.ListAssessmentResultsResponse
-	4,  // 11: clouditor.Assessment.AssessEvidence:output_type -> clouditor.AssessEvidenceResponse
-	10, // 12: clouditor.Assessment.AssessEvidences:output_type -> google.protobuf.Empty
-	9,  // [9:13] is the sub-list for method output_type
-	5,  // [5:9] is the sub-list for method input_type
-	5,  // [5:5] is the sub-list for extension type_name
-	5,  // [5:5] is the sub-list for extension extendee
-	0,  // [0:5] is the sub-list for field type_name
+	5, // 0: clouditor.ListAssessmentResultsResponse.results:type_name -> clouditor.Result
+	6, // 1: clouditor.AssessEvidenceRequest.evidence:type_name -> clouditor.Evidence
+	7, // 2: clouditor.Result.timestamp:type_name -> google.protobuf.Timestamp
+	8, // 3: clouditor.Result.metric_data:type_name -> clouditor.MetricConfiguration
+	0, // 4: clouditor.Assessment.TriggerAssessment:input_type -> clouditor.TriggerAssessmentRequest
+	1, // 5: clouditor.Assessment.ListAssessmentResults:input_type -> clouditor.ListAssessmentResultsRequest
+	3, // 6: clouditor.Assessment.AssessEvidence:input_type -> clouditor.AssessEvidenceRequest
+	6, // 7: clouditor.Assessment.AssessEvidences:input_type -> clouditor.Evidence
+	9, // 8: clouditor.Assessment.TriggerAssessment:output_type -> google.protobuf.Empty
+	2, // 9: clouditor.Assessment.ListAssessmentResults:output_type -> clouditor.ListAssessmentResultsResponse
+	4, // 10: clouditor.Assessment.AssessEvidence:output_type -> clouditor.AssessEvidenceResponse
+	9, // 11: clouditor.Assessment.AssessEvidences:output_type -> google.protobuf.Empty
+	8, // [8:12] is the sub-list for method output_type
+	4, // [4:8] is the sub-list for method input_type
+	4, // [4:4] is the sub-list for extension type_name
+	4, // [4:4] is the sub-list for extension extendee
+	0, // [0:4] is the sub-list for field type_name
 }
 
 func init() { file_assessment_proto_init() }
@@ -586,6 +522,7 @@ func file_assessment_proto_init() {
 	if File_assessment_proto != nil {
 		return
 	}
+	file_metric_proto_init()
 	if !protoimpl.UnsafeEnabled {
 		file_assessment_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*TriggerAssessmentRequest); i {
@@ -659,18 +596,6 @@ func file_assessment_proto_init() {
 				return nil
 			}
 		}
-		file_assessment_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*MetricData); i {
-			case 0:
-				return &v.state
-			case 1:
-				return &v.sizeCache
-			case 2:
-				return &v.unknownFields
-			default:
-				return nil
-			}
-		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -678,7 +603,7 @@ func file_assessment_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_assessment_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   7,
+			NumMessages:   6,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/api/assessment/metric.pb.go b/api/assessment/metric.pb.go
index 46b665b8..67d1c314 100644
--- a/api/assessment/metric.pb.go
+++ b/api/assessment/metric.pb.go
@@ -449,6 +449,73 @@ func (x *Order) GetValues() []*structpb.Value {
 	return nil
 }
 
+// Defines the operator and a target value for an individual metric
+type MetricConfiguration struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The operator to compare the metric, such as == or >
+	Operator string `protobuf:"bytes,1,opt,name=operator,proto3" json:"operator,omitempty"`
+	// The target value
+	TargetValue *structpb.Value `protobuf:"bytes,2,opt,name=target_value,json=targetValue,proto3" json:"target_value,omitempty"`
+	// Whether this configuration is a default configuration
+	IsDefault bool `protobuf:"varint,3,opt,name=is_default,json=isDefault,proto3" json:"is_default,omitempty"`
+}
+
+func (x *MetricConfiguration) Reset() {
+	*x = MetricConfiguration{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_metric_proto_msgTypes[5]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *MetricConfiguration) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*MetricConfiguration) ProtoMessage() {}
+
+func (x *MetricConfiguration) ProtoReflect() protoreflect.Message {
+	mi := &file_metric_proto_msgTypes[5]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use MetricConfiguration.ProtoReflect.Descriptor instead.
+func (*MetricConfiguration) Descriptor() ([]byte, []int) {
+	return file_metric_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *MetricConfiguration) GetOperator() string {
+	if x != nil {
+		return x.Operator
+	}
+	return ""
+}
+
+func (x *MetricConfiguration) GetTargetValue() *structpb.Value {
+	if x != nil {
+		return x.TargetValue
+	}
+	return nil
+}
+
+func (x *MetricConfiguration) GetIsDefault() bool {
+	if x != nil {
+		return x.IsDefault
+	}
+	return false
+}
+
 var File_metric_proto protoreflect.FileDescriptor
 
 var file_metric_proto_rawDesc = []byte{
@@ -492,8 +559,17 @@ var file_metric_proto_rawDesc = []byte{
 	0x12, 0x2e, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
 	0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
 	0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73,
-	0x42, 0x10, 0x5a, 0x0e, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65,
-	0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x22, 0x8b, 0x01, 0x0a, 0x13, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x6f, 0x70, 0x65, 0x72,
+	0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6f, 0x70, 0x65, 0x72,
+	0x61, 0x74, 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x0c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76,
+	0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x56, 0x61, 0x6c,
+	0x75, 0x65, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+	0x1d, 0x0a, 0x0a, 0x69, 0x73, 0x5f, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20,
+	0x01, 0x28, 0x08, 0x52, 0x09, 0x69, 0x73, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x42, 0x10,
+	0x5a, 0x0e, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74,
+	0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -509,15 +585,16 @@ func file_metric_proto_rawDescGZIP() []byte {
 }
 
 var file_metric_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_metric_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
+var file_metric_proto_msgTypes = make([]protoimpl.MessageInfo, 6)
 var file_metric_proto_goTypes = []interface{}{
-	(Metric_Scale)(0),      // 0: clouditor.Metric.Scale
-	(*Metric)(nil),         // 1: clouditor.Metric
-	(*Range)(nil),          // 2: clouditor.Range
-	(*MinMax)(nil),         // 3: clouditor.MinMax
-	(*AllowedValues)(nil),  // 4: clouditor.AllowedValues
-	(*Order)(nil),          // 5: clouditor.Order
-	(*structpb.Value)(nil), // 6: google.protobuf.Value
+	(Metric_Scale)(0),           // 0: clouditor.Metric.Scale
+	(*Metric)(nil),              // 1: clouditor.Metric
+	(*Range)(nil),               // 2: clouditor.Range
+	(*MinMax)(nil),              // 3: clouditor.MinMax
+	(*AllowedValues)(nil),       // 4: clouditor.AllowedValues
+	(*Order)(nil),               // 5: clouditor.Order
+	(*MetricConfiguration)(nil), // 6: clouditor.MetricConfiguration
+	(*structpb.Value)(nil),      // 7: google.protobuf.Value
 }
 var file_metric_proto_depIdxs = []int32{
 	0, // 0: clouditor.Metric.scale:type_name -> clouditor.Metric.Scale
@@ -525,13 +602,14 @@ var file_metric_proto_depIdxs = []int32{
 	4, // 2: clouditor.Range.allowed_values:type_name -> clouditor.AllowedValues
 	5, // 3: clouditor.Range.order:type_name -> clouditor.Order
 	3, // 4: clouditor.Range.min_max:type_name -> clouditor.MinMax
-	6, // 5: clouditor.AllowedValues.values:type_name -> google.protobuf.Value
-	6, // 6: clouditor.Order.values:type_name -> google.protobuf.Value
-	7, // [7:7] is the sub-list for method output_type
-	7, // [7:7] is the sub-list for method input_type
-	7, // [7:7] is the sub-list for extension type_name
-	7, // [7:7] is the sub-list for extension extendee
-	0, // [0:7] is the sub-list for field type_name
+	7, // 5: clouditor.AllowedValues.values:type_name -> google.protobuf.Value
+	7, // 6: clouditor.Order.values:type_name -> google.protobuf.Value
+	7, // 7: clouditor.MetricConfiguration.target_value:type_name -> google.protobuf.Value
+	8, // [8:8] is the sub-list for method output_type
+	8, // [8:8] is the sub-list for method input_type
+	8, // [8:8] is the sub-list for extension type_name
+	8, // [8:8] is the sub-list for extension extendee
+	0, // [0:8] is the sub-list for field type_name
 }
 
 func init() { file_metric_proto_init() }
@@ -600,6 +678,18 @@ func file_metric_proto_init() {
 				return nil
 			}
 		}
+		file_metric_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*MetricConfiguration); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	file_metric_proto_msgTypes[1].OneofWrappers = []interface{}{
 		(*Range_AllowedValues)(nil),
@@ -612,7 +702,7 @@ func file_metric_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_metric_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   5,
+			NumMessages:   6,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/api/orchestrator/orchestrator.pb.go b/api/orchestrator/orchestrator.pb.go
index 7da1332c..ec5f42f9 100644
--- a/api/orchestrator/orchestrator.pb.go
+++ b/api/orchestrator/orchestrator.pb.go
@@ -92,7 +92,7 @@ func (x AssessmentResult_ComplianceStatus) Number() protoreflect.EnumNumber {
 
 // Deprecated: Use AssessmentResult_ComplianceStatus.Descriptor instead.
 func (AssessmentResult_ComplianceStatus) EnumDescriptor() ([]byte, []int) {
-	return file_orchestrator_proto_rawDescGZIP(), []int{12, 0}
+	return file_orchestrator_proto_rawDescGZIP(), []int{21, 0}
 }
 
 type RegisterAssessmentToolRequest struct {
@@ -604,6 +604,437 @@ func (x *ListMetricsResponse) GetMetrics() []*assessment.Metric {
 	return nil
 }
 
+type GetCloudServiceRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"`
+}
+
+func (x *GetCloudServiceRequest) Reset() {
+	*x = GetCloudServiceRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[11]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetCloudServiceRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetCloudServiceRequest) ProtoMessage() {}
+
+func (x *GetCloudServiceRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[11]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetCloudServiceRequest.ProtoReflect.Descriptor instead.
+func (*GetCloudServiceRequest) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{11}
+}
+
+func (x *GetCloudServiceRequest) GetServiceId() string {
+	if x != nil {
+		return x.ServiceId
+	}
+	return ""
+}
+
+type RegisterCloudServiceRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Service *CloudService `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"`
+}
+
+func (x *RegisterCloudServiceRequest) Reset() {
+	*x = RegisterCloudServiceRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[12]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RegisterCloudServiceRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RegisterCloudServiceRequest) ProtoMessage() {}
+
+func (x *RegisterCloudServiceRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[12]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RegisterCloudServiceRequest.ProtoReflect.Descriptor instead.
+func (*RegisterCloudServiceRequest) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *RegisterCloudServiceRequest) GetService() *CloudService {
+	if x != nil {
+		return x.Service
+	}
+	return nil
+}
+
+type UpdateCloudServiceRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ServiceId string        `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"`
+	Service   *CloudService `protobuf:"bytes,2,opt,name=service,proto3" json:"service,omitempty"`
+}
+
+func (x *UpdateCloudServiceRequest) Reset() {
+	*x = UpdateCloudServiceRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[13]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *UpdateCloudServiceRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateCloudServiceRequest) ProtoMessage() {}
+
+func (x *UpdateCloudServiceRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[13]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateCloudServiceRequest.ProtoReflect.Descriptor instead.
+func (*UpdateCloudServiceRequest) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *UpdateCloudServiceRequest) GetServiceId() string {
+	if x != nil {
+		return x.ServiceId
+	}
+	return ""
+}
+
+func (x *UpdateCloudServiceRequest) GetService() *CloudService {
+	if x != nil {
+		return x.Service
+	}
+	return nil
+}
+
+type RemoveCloudServiceRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"`
+}
+
+func (x *RemoveCloudServiceRequest) Reset() {
+	*x = RemoveCloudServiceRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[14]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *RemoveCloudServiceRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*RemoveCloudServiceRequest) ProtoMessage() {}
+
+func (x *RemoveCloudServiceRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[14]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use RemoveCloudServiceRequest.ProtoReflect.Descriptor instead.
+func (*RemoveCloudServiceRequest) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *RemoveCloudServiceRequest) GetServiceId() string {
+	if x != nil {
+		return x.ServiceId
+	}
+	return ""
+}
+
+type ListCloudServicesRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+}
+
+func (x *ListCloudServicesRequest) Reset() {
+	*x = ListCloudServicesRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[15]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListCloudServicesRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListCloudServicesRequest) ProtoMessage() {}
+
+func (x *ListCloudServicesRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[15]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListCloudServicesRequest.ProtoReflect.Descriptor instead.
+func (*ListCloudServicesRequest) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{15}
+}
+
+type ListCloudServicesResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Services []*CloudService `protobuf:"bytes,1,rep,name=services,proto3" json:"services,omitempty"`
+}
+
+func (x *ListCloudServicesResponse) Reset() {
+	*x = ListCloudServicesResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[16]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListCloudServicesResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListCloudServicesResponse) ProtoMessage() {}
+
+func (x *ListCloudServicesResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[16]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListCloudServicesResponse.ProtoReflect.Descriptor instead.
+func (*ListCloudServicesResponse) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{16}
+}
+
+func (x *ListCloudServicesResponse) GetServices() []*CloudService {
+	if x != nil {
+		return x.Services
+	}
+	return nil
+}
+
+type GetMetricConfigurationRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"`
+	MetricId  string `protobuf:"bytes,2,opt,name=metric_id,json=metricId,proto3" json:"metric_id,omitempty"`
+}
+
+func (x *GetMetricConfigurationRequest) Reset() {
+	*x = GetMetricConfigurationRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[17]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *GetMetricConfigurationRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetMetricConfigurationRequest) ProtoMessage() {}
+
+func (x *GetMetricConfigurationRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[17]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetMetricConfigurationRequest.ProtoReflect.Descriptor instead.
+func (*GetMetricConfigurationRequest) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{17}
+}
+
+func (x *GetMetricConfigurationRequest) GetServiceId() string {
+	if x != nil {
+		return x.ServiceId
+	}
+	return ""
+}
+
+func (x *GetMetricConfigurationRequest) GetMetricId() string {
+	if x != nil {
+		return x.MetricId
+	}
+	return ""
+}
+
+type ListMetricConfigurationRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ServiceId string `protobuf:"bytes,1,opt,name=service_id,json=serviceId,proto3" json:"service_id,omitempty"`
+}
+
+func (x *ListMetricConfigurationRequest) Reset() {
+	*x = ListMetricConfigurationRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[18]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListMetricConfigurationRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListMetricConfigurationRequest) ProtoMessage() {}
+
+func (x *ListMetricConfigurationRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[18]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListMetricConfigurationRequest.ProtoReflect.Descriptor instead.
+func (*ListMetricConfigurationRequest) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *ListMetricConfigurationRequest) GetServiceId() string {
+	if x != nil {
+		return x.ServiceId
+	}
+	return ""
+}
+
+type ListMetricConfigurationResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// A map of metric configurations associated by their metric ID
+	Configurations map[string]*assessment.MetricConfiguration `protobuf:"bytes,1,rep,name=configurations,proto3" json:"configurations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *ListMetricConfigurationResponse) Reset() {
+	*x = ListMetricConfigurationResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[19]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *ListMetricConfigurationResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListMetricConfigurationResponse) ProtoMessage() {}
+
+func (x *ListMetricConfigurationResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[19]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListMetricConfigurationResponse.ProtoReflect.Descriptor instead.
+func (*ListMetricConfigurationResponse) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{19}
+}
+
+func (x *ListMetricConfigurationResponse) GetConfigurations() map[string]*assessment.MetricConfiguration {
+	if x != nil {
+		return x.Configurations
+	}
+	return nil
+}
+
 // Represents an external tool or service that offers assessments according to
 // certain metrics
 type AssessmentTool struct {
@@ -621,7 +1052,7 @@ type AssessmentTool struct {
 func (x *AssessmentTool) Reset() {
 	*x = AssessmentTool{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_orchestrator_proto_msgTypes[11]
+		mi := &file_orchestrator_proto_msgTypes[20]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -634,7 +1065,7 @@ func (x *AssessmentTool) String() string {
 func (*AssessmentTool) ProtoMessage() {}
 
 func (x *AssessmentTool) ProtoReflect() protoreflect.Message {
-	mi := &file_orchestrator_proto_msgTypes[11]
+	mi := &file_orchestrator_proto_msgTypes[20]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -647,7 +1078,7 @@ func (x *AssessmentTool) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AssessmentTool.ProtoReflect.Descriptor instead.
 func (*AssessmentTool) Descriptor() ([]byte, []int) {
-	return file_orchestrator_proto_rawDescGZIP(), []int{11}
+	return file_orchestrator_proto_rawDescGZIP(), []int{20}
 }
 
 func (x *AssessmentTool) GetId() string {
@@ -695,7 +1126,7 @@ type AssessmentResult struct {
 func (x *AssessmentResult) Reset() {
 	*x = AssessmentResult{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_orchestrator_proto_msgTypes[12]
+		mi := &file_orchestrator_proto_msgTypes[21]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -708,7 +1139,7 @@ func (x *AssessmentResult) String() string {
 func (*AssessmentResult) ProtoMessage() {}
 
 func (x *AssessmentResult) ProtoReflect() protoreflect.Message {
-	mi := &file_orchestrator_proto_msgTypes[12]
+	mi := &file_orchestrator_proto_msgTypes[21]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -721,7 +1152,7 @@ func (x *AssessmentResult) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use AssessmentResult.ProtoReflect.Descriptor instead.
 func (*AssessmentResult) Descriptor() ([]byte, []int) {
-	return file_orchestrator_proto_rawDescGZIP(), []int{12}
+	return file_orchestrator_proto_rawDescGZIP(), []int{21}
 }
 
 func (x *AssessmentResult) GetId() string {
@@ -759,6 +1190,69 @@ func (x *AssessmentResult) GetEvidenceId() string {
 	return ""
 }
 
+type CloudService struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Id          string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+	Name        string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Description string `protobuf:"bytes,3,opt,name=description,proto3" json:"description,omitempty"`
+}
+
+func (x *CloudService) Reset() {
+	*x = CloudService{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_orchestrator_proto_msgTypes[22]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CloudService) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CloudService) ProtoMessage() {}
+
+func (x *CloudService) ProtoReflect() protoreflect.Message {
+	mi := &file_orchestrator_proto_msgTypes[22]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CloudService.ProtoReflect.Descriptor instead.
+func (*CloudService) Descriptor() ([]byte, []int) {
+	return file_orchestrator_proto_rawDescGZIP(), []int{22}
+}
+
+func (x *CloudService) GetId() string {
+	if x != nil {
+		return x.Id
+	}
+	return ""
+}
+
+func (x *CloudService) GetName() string {
+	if x != nil {
+		return x.Name
+	}
+	return ""
+}
+
+func (x *CloudService) GetDescription() string {
+	if x != nil {
+		return x.Description
+	}
+	return ""
+}
+
 var File_orchestrator_proto protoreflect.FileDescriptor
 
 var file_orchestrator_proto_rawDesc = []byte{
@@ -811,110 +1305,234 @@ var file_orchestrator_proto_rawDesc = []byte{
 	0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
 	0x12, 0x2b, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
 	0x0b, 0x32, 0x11, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x83, 0x01,
-	0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c,
-	0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
-	0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
-	0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
-	0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61,
-	0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28,
-	0x09, 0x52, 0x10, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x73, 0x22, 0xff, 0x01, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65,
-	0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x49, 0x64, 0x12, 0x44, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18,
-	0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f,
-	0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75,
-	0x6c, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x74,
-	0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f,
-	0x0a, 0x0b, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20,
-	0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22,
-	0x34, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e, 0x54,
-	0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49,
-	0x41, 0x4e, 0x54, 0x10, 0x01, 0x32, 0xe8, 0x09, 0x0a, 0x0c, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73,
-	0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x8e, 0x01, 0x0a, 0x16, 0x52, 0x65, 0x67, 0x69, 0x73,
-	0x74, 0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f,
-	0x6c, 0x12, 0x28, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x52, 0x65,
-	0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74,
+	0x74, 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x37, 0x0a,
+	0x16, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72,
+	0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22, 0x50, 0x0a, 0x1b, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74,
+	0x65, 0x72, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
+	0x6f, 0x72, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52,
+	0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x6d, 0x0a, 0x19, 0x55, 0x70, 0x64, 0x61,
+	0x74, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65,
+	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69,
+	0x63, 0x65, 0x49, 0x64, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18,
+	0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f,
+	0x72, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76,
+	0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71,
+	0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x49, 0x64, 0x22, 0x1a, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64,
+	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22,
+	0x50, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x08,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17,
+	0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64,
+	0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x08, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x73, 0x22, 0x5b, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49,
+	0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x49, 0x64, 0x22, 0x3f,
+	0x0a, 0x1e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66,
+	0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x49, 0x64, 0x22,
+	0xec, 0x01, 0x0a, 0x1f, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f,
+	0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x12, 0x66, 0x0a, 0x0e, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x63, 0x6c,
+	0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72,
+	0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
+	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0e, 0x63, 0x6f, 0x6e,
+	0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x61, 0x0a, 0x13, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74,
+	0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x03, 0x6b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
+	0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x83,
+	0x01, 0x0a, 0x0e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f,
+	0x6c, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69,
+	0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
+	0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63,
+	0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2b, 0x0a, 0x11, 0x61, 0x76, 0x61, 0x69, 0x6c,
+	0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x18, 0x04, 0x20, 0x03,
+	0x28, 0x09, 0x52, 0x10, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x73, 0x22, 0xff, 0x01, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
+	0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x49, 0x64, 0x12, 0x44, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2c, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
+	0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73,
+	0x75, 0x6c, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x21, 0x0a, 0x0c,
+	0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x0b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12,
+	0x1f, 0x0a, 0x0b, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x76, 0x69, 0x64, 0x65, 0x6e, 0x63, 0x65, 0x49, 0x64,
+	0x22, 0x34, 0x0a, 0x10, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x49, 0x41, 0x4e,
+	0x54, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x4f, 0x4e, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c,
+	0x49, 0x41, 0x4e, 0x54, 0x10, 0x01, 0x22, 0x54, 0x0a, 0x0c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
+	0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,
+	0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+	0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0xa1, 0x12, 0x0a,
+	0x0c, 0x4f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x8e, 0x01,
+	0x0a, 0x16, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73,
+	0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x12, 0x28, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x73, 0x73,
+	0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41,
+	0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x22, 0x2f, 0x82,
+	0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65,
+	0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65,
+	0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x3a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0xbf,
+	0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
+	0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x25, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
+	0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
+	0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e,
+	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x53, 0x12, 0x21, 0x2f,
+	0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f,
+	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73,
+	0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x61,
+	0x74, 0x6f, 0x72, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x7d, 0x2f,
+	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73,
+	0x12, 0x88, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65,
+	0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x12, 0x23, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
+	0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74,
 	0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6c,
 	0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65,
-	0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x22, 0x21,
+	0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x12, 0x2b,
 	0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72,
 	0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c,
-	0x73, 0x3a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0xbf, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74,
-	0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x12,
-	0x25, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74,
-	0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
-	0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
-	0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x59,
-	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x53, 0x12, 0x21, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68,
-	0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
-	0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x5a, 0x2e, 0x12, 0x2c, 0x2f, 0x76, 0x31,
-	0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x7b, 0x6d, 0x65,
-	0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
-	0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x11, 0x47, 0x65,
-	0x74, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x12,
-	0x23, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x41,
-	0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
-	0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x22,
-	0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x12, 0x2b, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63,
-	0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73,
-	0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x7b, 0x74, 0x6f, 0x6f, 0x6c,
-	0x5f, 0x69, 0x64, 0x7d, 0x12, 0x94, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41,
-	0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x12, 0x26, 0x2e,
-	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
-	0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x65,
-	0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f,
-	0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c,
-	0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x1a, 0x2b, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72,
-	0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73,
-	0x73, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x7b, 0x74, 0x6f, 0x6f,
-	0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x93, 0x01, 0x0a, 0x18,
-	0x44, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73,
-	0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x12, 0x2a, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
-	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x44, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41,
-	0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 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, 0x33, 0x82, 0xd3,
-	0xe4, 0x93, 0x02, 0x2d, 0x2a, 0x2b, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73,
-	0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
-	0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x7b, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64,
-	0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73,
-	0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6c,
+	0x73, 0x2f, 0x7b, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x94, 0x01, 0x0a, 0x14,
+	0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74,
+	0x54, 0x6f, 0x6f, 0x6c, 0x12, 0x26, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
+	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e,
+	0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63,
+	0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
+	0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x22, 0x39, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x33, 0x1a,
+	0x2b, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f,
+	0x72, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f,
+	0x6c, 0x73, 0x2f, 0x7b, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x3a, 0x04, 0x74, 0x6f,
+	0x6f, 0x6c, 0x12, 0x93, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65,
+	0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x6f, 0x6f, 0x6c, 0x12,
+	0x2a, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x44, 0x65, 0x72, 0x65,
+	0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74,
+	0x54, 0x6f, 0x6f, 0x6c, 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, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x2a, 0x2b, 0x2f, 0x76, 0x31,
+	0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x73,
+	0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x6f, 0x6f, 0x6c, 0x73, 0x2f, 0x7b,
+	0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x9f, 0x01, 0x0a, 0x15, 0x53, 0x74, 0x6f,
+	0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75,
+	0x6c, 0x74, 0x12, 0x27, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x53,
+	0x74, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65,
+	0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6c,
 	0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73,
-	0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x71,
-	0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
-	0x2e, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74,
-	0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33,
-	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x1a, 0x23, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68,
-	0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d,
-	0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x3a, 0x06, 0x72, 0x65, 0x73,
-	0x75, 0x6c, 0x74, 0x12, 0x4f, 0x0a, 0x16, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65,
-	0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x1b, 0x2e,
-	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73,
-	0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 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, 0x28, 0x01, 0x12, 0x6e, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e,
-	0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
-	0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c,
-	0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
-	0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x2f,
-	0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x12, 0x6a, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69,
-	0x63, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65,
-	0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
-	0x11, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72,
-	0x69, 0x63, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f,
-	0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x6d, 0x65, 0x74,
-	0x72, 0x69, 0x63, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x7d,
+	0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x33, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2d, 0x1a, 0x23, 0x2f,
+	0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f,
+	0x61, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x75, 0x6c,
+	0x74, 0x73, 0x3a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x4f, 0x0a, 0x16, 0x53, 0x74,
+	0x6f, 0x72, 0x65, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73,
+	0x75, 0x6c, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
+	0x2e, 0x41, 0x73, 0x73, 0x65, 0x73, 0x73, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c,
+	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, 0x28, 0x01, 0x12, 0x6e, 0x0a, 0x0b, 0x4c,
+	0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x1d, 0x2e, 0x63, 0x6c, 0x6f,
+	0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x6c, 0x6f, 0x75,
+	0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x1a, 0x12, 0x18, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61,
+	0x74, 0x6f, 0x72, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x12, 0x6a, 0x0a, 0x09, 0x47,
+	0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x1c, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74,
+	0x6f, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x26, 0x12, 0x24, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61,
+	0x74, 0x6f, 0x72, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74,
+	0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x89, 0x01, 0x0a, 0x14, 0x52, 0x65, 0x67, 0x69,
+	0x73, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x12, 0x26, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x52, 0x65, 0x67,
+	0x69, 0x73, 0x74, 0x65, 0x72, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x22, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x6f,
+	0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6c, 0x6f, 0x75,
+	0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x3a, 0x07, 0x73, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x12, 0x92, 0x01, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c,
+	0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x2e, 0x63, 0x6c, 0x6f,
+	0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6c, 0x6f,
+	0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+	0x1a, 0x17, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x6c, 0x6f,
+	0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3d, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x37, 0x1a, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61,
+	0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x73, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x3a,
+	0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x83, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74,
+	0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x21, 0x2e, 0x63,
+	0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6c, 0x6f, 0x75,
+	0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x17, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x43, 0x6c, 0x6f, 0x75,
+	0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x34, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2e,
+	0x12, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74,
+	0x6f, 0x72, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x73, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x87,
+	0x01, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76,
+	0x69, 0x63, 0x65, 0x73, 0x12, 0x23, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72,
+	0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
+	0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x63, 0x6c, 0x6f, 0x75,
+	0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
+	0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63,
+	0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f,
+	0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x88, 0x01, 0x0a, 0x12, 0x52, 0x65, 0x6d,
+	0x6f, 0x76, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12,
+	0x24, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x52, 0x65, 0x6d, 0x6f,
+	0x76, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x53, 0x65, 0x72, 0x76, 0x69, 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, 0x34, 0x82,
+	0xd3, 0xe4, 0x93, 0x02, 0x2e, 0x2a, 0x2c, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65,
+	0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73, 0x65,
+	0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f,
+	0x69, 0x64, 0x7d, 0x12, 0xba, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28,
+	0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+	0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x56, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x50,
+	0x12, 0x4e, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74,
+	0x6f, 0x72, 0x2f, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x73, 0x2f, 0x7b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d,
+	0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
+	0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x7d,
+	0x12, 0xbd, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x2e,
+	0x63, 0x6c, 0x6f, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65,
+	0x74, 0x72, 0x69, 0x63, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+	0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
+	0x69, 0x74, 0x6f, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x43,
+	0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x44, 0x12, 0x42, 0x2f, 0x76,
+	0x31, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x2f, 0x63,
+	0x6c, 0x6f, 0x75, 0x64, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x73,
+	0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,
+	0x63, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
 	0x42, 0x12, 0x5a, 0x10, 0x61, 0x70, 0x69, 0x2f, 0x6f, 0x72, 0x63, 0x68, 0x65, 0x73, 0x74, 0x72,
 	0x61, 0x74, 0x6f, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
@@ -932,7 +1550,7 @@ func file_orchestrator_proto_rawDescGZIP() []byte {
 }
 
 var file_orchestrator_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
-var file_orchestrator_proto_msgTypes = make([]protoimpl.MessageInfo, 13)
+var file_orchestrator_proto_msgTypes = make([]protoimpl.MessageInfo, 24)
 var file_orchestrator_proto_goTypes = []interface{}{
 	(AssessmentResult_ComplianceStatus)(0),  // 0: clouditor.AssessmentResult.ComplianceStatus
 	(*RegisterAssessmentToolRequest)(nil),   // 1: clouditor.RegisterAssessmentToolRequest
@@ -946,41 +1564,72 @@ var file_orchestrator_proto_goTypes = []interface{}{
 	(*GetMetricsRequest)(nil),               // 9: clouditor.GetMetricsRequest
 	(*ListMetricsRequest)(nil),              // 10: clouditor.ListMetricsRequest
 	(*ListMetricsResponse)(nil),             // 11: clouditor.ListMetricsResponse
-	(*AssessmentTool)(nil),                  // 12: clouditor.AssessmentTool
-	(*AssessmentResult)(nil),                // 13: clouditor.AssessmentResult
-	(*assessment.Metric)(nil),               // 14: clouditor.Metric
-	(*emptypb.Empty)(nil),                   // 15: google.protobuf.Empty
+	(*GetCloudServiceRequest)(nil),          // 12: clouditor.GetCloudServiceRequest
+	(*RegisterCloudServiceRequest)(nil),     // 13: clouditor.RegisterCloudServiceRequest
+	(*UpdateCloudServiceRequest)(nil),       // 14: clouditor.UpdateCloudServiceRequest
+	(*RemoveCloudServiceRequest)(nil),       // 15: clouditor.RemoveCloudServiceRequest
+	(*ListCloudServicesRequest)(nil),        // 16: clouditor.ListCloudServicesRequest
+	(*ListCloudServicesResponse)(nil),       // 17: clouditor.ListCloudServicesResponse
+	(*GetMetricConfigurationRequest)(nil),   // 18: clouditor.GetMetricConfigurationRequest
+	(*ListMetricConfigurationRequest)(nil),  // 19: clouditor.ListMetricConfigurationRequest
+	(*ListMetricConfigurationResponse)(nil), // 20: clouditor.ListMetricConfigurationResponse
+	(*AssessmentTool)(nil),                  // 21: clouditor.AssessmentTool
+	(*AssessmentResult)(nil),                // 22: clouditor.AssessmentResult
+	(*CloudService)(nil),                    // 23: clouditor.CloudService
+	nil,                                     // 24: clouditor.ListMetricConfigurationResponse.ConfigurationsEntry
+	(*assessment.Metric)(nil),               // 25: clouditor.Metric
+	(*assessment.MetricConfiguration)(nil),  // 26: clouditor.MetricConfiguration
+	(*emptypb.Empty)(nil),                   // 27: google.protobuf.Empty
 }
 var file_orchestrator_proto_depIdxs = []int32{
-	12, // 0: clouditor.RegisterAssessmentToolRequest.tool:type_name -> clouditor.AssessmentTool
-	12, // 1: clouditor.ListAssessmentToolsResponse.tools:type_name -> clouditor.AssessmentTool
-	12, // 2: clouditor.UpdateAssessmentToolRequest.tool:type_name -> clouditor.AssessmentTool
-	13, // 3: clouditor.StoreAssessmentResultRequest.result:type_name -> clouditor.AssessmentResult
-	14, // 4: clouditor.ListMetricsResponse.metrics:type_name -> clouditor.Metric
-	0,  // 5: clouditor.AssessmentResult.result:type_name -> clouditor.AssessmentResult.ComplianceStatus
-	1,  // 6: clouditor.Orchestrator.RegisterAssessmentTool:input_type -> clouditor.RegisterAssessmentToolRequest
-	2,  // 7: clouditor.Orchestrator.ListAssessmentTools:input_type -> clouditor.ListAssessmentToolsRequest
-	4,  // 8: clouditor.Orchestrator.GetAssessmentTool:input_type -> clouditor.GetAssessmentToolRequest
-	5,  // 9: clouditor.Orchestrator.UpdateAssessmentTool:input_type -> clouditor.UpdateAssessmentToolRequest
-	6,  // 10: clouditor.Orchestrator.DeregisterAssessmentTool:input_type -> clouditor.DeregisterAssessmentToolRequest
-	7,  // 11: clouditor.Orchestrator.StoreAssessmentResult:input_type -> clouditor.StoreAssessmentResultRequest
-	13, // 12: clouditor.Orchestrator.StoreAssessmentResults:input_type -> clouditor.AssessmentResult
-	10, // 13: clouditor.Orchestrator.ListMetrics:input_type -> clouditor.ListMetricsRequest
-	9,  // 14: clouditor.Orchestrator.GetMetric:input_type -> clouditor.GetMetricsRequest
-	12, // 15: clouditor.Orchestrator.RegisterAssessmentTool:output_type -> clouditor.AssessmentTool
-	3,  // 16: clouditor.Orchestrator.ListAssessmentTools:output_type -> clouditor.ListAssessmentToolsResponse
-	12, // 17: clouditor.Orchestrator.GetAssessmentTool:output_type -> clouditor.AssessmentTool
-	12, // 18: clouditor.Orchestrator.UpdateAssessmentTool:output_type -> clouditor.AssessmentTool
-	15, // 19: clouditor.Orchestrator.DeregisterAssessmentTool:output_type -> google.protobuf.Empty
-	8,  // 20: clouditor.Orchestrator.StoreAssessmentResult:output_type -> clouditor.StoreAssessmentResultResponse
-	15, // 21: clouditor.Orchestrator.StoreAssessmentResults:output_type -> google.protobuf.Empty
-	11, // 22: clouditor.Orchestrator.ListMetrics:output_type -> clouditor.ListMetricsResponse
-	14, // 23: clouditor.Orchestrator.GetMetric:output_type -> clouditor.Metric
-	15, // [15:24] is the sub-list for method output_type
-	6,  // [6:15] is the sub-list for method input_type
-	6,  // [6:6] is the sub-list for extension type_name
-	6,  // [6:6] is the sub-list for extension extendee
-	0,  // [0:6] is the sub-list for field type_name
+	21, // 0: clouditor.RegisterAssessmentToolRequest.tool:type_name -> clouditor.AssessmentTool
+	21, // 1: clouditor.ListAssessmentToolsResponse.tools:type_name -> clouditor.AssessmentTool
+	21, // 2: clouditor.UpdateAssessmentToolRequest.tool:type_name -> clouditor.AssessmentTool
+	22, // 3: clouditor.StoreAssessmentResultRequest.result:type_name -> clouditor.AssessmentResult
+	25, // 4: clouditor.ListMetricsResponse.metrics:type_name -> clouditor.Metric
+	23, // 5: clouditor.RegisterCloudServiceRequest.service:type_name -> clouditor.CloudService
+	23, // 6: clouditor.UpdateCloudServiceRequest.service:type_name -> clouditor.CloudService
+	23, // 7: clouditor.ListCloudServicesResponse.services:type_name -> clouditor.CloudService
+	24, // 8: clouditor.ListMetricConfigurationResponse.configurations:type_name -> clouditor.ListMetricConfigurationResponse.ConfigurationsEntry
+	0,  // 9: clouditor.AssessmentResult.result:type_name -> clouditor.AssessmentResult.ComplianceStatus
+	26, // 10: clouditor.ListMetricConfigurationResponse.ConfigurationsEntry.value:type_name -> clouditor.MetricConfiguration
+	1,  // 11: clouditor.Orchestrator.RegisterAssessmentTool:input_type -> clouditor.RegisterAssessmentToolRequest
+	2,  // 12: clouditor.Orchestrator.ListAssessmentTools:input_type -> clouditor.ListAssessmentToolsRequest
+	4,  // 13: clouditor.Orchestrator.GetAssessmentTool:input_type -> clouditor.GetAssessmentToolRequest
+	5,  // 14: clouditor.Orchestrator.UpdateAssessmentTool:input_type -> clouditor.UpdateAssessmentToolRequest
+	6,  // 15: clouditor.Orchestrator.DeregisterAssessmentTool:input_type -> clouditor.DeregisterAssessmentToolRequest
+	7,  // 16: clouditor.Orchestrator.StoreAssessmentResult:input_type -> clouditor.StoreAssessmentResultRequest
+	22, // 17: clouditor.Orchestrator.StoreAssessmentResults:input_type -> clouditor.AssessmentResult
+	10, // 18: clouditor.Orchestrator.ListMetrics:input_type -> clouditor.ListMetricsRequest
+	9,  // 19: clouditor.Orchestrator.GetMetric:input_type -> clouditor.GetMetricsRequest
+	13, // 20: clouditor.Orchestrator.RegisterCloudService:input_type -> clouditor.RegisterCloudServiceRequest
+	14, // 21: clouditor.Orchestrator.UpdateCloudService:input_type -> clouditor.UpdateCloudServiceRequest
+	12, // 22: clouditor.Orchestrator.GetCloudService:input_type -> clouditor.GetCloudServiceRequest
+	16, // 23: clouditor.Orchestrator.ListCloudServices:input_type -> clouditor.ListCloudServicesRequest
+	15, // 24: clouditor.Orchestrator.RemoveCloudService:input_type -> clouditor.RemoveCloudServiceRequest
+	18, // 25: clouditor.Orchestrator.GetMetricConfiguration:input_type -> clouditor.GetMetricConfigurationRequest
+	19, // 26: clouditor.Orchestrator.ListMetricConfigurations:input_type -> clouditor.ListMetricConfigurationRequest
+	21, // 27: clouditor.Orchestrator.RegisterAssessmentTool:output_type -> clouditor.AssessmentTool
+	3,  // 28: clouditor.Orchestrator.ListAssessmentTools:output_type -> clouditor.ListAssessmentToolsResponse
+	21, // 29: clouditor.Orchestrator.GetAssessmentTool:output_type -> clouditor.AssessmentTool
+	21, // 30: clouditor.Orchestrator.UpdateAssessmentTool:output_type -> clouditor.AssessmentTool
+	27, // 31: clouditor.Orchestrator.DeregisterAssessmentTool:output_type -> google.protobuf.Empty
+	8,  // 32: clouditor.Orchestrator.StoreAssessmentResult:output_type -> clouditor.StoreAssessmentResultResponse
+	27, // 33: clouditor.Orchestrator.StoreAssessmentResults:output_type -> google.protobuf.Empty
+	11, // 34: clouditor.Orchestrator.ListMetrics:output_type -> clouditor.ListMetricsResponse
+	25, // 35: clouditor.Orchestrator.GetMetric:output_type -> clouditor.Metric
+	23, // 36: clouditor.Orchestrator.RegisterCloudService:output_type -> clouditor.CloudService
+	23, // 37: clouditor.Orchestrator.UpdateCloudService:output_type -> clouditor.CloudService
+	23, // 38: clouditor.Orchestrator.GetCloudService:output_type -> clouditor.CloudService
+	17, // 39: clouditor.Orchestrator.ListCloudServices:output_type -> clouditor.ListCloudServicesResponse
+	27, // 40: clouditor.Orchestrator.RemoveCloudService:output_type -> google.protobuf.Empty
+	26, // 41: clouditor.Orchestrator.GetMetricConfiguration:output_type -> clouditor.MetricConfiguration
+	20, // 42: clouditor.Orchestrator.ListMetricConfigurations:output_type -> clouditor.ListMetricConfigurationResponse
+	27, // [27:43] is the sub-list for method output_type
+	11, // [11:27] is the sub-list for method input_type
+	11, // [11:11] is the sub-list for extension type_name
+	11, // [11:11] is the sub-list for extension extendee
+	0,  // [0:11] is the sub-list for field type_name
 }
 
 func init() { file_orchestrator_proto_init() }
@@ -1122,7 +1771,7 @@ func file_orchestrator_proto_init() {
 			}
 		}
 		file_orchestrator_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
-			switch v := v.(*AssessmentTool); i {
+			switch v := v.(*GetCloudServiceRequest); i {
 			case 0:
 				return &v.state
 			case 1:
@@ -1134,6 +1783,114 @@ func file_orchestrator_proto_init() {
 			}
 		}
 		file_orchestrator_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RegisterCloudServiceRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*UpdateCloudServiceRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*RemoveCloudServiceRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListCloudServicesRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListCloudServicesResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*GetMetricConfigurationRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListMetricConfigurationRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*ListMetricConfigurationResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*AssessmentTool); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_orchestrator_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*AssessmentResult); i {
 			case 0:
 				return &v.state
@@ -1145,6 +1902,18 @@ func file_orchestrator_proto_init() {
 				return nil
 			}
 		}
+		file_orchestrator_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CloudService); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
 	}
 	type x struct{}
 	out := protoimpl.TypeBuilder{
@@ -1152,7 +1921,7 @@ func file_orchestrator_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_orchestrator_proto_rawDesc,
 			NumEnums:      1,
-			NumMessages:   13,
+			NumMessages:   24,
 			NumExtensions: 0,
 			NumServices:   1,
 		},
diff --git a/api/orchestrator/orchestrator.pb.gw.go b/api/orchestrator/orchestrator.pb.gw.go
index 97a338be..12624ebc 100644
--- a/api/orchestrator/orchestrator.pb.gw.go
+++ b/api/orchestrator/orchestrator.pb.gw.go
@@ -429,24 +429,464 @@ func local_request_Orchestrator_GetMetric_0(ctx context.Context, marshaler runti
 
 }
 
+func request_Orchestrator_RegisterCloudService_0(ctx context.Context, marshaler runtime.Marshaler, client OrchestratorClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq RegisterCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Service); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := client.RegisterCloudService(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Orchestrator_RegisterCloudService_0(ctx context.Context, marshaler runtime.Marshaler, server OrchestratorServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq RegisterCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Service); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	msg, err := server.RegisterCloudService(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_Orchestrator_UpdateCloudService_0(ctx context.Context, marshaler runtime.Marshaler, client OrchestratorClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq UpdateCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Service); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := client.UpdateCloudService(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Orchestrator_UpdateCloudService_0(ctx context.Context, marshaler runtime.Marshaler, server OrchestratorServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq UpdateCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	newReader, berr := utilities.IOReaderFactory(req.Body)
+	if berr != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
+	}
+	if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Service); err != nil && err != io.EOF {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
+	}
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := server.UpdateCloudService(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_Orchestrator_GetCloudService_0(ctx context.Context, marshaler runtime.Marshaler, client OrchestratorClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := client.GetCloudService(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Orchestrator_GetCloudService_0(ctx context.Context, marshaler runtime.Marshaler, server OrchestratorServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := server.GetCloudService(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_Orchestrator_ListCloudServices_0(ctx context.Context, marshaler runtime.Marshaler, client OrchestratorClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ListCloudServicesRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := client.ListCloudServices(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Orchestrator_ListCloudServices_0(ctx context.Context, marshaler runtime.Marshaler, server OrchestratorServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ListCloudServicesRequest
+	var metadata runtime.ServerMetadata
+
+	msg, err := server.ListCloudServices(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_Orchestrator_RemoveCloudService_0(ctx context.Context, marshaler runtime.Marshaler, client OrchestratorClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq RemoveCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := client.RemoveCloudService(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Orchestrator_RemoveCloudService_0(ctx context.Context, marshaler runtime.Marshaler, server OrchestratorServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq RemoveCloudServiceRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := server.RemoveCloudService(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_Orchestrator_GetMetricConfiguration_0(ctx context.Context, marshaler runtime.Marshaler, client OrchestratorClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetMetricConfigurationRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	val, ok = pathParams["metric_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "metric_id")
+	}
+
+	protoReq.MetricId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "metric_id", err)
+	}
+
+	msg, err := client.GetMetricConfiguration(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Orchestrator_GetMetricConfiguration_0(ctx context.Context, marshaler runtime.Marshaler, server OrchestratorServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq GetMetricConfigurationRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	val, ok = pathParams["metric_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "metric_id")
+	}
+
+	protoReq.MetricId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "metric_id", err)
+	}
+
+	msg, err := server.GetMetricConfiguration(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
+func request_Orchestrator_ListMetricConfigurations_0(ctx context.Context, marshaler runtime.Marshaler, client OrchestratorClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ListMetricConfigurationRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := client.ListMetricConfigurations(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+	return msg, metadata, err
+
+}
+
+func local_request_Orchestrator_ListMetricConfigurations_0(ctx context.Context, marshaler runtime.Marshaler, server OrchestratorServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+	var protoReq ListMetricConfigurationRequest
+	var metadata runtime.ServerMetadata
+
+	var (
+		val string
+		ok  bool
+		err error
+		_   = err
+	)
+
+	val, ok = pathParams["service_id"]
+	if !ok {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "service_id")
+	}
+
+	protoReq.ServiceId, err = runtime.String(val)
+	if err != nil {
+		return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "service_id", err)
+	}
+
+	msg, err := server.ListMetricConfigurations(ctx, &protoReq)
+	return msg, metadata, err
+
+}
+
 // RegisterOrchestratorHandlerServer registers the http handlers for service Orchestrator to "mux".
 // UnaryRPC     :call OrchestratorServer directly.
 // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
 // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterOrchestratorHandlerFromEndpoint instead.
 func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMux, server OrchestratorServer) error {
 
-	mux.Handle("POST", pattern_Orchestrator_RegisterAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("POST", pattern_Orchestrator_RegisterAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/RegisterAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Orchestrator_RegisterAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_RegisterAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_ListAssessmentTools_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListAssessmentTools", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Orchestrator_ListAssessmentTools_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_ListAssessmentTools_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_ListAssessmentTools_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListAssessmentTools", runtime.WithHTTPPathPattern("/v1/orchestator/{metric_id}/assessment_tools"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Orchestrator_ListAssessmentTools_1(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_ListAssessmentTools_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_GetAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/GetAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools/{tool_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Orchestrator_GetAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_GetAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("PUT", pattern_Orchestrator_UpdateAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/RegisterAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/UpdateAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools/{tool_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_RegisterAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_UpdateAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -454,22 +894,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_RegisterAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_UpdateAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("GET", pattern_Orchestrator_ListAssessmentTools_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("DELETE", pattern_Orchestrator_DeregisterAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListAssessmentTools", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/DeregisterAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools/{tool_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_ListAssessmentTools_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_DeregisterAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -477,22 +917,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_ListAssessmentTools_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_DeregisterAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("GET", pattern_Orchestrator_ListAssessmentTools_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("PUT", pattern_Orchestrator_StoreAssessmentResult_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListAssessmentTools", runtime.WithHTTPPathPattern("/v1/orchestator/{metric_id}/assessment_tools"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/StoreAssessmentResult", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_results"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_ListAssessmentTools_1(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_StoreAssessmentResult_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -500,22 +940,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_ListAssessmentTools_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_StoreAssessmentResult_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("GET", pattern_Orchestrator_GetAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("GET", pattern_Orchestrator_ListMetrics_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/GetAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools/{tool_id}"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListMetrics", runtime.WithHTTPPathPattern("/v1/orchestrator/metrics"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_GetAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_ListMetrics_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -523,22 +963,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_GetAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_ListMetrics_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("PUT", pattern_Orchestrator_UpdateAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("GET", pattern_Orchestrator_GetMetric_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/UpdateAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools/{tool_id}"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/GetMetric", runtime.WithHTTPPathPattern("/v1/orchestrator/metrics/{metric_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_UpdateAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_GetMetric_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -546,22 +986,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_UpdateAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_GetMetric_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("DELETE", pattern_Orchestrator_DeregisterAssessmentTool_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("POST", pattern_Orchestrator_RegisterCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/DeregisterAssessmentTool", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_tools/{tool_id}"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/RegisterCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_DeregisterAssessmentTool_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_RegisterCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -569,22 +1009,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_DeregisterAssessmentTool_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_RegisterCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("PUT", pattern_Orchestrator_StoreAssessmentResult_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("PUT", pattern_Orchestrator_UpdateCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/StoreAssessmentResult", runtime.WithHTTPPathPattern("/v1/orchestrator/assessment_results"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/UpdateCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_StoreAssessmentResult_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_UpdateCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -592,22 +1032,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_StoreAssessmentResult_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_UpdateCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("GET", pattern_Orchestrator_ListMetrics_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("GET", pattern_Orchestrator_GetCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListMetrics", runtime.WithHTTPPathPattern("/v1/orchestrator/metrics"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/GetCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_ListMetrics_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_GetCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -615,22 +1055,22 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_ListMetrics_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_GetCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
-	mux.Handle("GET", pattern_Orchestrator_GetMetric_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+	mux.Handle("GET", pattern_Orchestrator_ListCloudServices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
 		ctx, cancel := context.WithCancel(req.Context())
 		defer cancel()
 		var stream runtime.ServerTransportStream
 		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
 		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
-		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/GetMetric", runtime.WithHTTPPathPattern("/v1/orchestrator/metrics/{metric_id}"))
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListCloudServices", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services"))
 		if err != nil {
 			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
 			return
 		}
-		resp, md, err := local_request_Orchestrator_GetMetric_0(rctx, inboundMarshaler, server, req, pathParams)
+		resp, md, err := local_request_Orchestrator_ListCloudServices_0(rctx, inboundMarshaler, server, req, pathParams)
 		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
 		ctx = runtime.NewServerMetadataContext(ctx, md)
 		if err != nil {
@@ -638,7 +1078,76 @@ func RegisterOrchestratorHandlerServer(ctx context.Context, mux *runtime.ServeMu
 			return
 		}
 
-		forward_Orchestrator_GetMetric_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+		forward_Orchestrator_ListCloudServices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_Orchestrator_RemoveCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/RemoveCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Orchestrator_RemoveCloudService_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_RemoveCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_GetMetricConfiguration_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/GetMetricConfiguration", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}/metric_configurations/{metric_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Orchestrator_GetMetricConfiguration_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_GetMetricConfiguration_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_ListMetricConfigurations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		var stream runtime.ServerTransportStream
+		ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/clouditor.Orchestrator/ListMetricConfigurations", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}/metric_configurations"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := local_request_Orchestrator_ListMetricConfigurations_0(rctx, inboundMarshaler, server, req, pathParams)
+		md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_ListMetricConfigurations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
 
 	})
 
@@ -863,6 +1372,146 @@ func RegisterOrchestratorHandlerClient(ctx context.Context, mux *runtime.ServeMu
 
 	})
 
+	mux.Handle("POST", pattern_Orchestrator_RegisterCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/clouditor.Orchestrator/RegisterCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Orchestrator_RegisterCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_RegisterCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("PUT", pattern_Orchestrator_UpdateCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/clouditor.Orchestrator/UpdateCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Orchestrator_UpdateCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_UpdateCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_GetCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/clouditor.Orchestrator/GetCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Orchestrator_GetCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_GetCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_ListCloudServices_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/clouditor.Orchestrator/ListCloudServices", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Orchestrator_ListCloudServices_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_ListCloudServices_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("DELETE", pattern_Orchestrator_RemoveCloudService_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/clouditor.Orchestrator/RemoveCloudService", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Orchestrator_RemoveCloudService_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_RemoveCloudService_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_GetMetricConfiguration_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/clouditor.Orchestrator/GetMetricConfiguration", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}/metric_configurations/{metric_id}"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Orchestrator_GetMetricConfiguration_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_GetMetricConfiguration_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
+	mux.Handle("GET", pattern_Orchestrator_ListMetricConfigurations_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+		ctx, cancel := context.WithCancel(req.Context())
+		defer cancel()
+		inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+		rctx, err := runtime.AnnotateContext(ctx, mux, req, "/clouditor.Orchestrator/ListMetricConfigurations", runtime.WithHTTPPathPattern("/v1/orchestrator/cloud_services/{service_id}/metric_configurations"))
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+		resp, md, err := request_Orchestrator_ListMetricConfigurations_0(rctx, inboundMarshaler, client, req, pathParams)
+		ctx = runtime.NewServerMetadataContext(ctx, md)
+		if err != nil {
+			runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+			return
+		}
+
+		forward_Orchestrator_ListMetricConfigurations_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+	})
+
 	return nil
 }
 
@@ -884,6 +1533,20 @@ var (
 	pattern_Orchestrator_ListMetrics_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "orchestrator", "metrics"}, ""))
 
 	pattern_Orchestrator_GetMetric_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "orchestrator", "metrics", "metric_id"}, ""))
+
+	pattern_Orchestrator_RegisterCloudService_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "orchestrator", "cloud_services"}, ""))
+
+	pattern_Orchestrator_UpdateCloudService_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "orchestrator", "cloud_services", "service_id"}, ""))
+
+	pattern_Orchestrator_GetCloudService_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "orchestrator", "cloud_services", "service_id"}, ""))
+
+	pattern_Orchestrator_ListCloudServices_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "orchestrator", "cloud_services"}, ""))
+
+	pattern_Orchestrator_RemoveCloudService_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"v1", "orchestrator", "cloud_services", "service_id"}, ""))
+
+	pattern_Orchestrator_GetMetricConfiguration_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 1, 0, 4, 1, 5, 5}, []string{"v1", "orchestrator", "cloud_services", "service_id", "metric_configurations", "metric_id"}, ""))
+
+	pattern_Orchestrator_ListMetricConfigurations_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"v1", "orchestrator", "cloud_services", "service_id", "metric_configurations"}, ""))
 )
 
 var (
@@ -904,4 +1567,18 @@ var (
 	forward_Orchestrator_ListMetrics_0 = runtime.ForwardResponseMessage
 
 	forward_Orchestrator_GetMetric_0 = runtime.ForwardResponseMessage
+
+	forward_Orchestrator_RegisterCloudService_0 = runtime.ForwardResponseMessage
+
+	forward_Orchestrator_UpdateCloudService_0 = runtime.ForwardResponseMessage
+
+	forward_Orchestrator_GetCloudService_0 = runtime.ForwardResponseMessage
+
+	forward_Orchestrator_ListCloudServices_0 = runtime.ForwardResponseMessage
+
+	forward_Orchestrator_RemoveCloudService_0 = runtime.ForwardResponseMessage
+
+	forward_Orchestrator_GetMetricConfiguration_0 = runtime.ForwardResponseMessage
+
+	forward_Orchestrator_ListMetricConfigurations_0 = runtime.ForwardResponseMessage
 )
diff --git a/api/orchestrator/orchestrator_grpc.pb.go b/api/orchestrator/orchestrator_grpc.pb.go
index 536e2d32..4d36d3e8 100644
--- a/api/orchestrator/orchestrator_grpc.pb.go
+++ b/api/orchestrator/orchestrator_grpc.pb.go
@@ -40,6 +40,20 @@ type OrchestratorClient interface {
 	ListMetrics(ctx context.Context, in *ListMetricsRequest, opts ...grpc.CallOption) (*ListMetricsResponse, error)
 	// Returns the metric with the passed metric id
 	GetMetric(ctx context.Context, in *GetMetricsRequest, opts ...grpc.CallOption) (*assessment.Metric, error)
+	// Registers a new target cloud service
+	RegisterCloudService(ctx context.Context, in *RegisterCloudServiceRequest, opts ...grpc.CallOption) (*CloudService, error)
+	// Registers a new target cloud service
+	UpdateCloudService(ctx context.Context, in *UpdateCloudServiceRequest, opts ...grpc.CallOption) (*CloudService, error)
+	// Retrieves a target cloud service
+	GetCloudService(ctx context.Context, in *GetCloudServiceRequest, opts ...grpc.CallOption) (*CloudService, error)
+	// Lists all target cloud services
+	ListCloudServices(ctx context.Context, in *ListCloudServicesRequest, opts ...grpc.CallOption) (*ListCloudServicesResponse, error)
+	// Removes a target cloud service
+	RemoveCloudService(ctx context.Context, in *RemoveCloudServiceRequest, opts ...grpc.CallOption) (*emptypb.Empty, error)
+	// Retrieves a metric configuration for a specific service and metric ID
+	GetMetricConfiguration(ctx context.Context, in *GetMetricConfigurationRequest, opts ...grpc.CallOption) (*assessment.MetricConfiguration, error)
+	// Lists all a metric configurations for a specific service and metric ID
+	ListMetricConfigurations(ctx context.Context, in *ListMetricConfigurationRequest, opts ...grpc.CallOption) (*ListMetricConfigurationResponse, error)
 }
 
 type orchestratorClient struct {
@@ -156,6 +170,69 @@ func (c *orchestratorClient) GetMetric(ctx context.Context, in *GetMetricsReques
 	return out, nil
 }
 
+func (c *orchestratorClient) RegisterCloudService(ctx context.Context, in *RegisterCloudServiceRequest, opts ...grpc.CallOption) (*CloudService, error) {
+	out := new(CloudService)
+	err := c.cc.Invoke(ctx, "/clouditor.Orchestrator/RegisterCloudService", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *orchestratorClient) UpdateCloudService(ctx context.Context, in *UpdateCloudServiceRequest, opts ...grpc.CallOption) (*CloudService, error) {
+	out := new(CloudService)
+	err := c.cc.Invoke(ctx, "/clouditor.Orchestrator/UpdateCloudService", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *orchestratorClient) GetCloudService(ctx context.Context, in *GetCloudServiceRequest, opts ...grpc.CallOption) (*CloudService, error) {
+	out := new(CloudService)
+	err := c.cc.Invoke(ctx, "/clouditor.Orchestrator/GetCloudService", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *orchestratorClient) ListCloudServices(ctx context.Context, in *ListCloudServicesRequest, opts ...grpc.CallOption) (*ListCloudServicesResponse, error) {
+	out := new(ListCloudServicesResponse)
+	err := c.cc.Invoke(ctx, "/clouditor.Orchestrator/ListCloudServices", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *orchestratorClient) RemoveCloudService(ctx context.Context, in *RemoveCloudServiceRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) {
+	out := new(emptypb.Empty)
+	err := c.cc.Invoke(ctx, "/clouditor.Orchestrator/RemoveCloudService", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *orchestratorClient) GetMetricConfiguration(ctx context.Context, in *GetMetricConfigurationRequest, opts ...grpc.CallOption) (*assessment.MetricConfiguration, error) {
+	out := new(assessment.MetricConfiguration)
+	err := c.cc.Invoke(ctx, "/clouditor.Orchestrator/GetMetricConfiguration", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *orchestratorClient) ListMetricConfigurations(ctx context.Context, in *ListMetricConfigurationRequest, opts ...grpc.CallOption) (*ListMetricConfigurationResponse, error) {
+	out := new(ListMetricConfigurationResponse)
+	err := c.cc.Invoke(ctx, "/clouditor.Orchestrator/ListMetricConfigurations", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 // OrchestratorServer is the server API for Orchestrator service.
 // All implementations must embed UnimplementedOrchestratorServer
 // for forward compatibility
@@ -180,6 +257,20 @@ type OrchestratorServer interface {
 	ListMetrics(context.Context, *ListMetricsRequest) (*ListMetricsResponse, error)
 	// Returns the metric with the passed metric id
 	GetMetric(context.Context, *GetMetricsRequest) (*assessment.Metric, error)
+	// Registers a new target cloud service
+	RegisterCloudService(context.Context, *RegisterCloudServiceRequest) (*CloudService, error)
+	// Registers a new target cloud service
+	UpdateCloudService(context.Context, *UpdateCloudServiceRequest) (*CloudService, error)
+	// Retrieves a target cloud service
+	GetCloudService(context.Context, *GetCloudServiceRequest) (*CloudService, error)
+	// Lists all target cloud services
+	ListCloudServices(context.Context, *ListCloudServicesRequest) (*ListCloudServicesResponse, error)
+	// Removes a target cloud service
+	RemoveCloudService(context.Context, *RemoveCloudServiceRequest) (*emptypb.Empty, error)
+	// Retrieves a metric configuration for a specific service and metric ID
+	GetMetricConfiguration(context.Context, *GetMetricConfigurationRequest) (*assessment.MetricConfiguration, error)
+	// Lists all a metric configurations for a specific service and metric ID
+	ListMetricConfigurations(context.Context, *ListMetricConfigurationRequest) (*ListMetricConfigurationResponse, error)
 	mustEmbedUnimplementedOrchestratorServer()
 }
 
@@ -214,6 +305,27 @@ func (UnimplementedOrchestratorServer) ListMetrics(context.Context, *ListMetrics
 func (UnimplementedOrchestratorServer) GetMetric(context.Context, *GetMetricsRequest) (*assessment.Metric, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method GetMetric not implemented")
 }
+func (UnimplementedOrchestratorServer) RegisterCloudService(context.Context, *RegisterCloudServiceRequest) (*CloudService, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RegisterCloudService not implemented")
+}
+func (UnimplementedOrchestratorServer) UpdateCloudService(context.Context, *UpdateCloudServiceRequest) (*CloudService, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateCloudService not implemented")
+}
+func (UnimplementedOrchestratorServer) GetCloudService(context.Context, *GetCloudServiceRequest) (*CloudService, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetCloudService not implemented")
+}
+func (UnimplementedOrchestratorServer) ListCloudServices(context.Context, *ListCloudServicesRequest) (*ListCloudServicesResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListCloudServices not implemented")
+}
+func (UnimplementedOrchestratorServer) RemoveCloudService(context.Context, *RemoveCloudServiceRequest) (*emptypb.Empty, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method RemoveCloudService not implemented")
+}
+func (UnimplementedOrchestratorServer) GetMetricConfiguration(context.Context, *GetMetricConfigurationRequest) (*assessment.MetricConfiguration, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetMetricConfiguration not implemented")
+}
+func (UnimplementedOrchestratorServer) ListMetricConfigurations(context.Context, *ListMetricConfigurationRequest) (*ListMetricConfigurationResponse, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method ListMetricConfigurations not implemented")
+}
 func (UnimplementedOrchestratorServer) mustEmbedUnimplementedOrchestratorServer() {}
 
 // UnsafeOrchestratorServer may be embedded to opt out of forward compatibility for this service.
@@ -397,6 +509,132 @@ func _Orchestrator_GetMetric_Handler(srv interface{}, ctx context.Context, dec f
 	return interceptor(ctx, in, info, handler)
 }
 
+func _Orchestrator_RegisterCloudService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(RegisterCloudServiceRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OrchestratorServer).RegisterCloudService(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/clouditor.Orchestrator/RegisterCloudService",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OrchestratorServer).RegisterCloudService(ctx, req.(*RegisterCloudServiceRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Orchestrator_UpdateCloudService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UpdateCloudServiceRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OrchestratorServer).UpdateCloudService(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/clouditor.Orchestrator/UpdateCloudService",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OrchestratorServer).UpdateCloudService(ctx, req.(*UpdateCloudServiceRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Orchestrator_GetCloudService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetCloudServiceRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OrchestratorServer).GetCloudService(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/clouditor.Orchestrator/GetCloudService",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OrchestratorServer).GetCloudService(ctx, req.(*GetCloudServiceRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Orchestrator_ListCloudServices_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListCloudServicesRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OrchestratorServer).ListCloudServices(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/clouditor.Orchestrator/ListCloudServices",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OrchestratorServer).ListCloudServices(ctx, req.(*ListCloudServicesRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Orchestrator_RemoveCloudService_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(RemoveCloudServiceRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OrchestratorServer).RemoveCloudService(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/clouditor.Orchestrator/RemoveCloudService",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OrchestratorServer).RemoveCloudService(ctx, req.(*RemoveCloudServiceRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Orchestrator_GetMetricConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(GetMetricConfigurationRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OrchestratorServer).GetMetricConfiguration(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/clouditor.Orchestrator/GetMetricConfiguration",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OrchestratorServer).GetMetricConfiguration(ctx, req.(*GetMetricConfigurationRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Orchestrator_ListMetricConfigurations_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(ListMetricConfigurationRequest)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(OrchestratorServer).ListMetricConfigurations(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/clouditor.Orchestrator/ListMetricConfigurations",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(OrchestratorServer).ListMetricConfigurations(ctx, req.(*ListMetricConfigurationRequest))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 // Orchestrator_ServiceDesc is the grpc.ServiceDesc for Orchestrator service.
 // It's only intended for direct use with grpc.RegisterService,
 // and not to be introspected or modified (even as a copy)
@@ -436,6 +674,34 @@ var Orchestrator_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "GetMetric",
 			Handler:    _Orchestrator_GetMetric_Handler,
 		},
+		{
+			MethodName: "RegisterCloudService",
+			Handler:    _Orchestrator_RegisterCloudService_Handler,
+		},
+		{
+			MethodName: "UpdateCloudService",
+			Handler:    _Orchestrator_UpdateCloudService_Handler,
+		},
+		{
+			MethodName: "GetCloudService",
+			Handler:    _Orchestrator_GetCloudService_Handler,
+		},
+		{
+			MethodName: "ListCloudServices",
+			Handler:    _Orchestrator_ListCloudServices_Handler,
+		},
+		{
+			MethodName: "RemoveCloudService",
+			Handler:    _Orchestrator_RemoveCloudService_Handler,
+		},
+		{
+			MethodName: "GetMetricConfiguration",
+			Handler:    _Orchestrator_GetMetricConfiguration_Handler,
+		},
+		{
+			MethodName: "ListMetricConfigurations",
+			Handler:    _Orchestrator_ListMetricConfigurations_Handler,
+		},
 	},
 	Streams: []grpc.StreamDesc{
 		{
diff --git a/cli/commands/cloud/cloud.go b/cli/commands/cloud/cloud.go
new file mode 100644
index 00000000..39c1a6b7
--- /dev/null
+++ b/cli/commands/cloud/cloud.go
@@ -0,0 +1,285 @@
+// Copyright 2021 Fraunhofer AISEC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//           $$\                           $$\ $$\   $$\
+//           $$ |                          $$ |\__|  $$ |
+//  $$$$$$$\ $$ | $$$$$$\  $$\   $$\  $$$$$$$ |$$\ $$$$$$\    $$$$$$\   $$$$$$\
+// $$  _____|$$ |$$  __$$\ $$ |  $$ |$$  __$$ |$$ |\_$$  _|  $$  __$$\ $$  __$$\
+// $$ /      $$ |$$ /  $$ |$$ |  $$ |$$ /  $$ |$$ |  $$ |    $$ /  $$ |$$ | \__|
+// $$ |      $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$\ $$ |  $$ |$$ |
+// \$$$$$$\  $$ |\$$$$$   |\$$$$$   |\$$$$$$  |$$ |  \$$$   |\$$$$$   |$$ |
+//  \_______|\__| \______/  \______/  \_______|\__|   \____/  \______/ \__|
+//
+// This file is part of Clouditor Community Edition.
+
+package cloud
+
+import (
+	"context"
+	"fmt"
+
+	"clouditor.io/clouditor/api/assessment"
+	"clouditor.io/clouditor/api/orchestrator"
+	"clouditor.io/clouditor/cli"
+	"github.com/spf13/cobra"
+	"github.com/spf13/viper"
+	"google.golang.org/protobuf/types/known/emptypb"
+)
+
+// NewRegisterCloudServiceCommand returns a cobra command for the `discover` subcommand
+func NewRegisterCloudServiceCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "register [name]",
+		Short: "Registers a new target cloud service",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var (
+				err     error
+				session *cli.Session
+				client  orchestrator.OrchestratorClient
+				res     *orchestrator.CloudService
+			)
+
+			if session, err = cli.ContinueSession(); err != nil {
+				fmt.Printf("Error while retrieving the session. Please re-authenticate.\n")
+				return nil
+			}
+
+			client = orchestrator.NewOrchestratorClient(session)
+
+			name := args[0]
+
+			res, err = client.RegisterCloudService(context.Background(), &orchestrator.RegisterCloudServiceRequest{
+				Service: &orchestrator.CloudService{
+					Name: name,
+				},
+			})
+
+			return session.HandleResponse(res, err)
+		},
+		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+			return []string{"aws", "azure"}, cobra.ShellCompDirectiveNoFileComp
+		},
+	}
+
+	return cmd
+}
+
+// NewListCloudServicesCommand returns a cobra command for the `list` subcommand
+func NewListCloudServicesCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "list",
+		Short: "Lists all target cloud services",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var (
+				err     error
+				session *cli.Session
+				client  orchestrator.OrchestratorClient
+				res     *orchestrator.ListCloudServicesResponse
+			)
+
+			if session, err = cli.ContinueSession(); err != nil {
+				fmt.Printf("Error while retrieving the session. Please re-authenticate.\n")
+				return nil
+			}
+
+			client = orchestrator.NewOrchestratorClient(session)
+
+			res, err = client.ListCloudServices(context.Background(), &orchestrator.ListCloudServicesRequest{})
+
+			return session.HandleResponse(res, err)
+		},
+		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+			return []string{}, cobra.ShellCompDirectiveNoFileComp
+		},
+	}
+
+	return cmd
+}
+
+// NewGetCloudServiceComand returns a cobra command for the `get` subcommand
+func NewGetCloudServiceComand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "get [id]",
+		Short: "Retrieves a target cloud service by its ID",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var (
+				err     error
+				session *cli.Session
+				client  orchestrator.OrchestratorClient
+				res     *orchestrator.CloudService
+			)
+
+			if session, err = cli.ContinueSession(); err != nil {
+				fmt.Printf("Error while retrieving the session. Please re-authenticate.\n")
+				return nil
+			}
+
+			client = orchestrator.NewOrchestratorClient(session)
+
+			serviceID := args[0]
+
+			res, err = client.GetCloudService(context.Background(), &orchestrator.GetCloudServiceRequest{ServiceId: serviceID})
+
+			return session.HandleResponse(res, err)
+		},
+		ValidArgsFunction: cli.DefaultArgsShellComp,
+	}
+
+	return cmd
+}
+
+// NewRemoveCloudServiceComand returns a cobra command for the `get` subcommand
+func NewRemoveCloudServiceComand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "remove [id]",
+		Short: "Removes a target cloud service by its ID",
+		Args:  cobra.ExactArgs(1),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var (
+				err     error
+				session *cli.Session
+				client  orchestrator.OrchestratorClient
+				res     *emptypb.Empty
+			)
+
+			if session, err = cli.ContinueSession(); err != nil {
+				fmt.Printf("Error while retrieving the session. Please re-authenticate.\n")
+				return nil
+			}
+
+			client = orchestrator.NewOrchestratorClient(session)
+
+			serviceID := args[0]
+
+			res, err = client.RemoveCloudService(context.Background(), &orchestrator.RemoveCloudServiceRequest{ServiceId: serviceID})
+
+			return session.HandleResponse(res, err)
+		},
+		ValidArgsFunction: cli.DefaultArgsShellComp,
+	}
+
+	return cmd
+}
+
+// NewUpdateCloudServiceCommand returns a cobra command for the `update` subcommand
+func NewUpdateCloudServiceCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "update",
+		Short: "Updates a target cloud service",
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var (
+				err     error
+				session *cli.Session
+				client  orchestrator.OrchestratorClient
+				res     *orchestrator.CloudService
+			)
+
+			if session, err = cli.ContinueSession(); err != nil {
+				fmt.Printf("Error while retrieving the session. Please re-authenticate.\n")
+				return nil
+			}
+
+			client = orchestrator.NewOrchestratorClient(session)
+
+			res, err = client.UpdateCloudService(context.Background(), &orchestrator.UpdateCloudServiceRequest{
+				ServiceId: viper.GetString("id"),
+				Service: &orchestrator.CloudService{
+					Name:        viper.GetString("name"),
+					Description: viper.GetString("description"),
+				},
+			})
+
+			return session.HandleResponse(res, err)
+		},
+		ValidArgsFunction: cli.ValidArgsGetCloudServices,
+	}
+
+	cmd.PersistentFlags().String("id", "", "the cloud service id to update")
+	cmd.PersistentFlags().StringP("name", "n", "", "the name of the service")
+	cmd.PersistentFlags().StringP("description", "d", "", "an optional description")
+	_ = cmd.MarkPersistentFlagRequired("id")
+	_ = cmd.MarkPersistentFlagRequired("name")
+	_ = viper.BindPFlag("id", cmd.PersistentFlags().Lookup("id"))
+	_ = viper.BindPFlag("name", cmd.PersistentFlags().Lookup("name"))
+	_ = viper.BindPFlag("description", cmd.PersistentFlags().Lookup("description"))
+
+	_ = cmd.RegisterFlagCompletionFunc("id", cli.ValidArgsGetCloudServices)
+	_ = cmd.RegisterFlagCompletionFunc("name", cli.DefaultArgsShellComp)
+	_ = cmd.RegisterFlagCompletionFunc("description", cli.DefaultArgsShellComp)
+
+	return cmd
+}
+
+// NewGetMetricConfigurationCommand returns a cobra command for the `get-metric-configuration` subcommand
+// TODO(oxisto): Can we have something like cl cloud get <id> metric-configuration <id>?
+func NewGetMetricConfigurationCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "get-metric-configuration",
+		Short: "Retrieves a metric configuration for a specific target service",
+		Args:  cobra.ExactArgs(2),
+		RunE: func(cmd *cobra.Command, args []string) error {
+			var (
+				err     error
+				session *cli.Session
+				client  orchestrator.OrchestratorClient
+				res     *assessment.MetricConfiguration
+			)
+
+			if session, err = cli.ContinueSession(); err != nil {
+				fmt.Printf("Error while retrieving the session. Please re-authenticate.\n")
+				return nil
+			}
+
+			client = orchestrator.NewOrchestratorClient(session)
+
+			serviceID := args[0]
+			metricID := args[1]
+
+			res, err = client.GetMetricConfiguration(context.Background(), &orchestrator.GetMetricConfigurationRequest{ServiceId: serviceID, MetricId: metricID})
+
+			return session.HandleResponse(res, err)
+		},
+		ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+			return []string{}, cobra.ShellCompDirectiveNoFileComp
+		},
+	}
+
+	return cmd
+}
+
+// NewCloudCommand returns a cobra command for `cloud` subcommands
+func NewCloudCommand() *cobra.Command {
+	cmd := &cobra.Command{
+		Use:   "cloud",
+		Short: "Target cloud services commands",
+	}
+
+	AddCommands(cmd)
+
+	return cmd
+}
+
+// AddCommands adds all subcommands
+func AddCommands(cmd *cobra.Command) {
+	cmd.AddCommand(
+		NewRegisterCloudServiceCommand(),
+		NewListCloudServicesCommand(),
+		NewGetCloudServiceComand(),
+		NewUpdateCloudServiceCommand(),
+		NewRemoveCloudServiceComand(),
+		NewGetMetricConfigurationCommand(),
+	)
+}
diff --git a/cli/commands/commands.go b/cli/commands/commands.go
index b9c9cf50..e67b85e1 100644
--- a/cli/commands/commands.go
+++ b/cli/commands/commands.go
@@ -28,6 +28,7 @@ package commands
 import (
 	"clouditor.io/clouditor/cli"
 	"clouditor.io/clouditor/cli/commands/assessment"
+	"clouditor.io/clouditor/cli/commands/cloud"
 	"clouditor.io/clouditor/cli/commands/completion"
 	"clouditor.io/clouditor/cli/commands/discovery"
 	"clouditor.io/clouditor/cli/commands/login"
@@ -46,6 +47,7 @@ func AddCommands(cmd *cobra.Command) {
 		tool.NewToolCommand(),
 		assessment.NewAssessmentCommand(),
 		completion.NewCompletionCommand(),
+		cloud.NewCloudCommand(),
 	)
 
 	cmd.PersistentFlags().StringP("session-directory", "s", cli.DefaultSessionFolder, "the directory where the session will be saved and loaded from")
diff --git a/cli/commands/tool/tool.go b/cli/commands/tool/tool.go
index b534c938..c430a946 100644
--- a/cli/commands/tool/tool.go
+++ b/cli/commands/tool/tool.go
@@ -113,7 +113,7 @@ func NewShowToolCommand() *cobra.Command {
 func NewRegisterToolCommand() *cobra.Command {
 	cmd := &cobra.Command{
 		Use:   "register",
-		Short: "Registeres a new assessment tool",
+		Short: "Registers a new assessment tool",
 		RunE: func(cmd *cobra.Command, args []string) error {
 			var (
 				err     error
diff --git a/cli/session.go b/cli/session.go
index 139da6ff..53c4126c 100644
--- a/cli/session.go
+++ b/cli/session.go
@@ -218,7 +218,7 @@ func DefaultArgsShellComp(cmd *cobra.Command, args []string, toComplete string)
 	return []string{}, cobra.ShellCompDirectiveNoFileComp
 }
 
-func ValidArgsGetTools(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+func ValidArgsGetTools(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
 	if len(args) != 0 {
 		return nil, cobra.ShellCompDirectiveNoFileComp
 	}
@@ -226,7 +226,7 @@ func ValidArgsGetTools(cmd *cobra.Command, args []string, toComplete string) ([]
 	return getTools(toComplete), cobra.ShellCompDirectiveNoFileComp
 }
 
-func ValidArgsGetMetrics(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+func ValidArgsGetMetrics(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
 	if len(args) != 0 {
 		return nil, cobra.ShellCompDirectiveNoFileComp
 	}
@@ -234,7 +234,15 @@ func ValidArgsGetMetrics(cmd *cobra.Command, args []string, toComplete string) (
 	return getMetrics(toComplete), cobra.ShellCompDirectiveNoFileComp
 }
 
-func getTools(toComplete string) []string {
+func ValidArgsGetCloudServices(_ *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
+	if len(args) != 0 {
+		return nil, cobra.ShellCompDirectiveNoFileComp
+	}
+
+	return getCloudServices(toComplete), cobra.ShellCompDirectiveNoFileComp
+}
+
+func getTools(_ string) []string {
 	var (
 		err     error
 		session *Session
@@ -261,7 +269,8 @@ func getTools(toComplete string) []string {
 	return tools
 }
 
-func getMetrics(toComplete string) []string {
+// TODO(oxisto): This could be an interesting use case for 1.18 Go generics
+func getMetrics(_ string) []string {
 	var (
 		err     error
 		session *Session
@@ -287,3 +296,30 @@ func getMetrics(toComplete string) []string {
 
 	return metrics
 }
+
+func getCloudServices(_ string) []string {
+	var (
+		err     error
+		session *Session
+		client  orchestrator.OrchestratorClient
+		res     *orchestrator.ListCloudServicesResponse
+	)
+
+	if session, err = ContinueSession(); err != nil {
+		fmt.Printf("Error while retrieving the session. Please re-authenticate.\n")
+		return nil
+	}
+
+	client = orchestrator.NewOrchestratorClient(session)
+
+	if res, err = client.ListCloudServices(context.Background(), &orchestrator.ListCloudServicesRequest{}); err != nil {
+		return []string{}
+	}
+
+	var metrics []string
+	for _, v := range res.Services {
+		metrics = append(metrics, fmt.Sprintf("%s\t%s: %s", v.Id, v.Name, v.Description))
+	}
+
+	return metrics
+}
diff --git a/clouditor.code-workspace b/clouditor.code-workspace
index fa015314..c2e233d6 100644
--- a/clouditor.code-workspace
+++ b/clouditor.code-workspace
@@ -6,10 +6,12 @@
 	],
 	"settings": {
 		"cSpell.words": [
+			"AISEC",
 			"clouditor",
 			"Debugf",
 			"emptypb",
 			"garuppel",
+			"gocron",
 			"grpc",
 			"Infof",
 			"Kubernetes",
@@ -17,6 +19,7 @@
 			"oxisto",
 			"protobuf",
 			"Rego",
+			"stretchr",
 			"structpb",
 			"timestamppb",
 			"Warnf"
@@ -30,6 +33,7 @@
 				"--proto_path=${workspaceRoot}/third_party",
 				"--proto_path=${env.GOPATH}/src"
 			]
-		}
+		},
+		"go.coverOnSave": true
 	}
 }
\ No newline at end of file
diff --git a/cmd/engine/engine.go b/cmd/engine/engine.go
index 93f91ba3..757eb6dd 100644
--- a/cmd/engine/engine.go
+++ b/cmd/engine/engine.go
@@ -72,18 +72,20 @@ const (
 	DBNameFlag             = "db-name"
 	DBPortFlag             = "db-port"
 	DBInMemoryFlag         = "db-in-memory"
-
-	DefaultAPIDefaultUser     = "clouditor"
-	DefaultAPIDefaultPassword = "clouditor"
-	DefaultAPISecret          = "changeme"
-	DefaultAPIgRPCPort        = 9090
-	DefaultAPIHTTPPort        = 8080
-	DefaultDBUserName         = "postgres"
-	DefaultDBPassword         = "postgres"
-	DefaultDBHost             = "localhost"
-	DefaultDBName             = "postgres"
-	DefaultDBPort             = 5432
-	DefaultDBInMemory         = false
+	CreateDefaultTarget    = "target-default-create"
+
+	DefaultAPIDefaultUser      = "clouditor"
+	DefaultAPIDefaultPassword  = "clouditor"
+	DefaultAPISecret           = "changeme"
+	DefaultAPIgRPCPort         = 9090
+	DefaultAPIHTTPPort         = 8080
+	DefaultDBUserName          = "postgres"
+	DefaultDBPassword          = "postgres"
+	DefaultDBHost              = "localhost"
+	DefaultDBName              = "postgres"
+	DefaultDBPort              = 5432
+	DefaultDBInMemory          = false
+	DefaultCreateDefaultTarget = true
 
 	EnvPrefix = "CLOUDITOR"
 )
@@ -91,7 +93,7 @@ const (
 var server *grpc.Server
 var authService *service_auth.Service
 var discoveryService *service_discovery.Service
-var orchestratorService orchestrator.OrchestratorServer
+var orchestratorService *service_orchestrator.Service
 var assessmentService assessment.AssessmentServer
 var evidenceStoreService evidence.EvidenceStoreServer
 
@@ -120,6 +122,7 @@ func init() {
 	engineCmd.Flags().String(DBNameFlag, DefaultDBName, "Provides name of database")
 	engineCmd.Flags().Int16(DBPortFlag, DefaultDBPort, "Provides port for database")
 	engineCmd.Flags().Bool(DBInMemoryFlag, DefaultDBInMemory, "Uses an in-memory database which is not persisted at all")
+	engineCmd.Flags().Bool(CreateDefaultTarget, DefaultCreateDefaultTarget, "Creates a default target cloud service if it does not exist")
 
 	_ = viper.BindPFlag(APIDefaultUserFlag, engineCmd.Flags().Lookup(APIDefaultUserFlag))
 	_ = viper.BindPFlag(APIDefaultPasswordFlag, engineCmd.Flags().Lookup(APIDefaultPasswordFlag))
@@ -132,6 +135,7 @@ func init() {
 	_ = viper.BindPFlag(DBNameFlag, engineCmd.Flags().Lookup(DBNameFlag))
 	_ = viper.BindPFlag(DBPortFlag, engineCmd.Flags().Lookup(DBPortFlag))
 	_ = viper.BindPFlag(DBInMemoryFlag, engineCmd.Flags().Lookup(DBInMemoryFlag))
+	_ = viper.BindPFlag(CreateDefaultTarget, engineCmd.Flags().Lookup(CreateDefaultTarget))
 }
 
 func initConfig() {
@@ -170,12 +174,19 @@ func doCmd(_ *cobra.Command, _ []string) (err error) {
 	}
 
 	discoveryService = service_discovery.NewService()
-	orchestratorService = &service_orchestrator.Service{}
+	orchestratorService = service_orchestrator.NewService()
 	assessmentService = service_assessment.NewService()
 	evidenceStoreService = service_evidenceStore.NewService()
 
 	authService.CreateDefaultUser(viper.GetString(APIDefaultUserFlag), viper.GetString(APIDefaultPasswordFlag))
 
+	if viper.GetBool(CreateDefaultTarget) {
+		_, err := orchestratorService.CreateDefaultTargetCloudService()
+		if err != nil {
+			log.Errorf("could not register default target cloud service: %v", err)
+		}
+	}
+
 	grpcPort := viper.GetInt(APIgRPCPortFlag)
 	httpPort := viper.GetInt(APIHTTPPortFlag)
 
diff --git a/openapi/assessment/openapi.yaml b/openapi/assessment/openapi.yaml
index abd990e2..d332ca88 100644
--- a/openapi/assessment/openapi.yaml
+++ b/openapi/assessment/openapi.yaml
@@ -54,12 +54,17 @@ components:
                         $ref: '#/components/schemas/Value'
                     description: Repeated field of dynamically typed values.
             description: '`ListValue` is a wrapper around a repeated field of values. The JSON representation for `ListValue` is JSON array.'
-        MetricData:
+        MetricConfiguration:
             properties:
-                target_value:
-                    $ref: '#/components/schemas/Value'
                 operator:
                     type: string
+                    description: The operator to compare the metric, such as == or >
+                target_value:
+                    $ref: '#/components/schemas/Value'
+                is_default:
+                    type: boolean
+                    description: Whether this configuration is a default configuration
+            description: Defines the operator and a target value for an individual metric
         Result:
             properties:
                 id:
@@ -73,7 +78,7 @@ components:
                     type: string
                     description: Reference to the metric the assessment was based on
                 metric_data:
-                    $ref: '#/components/schemas/MetricData'
+                    $ref: '#/components/schemas/MetricConfiguration'
                 compliant:
                     type: boolean
                     description: 'Compliant case: true or false'
diff --git a/openapi/orchestrator/openapi.yaml b/openapi/orchestrator/openapi.yaml
index b765255c..5525ae5a 100644
--- a/openapi/orchestrator/openapi.yaml
+++ b/openapi/orchestrator/openapi.yaml
@@ -106,6 +106,118 @@ paths:
                 "200":
                     description: OK
                     content: {}
+    /v1/orchestrator/cloud_services:
+        get:
+            summary: Lists all target cloud services
+            operationId: Orchestrator_ListCloudServices
+            responses:
+                "200":
+                    description: OK
+                    content:
+                        application/json:
+                            schema:
+                                $ref: '#/components/schemas/ListCloudServicesResponse'
+        post:
+            summary: Registers a new target cloud service
+            operationId: Orchestrator_RegisterCloudService
+            requestBody:
+                content:
+                    application/json:
+                        schema:
+                            $ref: '#/components/schemas/CloudService'
+                required: true
+            responses:
+                "200":
+                    description: OK
+                    content:
+                        application/json:
+                            schema:
+                                $ref: '#/components/schemas/CloudService'
+    /v1/orchestrator/cloud_services/{service_id}:
+        get:
+            summary: Retrieves a target cloud service
+            operationId: Orchestrator_GetCloudService
+            parameters:
+                - name: service_id
+                  in: query
+                  schema:
+                    type: string
+            responses:
+                "200":
+                    description: OK
+                    content:
+                        application/json:
+                            schema:
+                                $ref: '#/components/schemas/CloudService'
+        put:
+            summary: Registers a new target cloud service
+            operationId: Orchestrator_UpdateCloudService
+            parameters:
+                - name: service_id
+                  in: query
+                  schema:
+                    type: string
+            requestBody:
+                content:
+                    application/json:
+                        schema:
+                            $ref: '#/components/schemas/CloudService'
+                required: true
+            responses:
+                "200":
+                    description: OK
+                    content:
+                        application/json:
+                            schema:
+                                $ref: '#/components/schemas/CloudService'
+        delete:
+            summary: Removes a target cloud service
+            operationId: Orchestrator_RemoveCloudService
+            parameters:
+                - name: service_id
+                  in: query
+                  schema:
+                    type: string
+            responses:
+                "200":
+                    description: OK
+                    content: {}
+    /v1/orchestrator/cloud_services/{service_id}/metric_configurations:
+        get:
+            summary: Lists all a metric configurations for a specific service and metric ID
+            operationId: Orchestrator_ListMetricConfigurations
+            parameters:
+                - name: service_id
+                  in: query
+                  schema:
+                    type: string
+            responses:
+                "200":
+                    description: OK
+                    content:
+                        application/json:
+                            schema:
+                                $ref: '#/components/schemas/ListMetricConfigurationResponse'
+    /v1/orchestrator/cloud_services/{service_id}/metric_configurations/{metric_id}:
+        get:
+            summary: Retrieves a metric configuration for a specific service and metric ID
+            operationId: Orchestrator_GetMetricConfiguration
+            parameters:
+                - name: service_id
+                  in: query
+                  schema:
+                    type: string
+                - name: metric_id
+                  in: query
+                  schema:
+                    type: string
+            responses:
+                "200":
+                    description: OK
+                    content:
+                        application/json:
+                            schema:
+                                $ref: '#/components/schemas/MetricConfiguration'
     /v1/orchestrator/metrics:
         get:
             summary: List all metrics provided by the metric catalog
@@ -171,12 +283,30 @@ components:
                         type: string
                     description: a list of metrics that this tool can assess, referred by their ids
             description: Represents an external tool or service that offers assessments according to certain metrics
+        CloudService:
+            properties:
+                id:
+                    type: string
+                name:
+                    type: string
+                description:
+                    type: string
         ListAssessmentToolsResponse:
             properties:
                 tools:
                     type: array
                     items:
                         $ref: '#/components/schemas/AssessmentTool'
+        ListCloudServicesResponse:
+            properties:
+                services:
+                    type: array
+                    items:
+                        $ref: '#/components/schemas/CloudService'
+        ListMetricConfigurationResponse:
+            properties:
+                configurations:
+                    $ref: '#/components/schemas/ConfigurationsEntry'
         ListMetricsResponse:
             properties:
                 metrics:
@@ -212,6 +342,17 @@ components:
                 range:
                     $ref: '#/components/schemas/Range'
             description: A metric resource
+        MetricConfiguration:
+            properties:
+                operator:
+                    type: string
+                    description: The operator to compare the metric, such as == or >
+                target_value:
+                    $ref: '#/components/schemas/Value'
+                is_default:
+                    type: boolean
+                    description: Whether this configuration is a default configuration
+            description: Defines the operator and a target value for an individual metric
         MinMax:
             properties:
                 min:
diff --git a/persistence/db.go b/persistence/db.go
index 76bea382..30246efb 100644
--- a/persistence/db.go
+++ b/persistence/db.go
@@ -29,6 +29,7 @@ import (
 	"fmt"
 
 	"clouditor.io/clouditor/api/auth"
+	"clouditor.io/clouditor/api/orchestrator"
 	"github.com/sirupsen/logrus"
 	"gorm.io/driver/postgres"
 	"gorm.io/driver/sqlite"
@@ -61,6 +62,10 @@ func InitDB(inMemory bool, host string, port int16) (err error) {
 		return fmt.Errorf("error during auto-migration: %w", err)
 	}
 
+	if err = db.AutoMigrate(&orchestrator.CloudService{}); err != nil {
+		return fmt.Errorf("error during auto-migration: %w", err)
+	}
+
 	return nil
 }
 
diff --git a/proto/assessment.proto b/proto/assessment.proto
index 3aefcc22..c3002ac5 100644
--- a/proto/assessment.proto
+++ b/proto/assessment.proto
@@ -30,9 +30,9 @@ package clouditor;
 
 import "google/api/annotations.proto";
 import "google/protobuf/empty.proto";
-import "google/protobuf/struct.proto";
 import "google/protobuf/timestamp.proto";
 import "evidence.proto";
+import "metric.proto";
 
 option go_package = "api/assessment";
 
@@ -90,7 +90,7 @@ message Result {
   string metric_id = 3;
 
   // Data corresponding to the metric by the given metric id
-  MetricData metric_data = 4;
+  MetricConfiguration metric_data = 4;
 
   // Compliant case: true or false
   bool compliant = 5;
@@ -104,9 +104,3 @@ message Result {
   // Some comments on the reason for non-compliance
   string non_compliance_comments = 8;
 }
-
-message MetricData {
-  google.protobuf.Value target_value =
-      1;               // target value, e.g. string, number, array, ...
-  string operator = 2; // the operator, e.g. "=="
-}
\ No newline at end of file
diff --git a/proto/metric.proto b/proto/metric.proto
index 5a35c57d..f5f07633 100644
--- a/proto/metric.proto
+++ b/proto/metric.proto
@@ -91,3 +91,15 @@ message AllowedValues { repeated google.protobuf.Value values = 1; }
 // Defines a range of values in a pre-defined order from the lowest to the
 // highest.
 message Order { repeated google.protobuf.Value values = 1; }
+
+// Defines the operator and a target value for an individual metric
+message MetricConfiguration {
+  // The operator to compare the metric, such as == or >
+  string operator = 1;
+
+  // The target value
+  google.protobuf.Value target_value = 2;
+
+  // Whether this configuration is a default configuration
+  bool is_default = 3;
+}
\ No newline at end of file
diff --git a/proto/orchestrator.proto b/proto/orchestrator.proto
index 101e004c..9361827f 100644
--- a/proto/orchestrator.proto
+++ b/proto/orchestrator.proto
@@ -106,6 +106,63 @@ service Orchestrator {
       get : "/v1/orchestrator/metrics/{metric_id}"
     };
   }
+
+  // Registers a new target cloud service
+  rpc RegisterCloudService(RegisterCloudServiceRequest) returns (CloudService) {
+    option (google.api.http) = {
+      post : "/v1/orchestrator/cloud_services"
+      body : "service"
+    };
+  }
+
+  // Registers a new target cloud service
+  rpc UpdateCloudService(UpdateCloudServiceRequest) returns (CloudService) {
+    option (google.api.http) = {
+      put : "/v1/orchestrator/cloud_services/{service_id}"
+      body : "service"
+    };
+  }
+
+  // Retrieves a target cloud service
+  rpc GetCloudService(GetCloudServiceRequest) returns (CloudService) {
+    option (google.api.http) = {
+      get : "/v1/orchestrator/cloud_services/{service_id}"
+    };
+  }
+
+  // Lists all target cloud services
+  rpc ListCloudServices(ListCloudServicesRequest)
+      returns (ListCloudServicesResponse) {
+    option (google.api.http) = {
+      get : "/v1/orchestrator/cloud_services"
+    };
+  }
+
+  // Removes a target cloud service
+  rpc RemoveCloudService(RemoveCloudServiceRequest)
+      returns (google.protobuf.Empty) {
+    option (google.api.http) = {
+      delete : "/v1/orchestrator/cloud_services/{service_id}"
+    };
+  }
+
+  // Retrieves a metric configuration for a specific service and metric ID
+  rpc GetMetricConfiguration(GetMetricConfigurationRequest)
+      returns (MetricConfiguration) {
+    option (google.api.http) = {
+      get : "/v1/orchestrator/cloud_services/{service_id}/"
+            "metric_configurations/"
+            "{metric_id}"
+    };
+  }
+
+  // Lists all a metric configurations for a specific service and metric ID
+  rpc ListMetricConfigurations(ListMetricConfigurationRequest)
+      returns (ListMetricConfigurationResponse) {
+    option (google.api.http) = {
+      get : "/v1/orchestrator/cloud_services/{service_id}/metric_configurations"
+    };
+  }
 }
 
 message RegisterAssessmentToolRequest { AssessmentTool tool = 1; }
@@ -134,6 +191,33 @@ message GetMetricsRequest { string metric_id = 1; }
 message ListMetricsRequest {}
 message ListMetricsResponse { repeated Metric metrics = 1; }
 
+message GetCloudServiceRequest { string service_id = 1; }
+
+message RegisterCloudServiceRequest { CloudService service = 1; }
+
+message UpdateCloudServiceRequest {
+  string service_id = 1;
+  CloudService service = 2;
+}
+
+message RemoveCloudServiceRequest { string service_id = 1; }
+
+message ListCloudServicesRequest {}
+message ListCloudServicesResponse { repeated CloudService services = 1; }
+
+message GetMetricConfigurationRequest {
+  string service_id = 1;
+
+  string metric_id = 2;
+}
+
+message ListMetricConfigurationRequest { string service_id = 1; }
+
+message ListMetricConfigurationResponse {
+  // A map of metric configurations associated by their metric ID
+  map<string, MetricConfiguration> configurations = 1;
+}
+
 // Represents an external tool or service that offers assessments according to
 // certain metrics
 message AssessmentTool {
@@ -165,3 +249,11 @@ message AssessmentResult {
     NON_COMPLIANT = 1;
   }
 }
+
+message CloudService {
+  string id = 1;
+
+  string name = 2;
+
+  string description = 3;
+}
\ No newline at end of file
diff --git a/service/assessment/assessment.go b/service/assessment/assessment.go
index 379b773b..3a3993ad 100644
--- a/service/assessment/assessment.go
+++ b/service/assessment/assessment.go
@@ -135,7 +135,7 @@ func (s Service) handleEvidence(evidence *evidence.Evidence) error {
 			Id:        uuid.NewString(),
 			Timestamp: timestamppb.Now(),
 			MetricId:  metricId,
-			MetricData: &assessment.MetricData{
+			MetricData: &assessment.MetricConfiguration{
 				TargetValue: targetValue,
 				Operator:    operator,
 			},
diff --git a/service/auth/auth.go b/service/auth/auth.go
index 2f5d8490..5959f35e 100644
--- a/service/auth/auth.go
+++ b/service/auth/auth.go
@@ -192,11 +192,6 @@ func StartDedicatedAuthServer(address string) (sock net.Listener, server *grpc.S
 		return nil, nil, fmt.Errorf("could not listen: %w", err)
 	}
 
-	err = persistence.InitDB(true, "", 0)
-
-	if err != nil {
-		return nil, nil, fmt.Errorf("could not initialize in-memory DB: %w", err)
-	}
 
 	authService = &Service{}
 	authService.CreateDefaultUser("clouditor", "clouditor")
diff --git a/service/orchestrator/cloud_service.go b/service/orchestrator/cloud_service.go
new file mode 100644
index 00000000..6215ae0d
--- /dev/null
+++ b/service/orchestrator/cloud_service.go
@@ -0,0 +1,165 @@
+// Copyright 2021 Fraunhofer AISEC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//           $$\                           $$\ $$\   $$\
+//           $$ |                          $$ |\__|  $$ |
+//  $$$$$$$\ $$ | $$$$$$\  $$\   $$\  $$$$$$$ |$$\ $$$$$$\    $$$$$$\   $$$$$$\
+// $$  _____|$$ |$$  __$$\ $$ |  $$ |$$  __$$ |$$ |\_$$  _|  $$  __$$\ $$  __$$\
+// $$ /      $$ |$$ /  $$ |$$ |  $$ |$$ /  $$ |$$ |  $$ |    $$ /  $$ |$$ | \__|
+// $$ |      $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$\ $$ |  $$ |$$ |
+// \$$$$$$\  $$ |\$$$$$   |\$$$$$   |\$$$$$$  |$$ |  \$$$   |\$$$$$   |$$ |
+//  \_______|\__| \______/  \______/  \_______|\__|   \____/  \______/ \__|
+//
+// This file is part of Clouditor Community Edition.
+
+package orchestrator
+
+import (
+	"context"
+	"errors"
+
+	"clouditor.io/clouditor/api/orchestrator"
+	"github.com/google/uuid"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/types/known/emptypb"
+	"gorm.io/gorm"
+)
+
+const DefaultTargetCloudServiceId = "00000000-0000-0000-000000000000"
+const DefaultTargetCloudServiceName = "default"
+const DefaultTargetCloudServiceDescription = "The default target cloud service"
+
+func (s *Service) RegisterCloudService(_ context.Context, req *orchestrator.RegisterCloudServiceRequest) (service *orchestrator.CloudService, err error) {
+	if req == nil || req.Service == nil {
+		return nil, status.Errorf(codes.InvalidArgument, "Service is empty")
+	}
+
+	if req.Service.Name == "" {
+		return nil, status.Errorf(codes.InvalidArgument, "Service name is empty")
+	}
+
+	service = new(orchestrator.CloudService)
+
+	// Generate a new ID
+	service.Id = uuid.NewString()
+	service.Name = req.Service.Name
+	service.Description = req.Service.Description
+
+	// Persist the service in our database
+	s.db.Create(&service)
+
+	return
+}
+
+func (s *Service) ListCloudServices(_ context.Context, _ *orchestrator.ListCloudServicesRequest) (response *orchestrator.ListCloudServicesResponse, err error) {
+	response = new(orchestrator.ListCloudServicesResponse)
+	response.Services = make([]*orchestrator.CloudService, 0)
+
+	err = s.db.Find(&response.Services).Error
+	if err != nil {
+		return nil, status.Errorf(codes.Internal, "database error: %s", err)
+	}
+
+	return response, nil
+}
+
+func (s *Service) GetCloudService(_ context.Context, req *orchestrator.GetCloudServiceRequest) (response *orchestrator.CloudService, err error) {
+	if req == nil || req.ServiceId == "" {
+		return nil, status.Errorf(codes.InvalidArgument, "Service id is empty")
+	}
+
+	response = new(orchestrator.CloudService)
+	err = s.db.First(&response, "Id = ?", req.ServiceId).Error
+	if errors.Is(err, gorm.ErrRecordNotFound) {
+		return nil, status.Errorf(codes.NotFound, "Service not found")
+	} else if err != nil {
+		return nil, status.Errorf(codes.Internal, "database error: %s", err)
+	}
+
+	return response, nil
+}
+
+func (s *Service) UpdateCloudService(_ context.Context, req *orchestrator.UpdateCloudServiceRequest) (response *orchestrator.CloudService, err error) {
+	if req.Service == nil {
+		return nil, status.Errorf(codes.InvalidArgument, "Service is empty")
+	}
+
+	if req.ServiceId == "" {
+		return nil, status.Errorf(codes.InvalidArgument, "Service id is empty")
+	}
+
+	var count int64
+	err = s.db.Model(&orchestrator.CloudService{}).Count(&count).Error
+	if err != nil {
+		return nil, status.Errorf(codes.Internal, "database error: %s", err)
+	}
+
+	if count == 0 {
+		return nil, status.Error(codes.NotFound, "Service not found")
+	}
+
+	req.Service.Id = req.ServiceId
+	err = s.db.Save(&req.Service).Error
+	if err != nil {
+		return nil, status.Errorf(codes.Internal, "database error: %s", err)
+	}
+
+	return req.Service, nil
+}
+
+func (s *Service) RemoveCloudService(_ context.Context, req *orchestrator.RemoveCloudServiceRequest) (response *emptypb.Empty, err error) {
+	if req.ServiceId == "" {
+		return nil, status.Errorf(codes.InvalidArgument, "Service id is empty")
+	}
+
+	err = s.db.Delete(&orchestrator.CloudService{Id: req.ServiceId}).Error
+	if errors.Is(err, gorm.ErrRecordNotFound) {
+		return nil, status.Errorf(codes.NotFound, "Service not found")
+	} else if err != nil {
+		return nil, status.Errorf(codes.Internal, "database error: %s", err)
+	}
+
+	return &emptypb.Empty{}, nil
+}
+
+// CreateDefaultTargetCloudService creates a new "default" target cloud services,
+// if no target service exists in the database.
+//
+// If a new target cloud service was created, it will be returned.
+func (s *Service) CreateDefaultTargetCloudService() (service *orchestrator.CloudService, err error) {
+	var count int64
+	s.db.Model(&orchestrator.CloudService{}).Count(&count)
+
+	if count == 0 {
+		// Create a default target cloud service
+		service =
+			&orchestrator.CloudService{
+				Id:          DefaultTargetCloudServiceId,
+				Name:        DefaultTargetCloudServiceName,
+				Description: DefaultTargetCloudServiceDescription,
+			}
+
+		// Save it directly into the database, so that we can set the ID
+		err = s.db.Create(&service).Error
+
+		if err != nil {
+			log.Infof("Created new default target cloud service %s", service.Id)
+		}
+
+		return service, err
+	}
+
+	return
+}
diff --git a/service/orchestrator/orchestrator.go b/service/orchestrator/orchestrator.go
index 40a162b0..adb3514e 100644
--- a/service/orchestrator/orchestrator.go
+++ b/service/orchestrator/orchestrator.go
@@ -30,12 +30,15 @@ import (
 	"embed"
 	"encoding/json"
 	"fmt"
+	"io/ioutil"
 
 	"clouditor.io/clouditor/api/assessment"
 	"clouditor.io/clouditor/api/orchestrator"
+	"clouditor.io/clouditor/persistence"
 	"github.com/sirupsen/logrus"
 	"google.golang.org/grpc/codes"
 	"google.golang.org/grpc/status"
+	"gorm.io/gorm"
 )
 
 //go:embed metrics.json
@@ -43,6 +46,7 @@ var f embed.FS
 
 var metrics []*assessment.Metric
 var metricIndex map[string]*assessment.Metric
+var defaultMetricConfigurations map[string]*assessment.MetricConfiguration
 var log *logrus.Entry
 
 var DefaultMetricsFile = "metrics.json"
@@ -50,19 +54,56 @@ var DefaultMetricsFile = "metrics.json"
 // Service is an implementation of the Clouditor Orchestrator service
 type Service struct {
 	orchestrator.UnimplementedOrchestratorServer
+
+	// metricConfigurations holds a double-map of metric configurations associated first by service ID and then metric ID
+	metricConfigurations map[string]map[string]*assessment.MetricConfiguration
+
+	db *gorm.DB
 }
 
 func init() {
 	log = logrus.WithField("component", "orchestrator")
+}
+
+func NewService() *Service {
+	s := Service{
+		metricConfigurations: make(map[string]map[string]*assessment.MetricConfiguration),
+	}
 
 	if err := LoadMetrics(DefaultMetricsFile); err != nil {
 		log.Errorf("Could not load embedded metrics. Will continue with empty metric list: %v", err)
 	}
 
 	metricIndex = make(map[string]*assessment.Metric)
-	for _, v := range metrics {
-		metricIndex[v.Id] = v
+	defaultMetricConfigurations = make(map[string]*assessment.MetricConfiguration)
+
+	for _, m := range metrics {
+		// Look for the data.json to include default metric configurations
+		fileName := fmt.Sprintf("policies/bundles/%s/data.json", m.Id)
+
+		b, err := ioutil.ReadFile(fileName)
+		if err != nil {
+			log.Errorf("Could not retrieve default configuration for metric %s: %s. Ignoring metric", m.Id, err)
+			continue
+		}
+
+		var config assessment.MetricConfiguration
+
+		err = json.Unmarshal(b, &config)
+		if err != nil {
+			log.Errorf("Error in reading default configuration for metric %s: %s. Ignoring metric", m.Id, err)
+			continue
+		}
+
+		config.IsDefault = true
+
+		metricIndex[m.Id] = m
+		defaultMetricConfigurations[m.Id] = &config
 	}
+
+	s.db = persistence.GetDatabase()
+
+	return &s
 }
 
 // LoadMetrics loads metrics definitions from a JSON file.
@@ -105,6 +146,45 @@ func (*Service) GetMetric(_ context.Context, request *orchestrator.GetMetricsReq
 	return response, nil
 }
 
+func (s *Service) GetMetricConfiguration(_ context.Context, req *orchestrator.GetMetricConfigurationRequest) (response *assessment.MetricConfiguration, err error) {
+	// Check, if we have a specific configuration for the metric
+	if config, ok := s.metricConfigurations[req.ServiceId][req.MetricId]; ok {
+		return config, nil
+	}
+
+	// Otherwise, fall back to our default configuration
+	if config, ok := defaultMetricConfigurations[req.MetricId]; ok {
+		return config, nil
+	}
+
+	return nil, status.Errorf(codes.NotFound, "Could not find metric configuration for metric %s in service %s", req.MetricId, req.ServiceId)
+}
+
+// ListMetricConfigurations retrieves a list of MetricConfiguration objects for a particular target
+// cloud service specified in req.
+//
+// The list MUST include a configuration for each known metric. If the user did not specify a custom
+// configuration for a particular metric within the service, the default metric configuration is
+// inserted into the list.
+func (s *Service) ListMetricConfigurations(ctx context.Context, req *orchestrator.ListMetricConfigurationRequest) (response *orchestrator.ListMetricConfigurationResponse, err error) {
+	response = &orchestrator.ListMetricConfigurationResponse{
+		Configurations: make(map[string]*assessment.MetricConfiguration),
+	}
+
+	// TODO(oxisto): This is not very efficient, we should do this once at startup so that we can just return the map
+	for metricId := range metricIndex {
+		config, err := s.GetMetricConfiguration(ctx, &orchestrator.GetMetricConfigurationRequest{ServiceId: req.ServiceId, MetricId: metricId})
+
+		if err != nil {
+			return nil, err
+		}
+
+		response.Configurations[metricId] = config
+	}
+
+	return
+}
+
 //// Tools
 //
 //// TODO Implement DeregisterAssessmentTool


Test patch:
diff --git a/cli/commands/cloud/cloud_test.go b/cli/commands/cloud/cloud_test.go
new file mode 100644
index 00000000..9a9e37f2
--- /dev/null
+++ b/cli/commands/cloud/cloud_test.go
@@ -0,0 +1,230 @@
+// Copyright 2021 Fraunhofer AISEC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+//           $$\                           $$\ $$\   $$\
+//           $$ |                          $$ |\__|  $$ |
+//  $$$$$$$\ $$ | $$$$$$\  $$\   $$\  $$$$$$$ |$$\ $$$$$$\    $$$$$$\   $$$$$$\
+// $$  _____|$$ |$$  __$$\ $$ |  $$ |$$  __$$ |$$ |\_$$  _|  $$  __$$\ $$  __$$\
+// $$ /      $$ |$$ /  $$ |$$ |  $$ |$$ /  $$ |$$ |  $$ |    $$ /  $$ |$$ | \__|
+// $$ |      $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$ |  $$ |$$\ $$ |  $$ |$$ |
+// \$$$$$$\  $$ |\$$$$$   |\$$$$$   |\$$$$$$  |$$ |  \$$$   |\$$$$$   |$$ |
+//  \_______|\__| \______/  \______/  \_______|\__|   \____/  \______/ \__|
+//
+// This file is part of Clouditor Community Edition.
+
+package cloud_test
+
+import (
+	"bytes"
+	"context"
+	"fmt"
+	"io/ioutil"
+	"net"
+	"os"
+	"testing"
+
+	"clouditor.io/clouditor/api/orchestrator"
+	"clouditor.io/clouditor/cli"
+	"clouditor.io/clouditor/cli/commands/cloud"
+	"clouditor.io/clouditor/cli/commands/login"
+	"clouditor.io/clouditor/persistence"
+	service_auth "clouditor.io/clouditor/service/auth"
+	service_orchestrator "clouditor.io/clouditor/service/orchestrator"
+	"github.com/spf13/viper"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc"
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/types/known/emptypb"
+)
+
+var sock net.Listener
+var server *grpc.Server
+var service *service_orchestrator.Service
+var target *orchestrator.CloudService
+
+func TestMain(m *testing.M) {
+	var (
+		err error
+		dir string
+	)
+
+	err = os.Chdir("../../../")
+	if err != nil {
+		panic(err)
+	}
+
+	err = persistence.InitDB(true, "", 0)
+	if err != nil {
+		panic(err)
+	}
+
+	service = service_orchestrator.NewService()
+
+	sock, server, err = service_auth.StartDedicatedAuthServer(":0")
+	if err != nil {
+		panic(err)
+	}
+	orchestrator.RegisterOrchestratorServer(server, service)
+
+	target, err = service.CreateDefaultTargetCloudService()
+	if err != nil {
+		panic(err)
+	}
+
+	defer sock.Close()
+	defer server.Stop()
+
+	dir, err = ioutil.TempDir(os.TempDir(), ".clouditor")
+	if err != nil {
+		panic(err)
+	}
+
+	viper.Set("username", "clouditor")
+	viper.Set("password", "clouditor")
+	viper.Set("session-directory", dir)
+
+	cmd := login.NewLoginCommand()
+	err = cmd.RunE(nil, []string{fmt.Sprintf("localhost:%d", sock.Addr().(*net.TCPAddr).Port)})
+	if err != nil {
+		panic(err)
+	}
+
+	defer os.Exit(m.Run())
+}
+
+func TestNewCloudCommand(t *testing.T) {
+	cmd := cloud.NewCloudCommand()
+
+	assert.NotNil(t, cmd)
+	assert.True(t, cmd.HasSubCommands())
+}
+
+func TestRegisterCloudServiceCommand(t *testing.T) {
+	var err error
+	var b bytes.Buffer
+	var response orchestrator.CloudService
+
+	cli.Output = &b
+
+	cmd := cloud.NewRegisterCloudServiceCommand()
+	err = cmd.RunE(nil, []string{"not_default"})
+
+	assert.Nil(t, err)
+
+	err = protojson.Unmarshal(b.Bytes(), &response)
+
+	assert.Nil(t, err)
+	assert.Equal(t, "not_default", response.Name)
+}
+
+func TestListCloudServicesCommand(t *testing.T) {
+	var err error
+	var b bytes.Buffer
+	var response orchestrator.ListCloudServicesResponse
+
+	cli.Output = &b
+
+	cmd := cloud.NewListCloudServicesCommand()
+	err = cmd.RunE(nil, []string{})
+
+	assert.Nil(t, err)
+
+	err = protojson.Unmarshal(b.Bytes(), &response)
+
+	assert.Nil(t, err)
+	assert.NotEmpty(t, response.Services)
+}
+
+func TestGetCloudServiceCommand(t *testing.T) {
+	var err error
+	var b bytes.Buffer
+	var response orchestrator.CloudService
+
+	cli.Output = &b
+
+	cmd := cloud.NewGetCloudServiceComand()
+	err = cmd.RunE(nil, []string{target.Id})
+
+	assert.Nil(t, err)
+
+	err = protojson.Unmarshal(b.Bytes(), &response)
+
+	assert.Nil(t, err)
+	assert.Equal(t, target.Id, response.Id)
+}
+
+func TestRemoveCloudServicesCommand(t *testing.T) {
+	var err error
+	var b bytes.Buffer
+	var response emptypb.Empty
+
+	cli.Output = &b
+
+	cmd := cloud.NewRemoveCloudServiceComand()
+	err = cmd.RunE(nil, []string{target.Id})
+
+	assert.Nil(t, err)
+
+	err = protojson.Unmarshal(b.Bytes(), &response)
+
+	assert.Nil(t, err)
+
+	// Re-create default service
+	_, err = service.CreateDefaultTargetCloudService()
+
+	assert.Nil(t, err)
+}
+
+func TestUpdateCloudServiceCommand(t *testing.T) {
+	var err error
+	var b bytes.Buffer
+	var response orchestrator.CloudService
+
+	cli.Output = &b
+
+	viper.Set("id", target.Id)
+	viper.Set("name", "not_default")
+
+	cmd := cloud.NewUpdateCloudServiceCommand()
+	err = cmd.RunE(nil, []string{})
+
+	assert.Nil(t, err)
+
+	err = protojson.Unmarshal(b.Bytes(), &response)
+
+	assert.Nil(t, err)
+	assert.Equal(t, target.Id, response.Id)
+	assert.Equal(t, "not_default", response.Name)
+}
+
+func TestGetMetricConfiguration(t *testing.T) {
+	var (
+		err    error
+		b      bytes.Buffer
+		target *orchestrator.CloudService
+	)
+
+	cli.Output = &b
+
+	// create a new target service
+	target, err = service.RegisterCloudService(context.TODO(), &orchestrator.RegisterCloudServiceRequest{Service: &orchestrator.CloudService{Name: "myservice"}})
+
+	assert.NotNil(t, target)
+	assert.Nil(t, err)
+
+	cmd := cloud.NewGetMetricConfigurationCommand()
+	err = cmd.RunE(nil, []string{target.Id, "TransportEncryptionEnabled"})
+
+	assert.Nil(t, err)
+}
diff --git a/cli/commands/login/login_test.go b/cli/commands/login/login_test.go
index 28c014cf..fc0e7e1a 100644
--- a/cli/commands/login/login_test.go
+++ b/cli/commands/login/login_test.go
@@ -33,6 +33,7 @@ import (
 	"testing"
 
 	"clouditor.io/clouditor/cli/commands/login"
+	"clouditor.io/clouditor/persistence"
 	service_auth "clouditor.io/clouditor/service/auth"
 	"github.com/spf13/viper"
 	"github.com/stretchr/testify/assert"
@@ -45,8 +46,12 @@ var server *grpc.Server
 func TestMain(m *testing.M) {
 	var err error
 
-	sock, server, err = service_auth.StartDedicatedAuthServer(":0")
+	err = persistence.InitDB(true, "", 0)
+	if err != nil {
+		panic(err)
+	}
 
+	sock, server, err = service_auth.StartDedicatedAuthServer(":0")
 	if err != nil {
 		panic(err)
 	}
diff --git a/cli/commands/metric/metric_test.go b/cli/commands/metric/metric_test.go
index 7023151d..fb6d9af6 100644
--- a/cli/commands/metric/metric_test.go
+++ b/cli/commands/metric/metric_test.go
@@ -37,6 +37,7 @@ import (
 	"clouditor.io/clouditor/cli"
 	"clouditor.io/clouditor/cli/commands/login"
 	"clouditor.io/clouditor/cli/commands/metric"
+	"clouditor.io/clouditor/persistence"
 	service_auth "clouditor.io/clouditor/service/auth"
 	service_orchestrator "clouditor.io/clouditor/service/orchestrator"
 	"github.com/spf13/viper"
@@ -50,12 +51,25 @@ var server *grpc.Server
 
 func TestMain(m *testing.M) {
 	var (
-		err error
-		dir string
+		err     error
+		dir     string
+		service *service_orchestrator.Service
 	)
 
+	err = os.Chdir("../../../")
+	if err != nil {
+		panic(err)
+	}
+
+	err = persistence.InitDB(true, "", 0)
+	if err != nil {
+		panic(err)
+	}
+
+	service = service_orchestrator.NewService()
+
 	sock, server, err = service_auth.StartDedicatedAuthServer(":0")
-	orchestrator.RegisterOrchestratorServer(server, &service_orchestrator.Service{})
+	orchestrator.RegisterOrchestratorServer(server, service)
 
 	if err != nil {
 		panic(err)
diff --git a/cli/commands/tool/tool_test.go b/cli/commands/tool/tool_test.go
index ec455de8..296de8e5 100644
--- a/cli/commands/tool/tool_test.go
+++ b/cli/commands/tool/tool_test.go
@@ -35,6 +35,7 @@ import (
 	"clouditor.io/clouditor/api/orchestrator"
 	"clouditor.io/clouditor/cli/commands/login"
 	"clouditor.io/clouditor/cli/commands/tool"
+	"clouditor.io/clouditor/persistence"
 	service_auth "clouditor.io/clouditor/service/auth"
 	service_orchestrator "clouditor.io/clouditor/service/orchestrator"
 	"github.com/spf13/viper"
@@ -47,12 +48,25 @@ var server *grpc.Server
 
 func TestMain(m *testing.M) {
 	var (
-		err error
-		dir string
+		err     error
+		dir     string
+		service *service_orchestrator.Service
 	)
 
+	err = os.Chdir("../../../")
+	if err != nil {
+		panic(err)
+	}
+
+	err = persistence.InitDB(true, "", 0)
+	if err != nil {
+		panic(err)
+	}
+
+	service = service_orchestrator.NewService()
+
 	sock, server, err = service_auth.StartDedicatedAuthServer(":0")
-	orchestrator.RegisterOrchestratorServer(server, &service_orchestrator.Service{})
+	orchestrator.RegisterOrchestratorServer(server, service)
 
 	if err != nil {
 		panic(err)
diff --git a/cli/session_test.go b/cli/session_test.go
index 0b5cdd69..aada0202 100644
--- a/cli/session_test.go
+++ b/cli/session_test.go
@@ -35,6 +35,7 @@ import (
 
 	"clouditor.io/clouditor/api/auth"
 	"clouditor.io/clouditor/cli"
+	"clouditor.io/clouditor/persistence"
 	service_auth "clouditor.io/clouditor/service/auth"
 	"github.com/spf13/viper"
 	"github.com/stretchr/testify/assert"
@@ -49,8 +50,12 @@ var server *grpc.Server
 func TestMain(m *testing.M) {
 	var err error
 
-	sock, server, err = service_auth.StartDedicatedAuthServer(":0")
+	err = persistence.InitDB(true, "", 0)
+	if err != nil {
+		panic(err)
+	}
 
+	sock, server, err = service_auth.StartDedicatedAuthServer(":0")
 	if err != nil {
 		panic(err)
 	}
diff --git a/policies/policies_test.go b/policies/policies_test.go
index feb771fa..5bd18906 100644
--- a/policies/policies_test.go
+++ b/policies/policies_test.go
@@ -186,7 +186,7 @@ func TestRunEvidence(t *testing.T) {
 			wantErr:    false,
 		},
 		{
-			name: "VM:Compliant Case",
+			name: "VM: Compliant Case",
 			fields: fields{
 				resource: voc.VirtualMachine{
 					Compute: &voc.Compute{
@@ -218,7 +218,7 @@ func TestRunEvidence(t *testing.T) {
 			wantErr:    false,
 		},
 		{
-			name: "VM:Non-Compliant Case",
+			name: "VM: Non-Compliant Case",
 			fields: fields{
 				resource: voc.VirtualMachine{
 					Compute: &voc.Compute{
diff --git a/service/orchestrator/cloud_service_test.go b/service/orchestrator/cloud_service_test.go
new file mode 100644
index 00000000..42629cef
--- /dev/null
+++ b/service/orchestrator/cloud_service_test.go
@@ -0,0 +1,124 @@
+package orchestrator_test
+
+import (
+	"context"
+	"testing"
+
+	"clouditor.io/clouditor/api/orchestrator"
+	service_orchestrator "clouditor.io/clouditor/service/orchestrator"
+	"github.com/stretchr/testify/assert"
+	"google.golang.org/grpc/codes"
+	"google.golang.org/grpc/status"
+	"google.golang.org/protobuf/proto"
+)
+
+func TestRegisterCloudService(t *testing.T) {
+	tests := []struct {
+		name string
+		req  *orchestrator.RegisterCloudServiceRequest
+		res  *orchestrator.CloudService
+		err  error
+	}{
+		{
+			"missing service",
+			&orchestrator.RegisterCloudServiceRequest{},
+			nil,
+			status.Error(codes.InvalidArgument, "Service is empty"),
+		},
+		{
+			"missing service name",
+			&orchestrator.RegisterCloudServiceRequest{Service: &orchestrator.CloudService{}},
+			nil,
+			status.Error(codes.InvalidArgument, "Service name is empty"),
+		},
+		{
+			"valid",
+			&orchestrator.RegisterCloudServiceRequest{Service: &orchestrator.CloudService{Name: "test", Description: "some"}},
+			&orchestrator.CloudService{Name: "test", Description: "some"},
+			nil,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			res, err := service.RegisterCloudService(context.Background(), tt.req)
+
+			if tt.err == nil {
+				assert.Equal(t, err, tt.err)
+			} else {
+				assert.EqualError(t, err, tt.err.Error())
+			}
+
+			if tt.res != nil {
+				assert.NotEmpty(t, res.Id)
+			}
+
+			// reset the IDs because we cannot compare them, since they are randomly generated
+			if res != nil {
+				res.Id = ""
+			}
+
+			if tt.res != nil {
+				tt.res.Id = ""
+			}
+
+			assert.True(t, proto.Equal(res, tt.res), "%v != %v", res, tt.res)
+		})
+	}
+}
+
+func TestGetCloudService(t *testing.T) {
+	tests := []struct {
+		name string
+		req  *orchestrator.GetCloudServiceRequest
+		res  *orchestrator.CloudService
+		err  error
+	}{
+		{
+			"missing request",
+			nil,
+			nil,
+			status.Error(codes.InvalidArgument, "Service id is empty"),
+		},
+		{
+			"missing service id",
+			&orchestrator.GetCloudServiceRequest{},
+			nil,
+			status.Error(codes.InvalidArgument, "Service id is empty"),
+		},
+		{
+			"invalid service id",
+			&orchestrator.GetCloudServiceRequest{ServiceId: "does-not-exist"},
+			nil,
+			status.Error(codes.NotFound, "Service not found"),
+		},
+		{
+			"valid",
+			&orchestrator.GetCloudServiceRequest{ServiceId: defaultTarget.Id},
+			&orchestrator.CloudService{
+				Id:          service_orchestrator.DefaultTargetCloudServiceId,
+				Name:        service_orchestrator.DefaultTargetCloudServiceName,
+				Description: service_orchestrator.DefaultTargetCloudServiceDescription,
+			},
+			nil,
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			res, err := service.GetCloudService(context.Background(), tt.req)
+
+			if tt.err == nil {
+				assert.Equal(t, err, tt.err)
+			} else {
+				assert.EqualError(t, err, tt.err.Error())
+			}
+
+			if tt.res != nil {
+				assert.NotEmpty(t, res.Id)
+			}
+
+			assert.True(t, proto.Equal(res, tt.res), "%v != %v", res, tt.res)
+		})
+	}
+}
diff --git a/service/orchestrator/orchestrator_test.go b/service/orchestrator/orchestrator_test.go
index 2ccf4ea4..45b50f0b 100644
--- a/service/orchestrator/orchestrator_test.go
+++ b/service/orchestrator/orchestrator_test.go
@@ -28,16 +28,39 @@ package orchestrator_test
 import (
 	"context"
 	"io/fs"
+	"os"
 	"testing"
 
 	"clouditor.io/clouditor/api/assessment"
+	"clouditor.io/clouditor/persistence"
 
 	"clouditor.io/clouditor/api/orchestrator"
 	service_orchestrator "clouditor.io/clouditor/service/orchestrator"
 	"github.com/stretchr/testify/assert"
 )
 
-var service service_orchestrator.Service
+var service *service_orchestrator.Service
+var defaultTarget *orchestrator.CloudService
+
+func TestMain(m *testing.M) {
+	err := os.Chdir("../../")
+	if err != nil {
+		panic(err)
+	}
+
+	err = persistence.InitDB(true, "", 0)
+	if err != nil {
+		panic(err)
+	}
+
+	service = service_orchestrator.NewService()
+	defaultTarget, err = service.CreateDefaultTargetCloudService()
+	if err != nil {
+		panic(err)
+	}
+
+	os.Exit(m.Run())
+}
 
 func TestListMetrics(t *testing.T) {
 	var (
@@ -51,6 +74,18 @@ func TestListMetrics(t *testing.T) {
 	assert.NotEmpty(t, response.Metrics)
 }
 
+func TestListMetricConfigurations(t *testing.T) {
+	var (
+		response *orchestrator.ListMetricConfigurationResponse
+		err      error
+	)
+
+	response, err = service.ListMetricConfigurations(context.TODO(), &orchestrator.ListMetricConfigurationRequest{})
+
+	assert.Nil(t, err)
+	assert.NotEmpty(t, response.Configurations)
+}
+
 func TestGetMetric(t *testing.T) {
 	var (
 		request *orchestrator.GetMetricsRequest