diff --git a/api/go/gosdn/conflict/conflict.pb.go b/api/go/gosdn/conflict/conflict.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..ee721fffb0cfbab32110663d3bd465173b731a89
--- /dev/null
+++ b/api/go/gosdn/conflict/conflict.pb.go
@@ -0,0 +1,150 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// 	protoc-gen-go v1.27.1
+// 	protoc        (unknown)
+// source: gosdn/conflict/conflict.proto
+
+package conflict
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	_ "google.golang.org/protobuf/types/descriptorpb"
+	reflect "reflect"
+	sync "sync"
+)
+
+const (
+	// Verify that this generated code is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+	// Verify that runtime/protoimpl is sufficiently up-to-date.
+	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type Metadata struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResourceVersion int64 `protobuf:"varint,1,opt,name=resourceVersion,proto3" json:"resourceVersion,omitempty"`
+}
+
+func (x *Metadata) Reset() {
+	*x = Metadata{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gosdn_conflict_conflict_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Metadata) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Metadata) ProtoMessage() {}
+
+func (x *Metadata) ProtoReflect() protoreflect.Message {
+	mi := &file_gosdn_conflict_conflict_proto_msgTypes[0]
+	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 Metadata.ProtoReflect.Descriptor instead.
+func (*Metadata) Descriptor() ([]byte, []int) {
+	return file_gosdn_conflict_conflict_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Metadata) GetResourceVersion() int64 {
+	if x != nil {
+		return x.ResourceVersion
+	}
+	return 0
+}
+
+var File_gosdn_conflict_conflict_proto protoreflect.FileDescriptor
+
+var file_gosdn_conflict_conflict_proto_rawDesc = []byte{
+	0x0a, 0x1d, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74,
+	0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
+	0x0e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x1a,
+	0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+	0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x22, 0x34, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x28, 0x0a,
+	0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
+	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+	0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x34, 0x5a, 0x32, 0x63, 0x6f, 0x64, 0x65, 0x2e,
+	0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65,
+	0x74, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x67,
+	0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x62, 0x06, 0x70,
+	0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+	file_gosdn_conflict_conflict_proto_rawDescOnce sync.Once
+	file_gosdn_conflict_conflict_proto_rawDescData = file_gosdn_conflict_conflict_proto_rawDesc
+)
+
+func file_gosdn_conflict_conflict_proto_rawDescGZIP() []byte {
+	file_gosdn_conflict_conflict_proto_rawDescOnce.Do(func() {
+		file_gosdn_conflict_conflict_proto_rawDescData = protoimpl.X.CompressGZIP(file_gosdn_conflict_conflict_proto_rawDescData)
+	})
+	return file_gosdn_conflict_conflict_proto_rawDescData
+}
+
+var file_gosdn_conflict_conflict_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_gosdn_conflict_conflict_proto_goTypes = []interface{}{
+	(*Metadata)(nil), // 0: gosdn.conflict.Metadata
+}
+var file_gosdn_conflict_conflict_proto_depIdxs = []int32{
+	0, // [0:0] is the sub-list for method output_type
+	0, // [0:0] is the sub-list for method input_type
+	0, // [0:0] is the sub-list for extension type_name
+	0, // [0:0] is the sub-list for extension extendee
+	0, // [0:0] is the sub-list for field type_name
+}
+
+func init() { file_gosdn_conflict_conflict_proto_init() }
+func file_gosdn_conflict_conflict_proto_init() {
+	if File_gosdn_conflict_conflict_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_gosdn_conflict_conflict_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Metadata); 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{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_gosdn_conflict_conflict_proto_rawDesc,
+			NumEnums:      0,
+			NumMessages:   1,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_gosdn_conflict_conflict_proto_goTypes,
+		DependencyIndexes: file_gosdn_conflict_conflict_proto_depIdxs,
+		MessageInfos:      file_gosdn_conflict_conflict_proto_msgTypes,
+	}.Build()
+	File_gosdn_conflict_conflict_proto = out.File
+	file_gosdn_conflict_conflict_proto_rawDesc = nil
+	file_gosdn_conflict_conflict_proto_goTypes = nil
+	file_gosdn_conflict_conflict_proto_depIdxs = nil
+}
diff --git a/api/go/gosdn/rbac/user.pb.go b/api/go/gosdn/rbac/user.pb.go
index ef2f31b24e1600f2bb8f43c9ffd20442610dc423..320cbbedd1bd893d9103ce37aab12ba132de071d 100644
--- a/api/go/gosdn/rbac/user.pb.go
+++ b/api/go/gosdn/rbac/user.pb.go
@@ -7,6 +7,7 @@
 package rbac
 
 import (
+	conflict "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
 	_ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options"
 	_ "google.golang.org/genproto/googleapis/api/annotations"
 	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@@ -28,11 +29,12 @@ type User struct {
 	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"`
-	Roles    map[string]string `protobuf:"bytes,3,rep,name=roles,proto3" json:"roles,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Key = pnd uuid, value= role name
-	Password string            `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"`
-	Token    string            `protobuf:"bytes,5,opt,name=token,proto3" json:"token,omitempty"`
+	Id       string             `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
+	Name     string             `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
+	Roles    map[string]string  `protobuf:"bytes,3,rep,name=roles,proto3" json:"roles,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Key = pnd uuid, value= role name
+	Password string             `protobuf:"bytes,4,opt,name=password,proto3" json:"password,omitempty"`
+	Token    string             `protobuf:"bytes,5,opt,name=token,proto3" json:"token,omitempty"`
+	Metadata *conflict.Metadata `protobuf:"bytes,6,opt,name=metadata,proto3" json:"metadata,omitempty"`
 }
 
 func (x *User) Reset() {
@@ -102,6 +104,13 @@ func (x *User) GetToken() string {
 	return ""
 }
 
+func (x *User) GetMetadata() *conflict.Metadata {
+	if x != nil {
+		return x.Metadata
+	}
+	return nil
+}
+
 // CreateUsers
 type CreateUsersRequest struct {
 	state         protoimpl.MessageState
@@ -686,114 +695,120 @@ var file_gosdn_rbac_user_proto_rawDesc = []byte{
 	0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
 	0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
 	0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x72, 0x62, 0x61, 0x63, 0x2f,
-	0x72, 0x62, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc9, 0x01, 0x0a, 0x04, 0x55,
-	0x73, 0x65, 0x72, 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, 0x31, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73,
-	0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72,
-	0x62, 0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x45, 0x6e,
-	0x74, 0x72, 0x79, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61,
-	0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61,
-	0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18,
-	0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x38, 0x0a, 0x0a,
-	0x52, 0x6f, 0x6c, 0x65, 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, 0x14, 0x0a, 0x05,
-	0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c,
-	0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65,
-	0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
-	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73,
-	0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e,
-	0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72,
-	0x22, 0x5f, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52,
-	0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
-	0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65,
-	0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18,
-	0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62,
-	0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x22, 0x52, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
-	0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
-	0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
-	0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d,
-	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69,
-	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e,
-	0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28,
-	0x0b, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x55,
-	0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2f, 0x0a, 0x0f, 0x47, 0x65, 0x74,
-	0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09,
+	0x72, 0x62, 0x61, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1d, 0x67, 0x6f, 0x73, 0x64,
+	0x6e, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x6c,
+	0x69, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xff, 0x01, 0x0a, 0x04, 0x55, 0x73,
+	0x65, 0x72, 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, 0x31, 0x0a, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x18,
+	0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62,
+	0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x2e, 0x52, 0x6f, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74,
+	0x72, 0x79, 0x52, 0x05, 0x72, 0x6f, 0x6c, 0x65, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73,
+	0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73,
+	0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x05,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x34, 0x0a, 0x08, 0x6d,
+	0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e,
+	0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x63, 0x6f, 0x6e, 0x66, 0x6c, 0x69, 0x63, 0x74, 0x2e, 0x4d,
+	0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
+	0x61, 0x1a, 0x38, 0x0a, 0x0a, 0x52, 0x6f, 0x6c, 0x65, 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, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x58, 0x0a, 0x12, 0x43,
+	0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
+	0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e,
+	0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52,
+	0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x5f, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55,
+	0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09,
 	0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52,
-	0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x82, 0x01, 0x0a, 0x10, 0x47,
-	0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
-	0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a,
-	0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e,
-	0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75,
-	0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65,
-	0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e,
-	0x72, 0x62, 0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22,
-	0x58, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65,
+	0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74,
+	0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73,
+	0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06,
+	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x52, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
+	0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65,
+	0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d,
+	0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x81, 0x01, 0x0a, 0x0f, 0x47,
+	0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c,
+	0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06,
+	0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67,
+	0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72,
+	0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72,
+	0x62, 0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x2f,
+	0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22,
+	0x82, 0x01, 0x0a, 0x10, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70,
+	0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+	0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01,
+	0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e,
+	0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x24,
+	0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67,
+	0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04,
+	0x75, 0x73, 0x65, 0x72, 0x22, 0x58, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73,
+	0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69,
+	0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74,
+	0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72,
+	0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72,
+	0x62, 0x61, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x5f,
+	0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73,
+	0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
+	0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63,
+	0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22,
+	0x4e, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65,
 	0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
 	0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
-	0x61, 0x6d, 0x70, 0x12, 0x24, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x03, 0x28,
-	0x0b, 0x32, 0x10, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x55,
-	0x73, 0x65, 0x72, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x22, 0x5f, 0x0a, 0x13, 0x55, 0x70, 0x64,
+	0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+	0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22,
+	0x5f, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
+	0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73,
+	0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61,
+	0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x32, 0xf7, 0x03, 0x0a, 0x0b, 0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,
+	0x12, 0x68, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12,
+	0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x43, 0x72, 0x65,
+	0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
+	0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x43, 0x72, 0x65,
 	0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
-	0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x2a,
-	0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12,
-	0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x4e, 0x0a, 0x12, 0x44, 0x65,
-	0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
-	0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a,
-	0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09,
-	0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x5f, 0x0a, 0x13, 0x44, 0x65,
-	0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
-	0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01,
-	0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12,
-	0x2a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32,
-	0x12, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x53, 0x74, 0x61,
-	0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0xf7, 0x03, 0x0a, 0x0b,
-	0x55, 0x73, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x68, 0x0a, 0x0b, 0x43,
-	0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x73,
-	0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73,
-	0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x6f, 0x73,
-	0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x55, 0x73,
-	0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4,
-	0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x63,
-	0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
-	0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x47, 0x65,
-	0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x67,
-	0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65,
-	0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12, 0x82, 0xd3, 0xe4, 0x93, 0x02,
-	0x0c, 0x12, 0x0a, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x67, 0x65, 0x74, 0x12, 0x55, 0x0a,
-	0x08, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64,
-	0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52,
-	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72,
-	0x62, 0x61, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x08, 0x12, 0x06, 0x2f, 0x75,
-	0x73, 0x65, 0x72, 0x73, 0x12, 0x68, 0x0a, 0x0b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73,
-	0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63,
-	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63,
-	0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70,
-	0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22,
-	0x0d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x65,
-	0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e,
-	0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e,
-	0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74,
-	0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x15,
-	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x2a, 0x0d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x64,
-	0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x30, 0x5a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62,
-	0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65, 0x74, 0x2f,
-	0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x6f, 0x73,
-	0x64, 0x6e, 0x2f, 0x72, 0x62, 0x61, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x75, 0x73,
+	0x65, 0x72, 0x73, 0x2f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x56, 0x0a, 0x07, 0x47, 0x65,
+	0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62,
+	0x61, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x1a, 0x1b, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x47,
+	0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x12,
+	0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x12, 0x0a, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x67,
+	0x65, 0x74, 0x12, 0x55, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1b,
+	0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x55,
+	0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f,
+	0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x0e, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x08, 0x12, 0x06, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x12, 0x68, 0x0a, 0x0b, 0x55, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e,
+	0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
+	0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e,
+	0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72,
+	0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02,
+	0x12, 0x3a, 0x01, 0x2a, 0x22, 0x0d, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x73, 0x2f, 0x75, 0x70, 0x64,
+	0x61, 0x74, 0x65, 0x12, 0x65, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65,
+	0x72, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+	0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2e, 0x72, 0x62, 0x61, 0x63, 0x2e,
+	0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x55, 0x73, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+	0x6e, 0x73, 0x65, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x2a, 0x0d, 0x2f, 0x75, 0x73,
+	0x65, 0x72, 0x73, 0x2f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x30, 0x5a, 0x2e, 0x63, 0x6f,
+	0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64,
+	0x61, 0x6e, 0x65, 0x74, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67,
+	0x6f, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x72, 0x62, 0x61, 0x63, 0x62, 0x06, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -822,34 +837,36 @@ var file_gosdn_rbac_user_proto_goTypes = []interface{}{
 	(*DeleteUsersRequest)(nil),  // 9: gosdn.rbac.DeleteUsersRequest
 	(*DeleteUsersResponse)(nil), // 10: gosdn.rbac.DeleteUsersResponse
 	nil,                         // 11: gosdn.rbac.User.RolesEntry
-	(Status)(0),                 // 12: gosdn.rbac.Status
+	(*conflict.Metadata)(nil),   // 12: gosdn.conflict.Metadata
+	(Status)(0),                 // 13: gosdn.rbac.Status
 }
 var file_gosdn_rbac_user_proto_depIdxs = []int32{
 	11, // 0: gosdn.rbac.User.roles:type_name -> gosdn.rbac.User.RolesEntry
-	0,  // 1: gosdn.rbac.CreateUsersRequest.user:type_name -> gosdn.rbac.User
-	12, // 2: gosdn.rbac.CreateUsersResponse.status:type_name -> gosdn.rbac.Status
-	12, // 3: gosdn.rbac.GetUserResponse.status:type_name -> gosdn.rbac.Status
-	0,  // 4: gosdn.rbac.GetUserResponse.user:type_name -> gosdn.rbac.User
-	12, // 5: gosdn.rbac.GetUsersResponse.status:type_name -> gosdn.rbac.Status
-	0,  // 6: gosdn.rbac.GetUsersResponse.user:type_name -> gosdn.rbac.User
-	0,  // 7: gosdn.rbac.UpdateUsersRequest.user:type_name -> gosdn.rbac.User
-	12, // 8: gosdn.rbac.UpdateUsersResponse.status:type_name -> gosdn.rbac.Status
-	12, // 9: gosdn.rbac.DeleteUsersResponse.status:type_name -> gosdn.rbac.Status
-	1,  // 10: gosdn.rbac.UserService.CreateUsers:input_type -> gosdn.rbac.CreateUsersRequest
-	3,  // 11: gosdn.rbac.UserService.GetUser:input_type -> gosdn.rbac.GetUserRequest
-	5,  // 12: gosdn.rbac.UserService.GetUsers:input_type -> gosdn.rbac.GetUsersRequest
-	7,  // 13: gosdn.rbac.UserService.UpdateUsers:input_type -> gosdn.rbac.UpdateUsersRequest
-	9,  // 14: gosdn.rbac.UserService.DeleteUsers:input_type -> gosdn.rbac.DeleteUsersRequest
-	2,  // 15: gosdn.rbac.UserService.CreateUsers:output_type -> gosdn.rbac.CreateUsersResponse
-	4,  // 16: gosdn.rbac.UserService.GetUser:output_type -> gosdn.rbac.GetUserResponse
-	6,  // 17: gosdn.rbac.UserService.GetUsers:output_type -> gosdn.rbac.GetUsersResponse
-	8,  // 18: gosdn.rbac.UserService.UpdateUsers:output_type -> gosdn.rbac.UpdateUsersResponse
-	10, // 19: gosdn.rbac.UserService.DeleteUsers:output_type -> gosdn.rbac.DeleteUsersResponse
-	15, // [15:20] is the sub-list for method output_type
-	10, // [10:15] is the sub-list for method input_type
-	10, // [10:10] is the sub-list for extension type_name
-	10, // [10:10] is the sub-list for extension extendee
-	0,  // [0:10] is the sub-list for field type_name
+	12, // 1: gosdn.rbac.User.metadata:type_name -> gosdn.conflict.Metadata
+	0,  // 2: gosdn.rbac.CreateUsersRequest.user:type_name -> gosdn.rbac.User
+	13, // 3: gosdn.rbac.CreateUsersResponse.status:type_name -> gosdn.rbac.Status
+	13, // 4: gosdn.rbac.GetUserResponse.status:type_name -> gosdn.rbac.Status
+	0,  // 5: gosdn.rbac.GetUserResponse.user:type_name -> gosdn.rbac.User
+	13, // 6: gosdn.rbac.GetUsersResponse.status:type_name -> gosdn.rbac.Status
+	0,  // 7: gosdn.rbac.GetUsersResponse.user:type_name -> gosdn.rbac.User
+	0,  // 8: gosdn.rbac.UpdateUsersRequest.user:type_name -> gosdn.rbac.User
+	13, // 9: gosdn.rbac.UpdateUsersResponse.status:type_name -> gosdn.rbac.Status
+	13, // 10: gosdn.rbac.DeleteUsersResponse.status:type_name -> gosdn.rbac.Status
+	1,  // 11: gosdn.rbac.UserService.CreateUsers:input_type -> gosdn.rbac.CreateUsersRequest
+	3,  // 12: gosdn.rbac.UserService.GetUser:input_type -> gosdn.rbac.GetUserRequest
+	5,  // 13: gosdn.rbac.UserService.GetUsers:input_type -> gosdn.rbac.GetUsersRequest
+	7,  // 14: gosdn.rbac.UserService.UpdateUsers:input_type -> gosdn.rbac.UpdateUsersRequest
+	9,  // 15: gosdn.rbac.UserService.DeleteUsers:input_type -> gosdn.rbac.DeleteUsersRequest
+	2,  // 16: gosdn.rbac.UserService.CreateUsers:output_type -> gosdn.rbac.CreateUsersResponse
+	4,  // 17: gosdn.rbac.UserService.GetUser:output_type -> gosdn.rbac.GetUserResponse
+	6,  // 18: gosdn.rbac.UserService.GetUsers:output_type -> gosdn.rbac.GetUsersResponse
+	8,  // 19: gosdn.rbac.UserService.UpdateUsers:output_type -> gosdn.rbac.UpdateUsersResponse
+	10, // 20: gosdn.rbac.UserService.DeleteUsers:output_type -> gosdn.rbac.DeleteUsersResponse
+	16, // [16:21] is the sub-list for method output_type
+	11, // [11:16] 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_gosdn_rbac_user_proto_init() }
diff --git a/api/go/gosdn/topology/node.pb.go b/api/go/gosdn/topology/node.pb.go
index 0c9330271dd3e7d66d7f8454d254091c32961090..b24ecce2e4d1e47314008fb302435a5d48af6533 100644
--- a/api/go/gosdn/topology/node.pb.go
+++ b/api/go/gosdn/topology/node.pb.go
@@ -23,6 +23,53 @@ const (
 	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 )
 
+type Metadata struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	ResourceVersion int64 `protobuf:"varint,1,opt,name=resourceVersion,proto3" json:"resourceVersion,omitempty"`
+}
+
+func (x *Metadata) Reset() {
+	*x = Metadata{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_gosdn_topology_node_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Metadata) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Metadata) ProtoMessage() {}
+
+func (x *Metadata) ProtoReflect() protoreflect.Message {
+	mi := &file_gosdn_topology_node_proto_msgTypes[0]
+	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 Metadata.ProtoReflect.Descriptor instead.
+func (*Metadata) Descriptor() ([]byte, []int) {
+	return file_gosdn_topology_node_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Metadata) GetResourceVersion() int64 {
+	if x != nil {
+		return x.ResourceVersion
+	}
+	return 0
+}
+
 type Node struct {
 	state         protoimpl.MessageState
 	sizeCache     protoimpl.SizeCache
@@ -35,7 +82,7 @@ type Node struct {
 func (x *Node) Reset() {
 	*x = Node{}
 	if protoimpl.UnsafeEnabled {
-		mi := &file_gosdn_topology_node_proto_msgTypes[0]
+		mi := &file_gosdn_topology_node_proto_msgTypes[1]
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		ms.StoreMessageInfo(mi)
 	}
@@ -48,7 +95,7 @@ func (x *Node) String() string {
 func (*Node) ProtoMessage() {}
 
 func (x *Node) ProtoReflect() protoreflect.Message {
-	mi := &file_gosdn_topology_node_proto_msgTypes[0]
+	mi := &file_gosdn_topology_node_proto_msgTypes[1]
 	if protoimpl.UnsafeEnabled && x != nil {
 		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 		if ms.LoadMessageInfo() == nil {
@@ -61,7 +108,7 @@ func (x *Node) ProtoReflect() protoreflect.Message {
 
 // Deprecated: Use Node.ProtoReflect.Descriptor instead.
 func (*Node) Descriptor() ([]byte, []int) {
-	return file_gosdn_topology_node_proto_rawDescGZIP(), []int{0}
+	return file_gosdn_topology_node_proto_rawDescGZIP(), []int{1}
 }
 
 func (x *Node) GetId() string {
@@ -90,14 +137,17 @@ var file_gosdn_topology_node_proto_rawDesc = []byte{
 	0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2e, 0x70, 0x72, 0x6f,
 	0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, 0x6e, 0x61, 0x70, 0x69, 0x76,
 	0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61,
-	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x2a, 0x0a, 0x04, 0x4e,
-	0x6f, 0x64, 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, 0x42, 0x34, 0x5a, 0x32, 0x63, 0x6f, 0x64, 0x65, 0x2e,
-	0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64, 0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65,
-	0x74, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x67,
-	0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x62, 0x06, 0x70,
-	0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x34, 0x0a, 0x08, 0x4d,
+	0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75,
+	0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+	0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
+	0x6e, 0x22, 0x2a, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 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, 0x42, 0x34, 0x5a,
+	0x32, 0x63, 0x6f, 0x64, 0x65, 0x2e, 0x66, 0x62, 0x69, 0x2e, 0x68, 0x2d, 0x64, 0x61, 0x2e, 0x64,
+	0x65, 0x2f, 0x64, 0x61, 0x6e, 0x65, 0x74, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x61, 0x70,
+	0x69, 0x2f, 0x67, 0x6f, 0x2f, 0x67, 0x6f, 0x73, 0x64, 0x6e, 0x2f, 0x74, 0x6f, 0x70, 0x6f, 0x6c,
+	0x6f, 0x67, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -112,9 +162,10 @@ func file_gosdn_topology_node_proto_rawDescGZIP() []byte {
 	return file_gosdn_topology_node_proto_rawDescData
 }
 
-var file_gosdn_topology_node_proto_msgTypes = make([]protoimpl.MessageInfo, 1)
+var file_gosdn_topology_node_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
 var file_gosdn_topology_node_proto_goTypes = []interface{}{
-	(*Node)(nil), // 0: gosdn.topology.Node
+	(*Metadata)(nil), // 0: gosdn.topology.Metadata
+	(*Node)(nil),     // 1: gosdn.topology.Node
 }
 var file_gosdn_topology_node_proto_depIdxs = []int32{
 	0, // [0:0] is the sub-list for method output_type
@@ -131,6 +182,18 @@ func file_gosdn_topology_node_proto_init() {
 	}
 	if !protoimpl.UnsafeEnabled {
 		file_gosdn_topology_node_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Metadata); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_gosdn_topology_node_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 			switch v := v.(*Node); i {
 			case 0:
 				return &v.state
@@ -149,7 +212,7 @@ func file_gosdn_topology_node_proto_init() {
 			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 			RawDescriptor: file_gosdn_topology_node_proto_rawDesc,
 			NumEnums:      0,
-			NumMessages:   1,
+			NumMessages:   2,
 			NumExtensions: 0,
 			NumServices:   0,
 		},
diff --git a/api/openapiv2/gosdn_northbound.swagger.json b/api/openapiv2/gosdn_northbound.swagger.json
index 1e83ff86a42e2c5caa0874196388e5bccc5a3fc2..7732e02a12841b8fe2961ac65d566017e288ab05 100644
--- a/api/openapiv2/gosdn_northbound.swagger.json
+++ b/api/openapiv2/gosdn_northbound.swagger.json
@@ -2921,6 +2921,15 @@
       ],
       "default": "STATUS_UNSPECIFIED"
     },
+    "gosdnconflictMetadata": {
+      "type": "object",
+      "properties": {
+        "resourceVersion": {
+          "type": "string",
+          "format": "int64"
+        }
+      }
+    },
     "gosdncoreStatus": {
       "type": "string",
       "enum": [
@@ -3937,6 +3946,9 @@
         },
         "token": {
           "type": "string"
+        },
+        "metadata": {
+          "$ref": "#/definitions/gosdnconflictMetadata"
         }
       }
     },
diff --git a/api/proto/gosdn/conflict/conflict.proto b/api/proto/gosdn/conflict/conflict.proto
new file mode 100644
index 0000000000000000000000000000000000000000..d95c41e1705b775e2ef88c04241e0633b3cb8e15
--- /dev/null
+++ b/api/proto/gosdn/conflict/conflict.proto
@@ -0,0 +1,11 @@
+syntax = "proto3";
+
+package gosdn.conflict;
+
+import "google/protobuf/descriptor.proto";
+
+option go_package = "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict";
+
+message Metadata {
+    int64 resourceVersion = 1;
+}
diff --git a/api/proto/gosdn/rbac/user.proto b/api/proto/gosdn/rbac/user.proto
index 8de04465cc4add2b4223930157118d5e6858cab1..71d578117095d3b51f32d511920b0b7925ccc8bd 100644
--- a/api/proto/gosdn/rbac/user.proto
+++ b/api/proto/gosdn/rbac/user.proto
@@ -7,6 +7,7 @@ import "google/protobuf/descriptor.proto";
 import "protoc-gen-openapiv2/options/annotations.proto";
 
 import "gosdn/rbac/rbac.proto";
+import "gosdn/conflict/conflict.proto";
 
 option go_package = "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac";
 
@@ -61,6 +62,7 @@ message User {
     map<string, string> roles = 3; // Key = pnd uuid, value= role name
     string password = 4;
     string token = 5;
+    conflict.Metadata metadata = 6;
 }
 
 // CreateUsers
diff --git a/api/proto/gosdn/topology/node.proto b/api/proto/gosdn/topology/node.proto
index ca06fab019f59cd8584b2dbe4f6b4d40b34dd267..e6ac7e2702f2863a9a0ca18e0ce26734a0a5d00a 100644
--- a/api/proto/gosdn/topology/node.proto
+++ b/api/proto/gosdn/topology/node.proto
@@ -9,6 +9,10 @@ import "protoc-gen-openapiv2/options/annotations.proto";
 
 option go_package = "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/topology";
 
+message Metadata {
+    int64 resourceVersion = 1;
+}
+
 message Node {
     string id = 1;
     string name = 2;
diff --git a/cli/cmd/userUpdate.go b/cli/cmd/userUpdate.go
index dc1d5d48a86bfde6e341270846c049705216f5f1..7ff50486c9fb9fa8e9ea41138c9d6cbd8dad3211 100644
--- a/cli/cmd/userUpdate.go
+++ b/cli/cmd/userUpdate.go
@@ -34,6 +34,7 @@ package cmd
 import (
 	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
 	"code.fbi.h-da.de/danet/gosdn/controller/api"
+	"github.com/google/uuid"
 	log "github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"github.com/spf13/viper"
@@ -48,6 +49,15 @@ var userUpdateCmd = &cobra.Command{
     role is optional but needed to operate on PNDs.`,
 
 	RunE: func(cmd *cobra.Command, args []string) error {
+		exisitingUser, err := api.GetUser(
+			createContextWithAuthorization(),
+			viper.GetString("controllerAPIEndpoint"),
+			nbUserName,
+			uuid.Nil,
+		)
+		if err != nil {
+			return err
+		}
 
 		roles := map[string]string{}
 		// only active pnd for now, add option for additional param later
@@ -57,6 +67,7 @@ var userUpdateCmd = &cobra.Command{
 		users := []*apb.User{
 			{
 				Id:       nbUserID,
+				Metadata: exisitingUser.User.Metadata,
 				Name:     nbUserName,
 				Password: nbUserPwd,
 				Roles:    roles,
diff --git a/controller/api/apiUtil_test.go b/controller/api/apiUtil_test.go
index cc01aebb9dae75ae39d959bf59deaf155bc8db1e..78ae66d8bfbcc64121370f53f05840feaf702f6f 100644
--- a/controller/api/apiUtil_test.go
+++ b/controller/api/apiUtil_test.go
@@ -4,6 +4,7 @@ import (
 	"encoding/base64"
 	"time"
 
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
 	rbacImpl "code.fbi.h-da.de/danet/gosdn/controller/rbac"
 	"code.fbi.h-da.de/danet/gosdn/controller/store"
@@ -82,7 +83,7 @@ func createTestUsers() error {
 	}
 
 	for _, u := range users {
-		err := userService.Add(rbacImpl.NewUser(u.ID(), u.Name(), u.Roles, u.Password, "", salt))
+		err := userService.Add(rbacImpl.NewUser(u.ID(), u.Name(), u.Roles, u.Password, "", salt, conflict.Metadata{ResourceVersion: 0}))
 		if err != nil {
 			return err
 		}
diff --git a/controller/api/user_test.go b/controller/api/user_test.go
index afa2f6dc6aa0f3bc9edbde0030dab5f20d74b31d..b08407e6745d939714700f9a69e5eef50da0caa2 100644
--- a/controller/api/user_test.go
+++ b/controller/api/user_test.go
@@ -5,6 +5,7 @@ import (
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
 	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
 	"github.com/google/uuid"
 	"google.golang.org/grpc/metadata"
@@ -38,6 +39,9 @@ func TestCreateUsers(t *testing.T) {
 						Roles:    map[string]string{pndID: "s"},
 						Password: "roh",
 						Token:    "da",
+						Metadata: &conflict.Metadata{
+							ResourceVersion: 1,
+						},
 					},
 				},
 			},
@@ -208,8 +212,9 @@ func TestUpdateUsers(t *testing.T) {
 				addr: testAPIEndpoint,
 				users: []*apb.User{
 					{
-						Id:   adminID,
-						Name: "sth Else",
+						Id:       adminID,
+						Name:     "sth Else",
+						Metadata: &conflict.Metadata{},
 					},
 				},
 			},
diff --git a/controller/conflict/versioning.go b/controller/conflict/versioning.go
new file mode 100644
index 0000000000000000000000000000000000000000..1d65c29dfba6d8b19408ad9b4cefeda4f3e38df4
--- /dev/null
+++ b/controller/conflict/versioning.go
@@ -0,0 +1,10 @@
+package conflict
+
+import "time"
+
+// Metadata are additional information that every entity persisted in a store must provide.
+type Metadata struct {
+	ResourceVersion int       `json:"resource_version,omitempty" bson:"resource_version,omitempty"`
+	LastUpdated     time.Time `json:"last_updated,omitempty" bson:"last_updated,omitempty"`
+	CreatedAt       time.Time `json:"created_at,omitempty" bson:"created_at,omitempty"`
+}
diff --git a/controller/controller.go b/controller/controller.go
index 6ea0fb68c34168df90896266c35353811ef7196a..fbc888b9c1e19804fa7edcaa55127bfcb4527f06 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -32,6 +32,7 @@ import (
 	apps "code.fbi.h-da.de/danet/gosdn/controller/app"
 
 	"code.fbi.h-da.de/danet/gosdn/controller/config"
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	eventservice "code.fbi.h-da.de/danet/gosdn/controller/eventService"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
@@ -304,7 +305,7 @@ func ensureDefaultUserExists() error {
 
 		hashedPassword := base64.RawStdEncoding.EncodeToString(argon2.IDKey([]byte(generatedPassword), []byte(salt), 1, 64*1024, 4, 32))
 
-		err = c.userService.Add(rbacImpl.NewUser(uuid.New(), defaultUserName, map[string]string{config.BasePndUUID.String(): "admin"}, string(hashedPassword), "", salt))
+		err = c.userService.Add(rbacImpl.NewUser(uuid.New(), defaultUserName, map[string]string{config.BasePndUUID.String(): "admin"}, string(hashedPassword), "", salt, conflict.Metadata{}))
 		if err != nil {
 			return err
 		}
diff --git a/controller/interfaces/rbac/rbacService.go b/controller/interfaces/rbac/rbacService.go
index eddfbfce11efd9775a5ca018831997e65ae9d6d9..8aadf7f09d6ac1a79761d1caa97f37400abfdccb 100644
--- a/controller/interfaces/rbac/rbacService.go
+++ b/controller/interfaces/rbac/rbacService.go
@@ -1,6 +1,7 @@
 package rbac
 
 import (
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/store"
 )
 
@@ -21,6 +22,7 @@ type LoadedUser struct {
 	Password string            `json:"password"`
 	Token    string            `json:"token,omitempty"`
 	Salt     string            `json:"salt" bson:"salt"`
+	Metadata conflict.Metadata `json:"metadata" bson:"metadata"`
 }
 
 // RoleService describes an interface for role service implementations.
diff --git a/controller/interfaces/rbac/user.go b/controller/interfaces/rbac/user.go
index 0cec5417b5bb991ce448c53bee34461742043d30..51051b4dda64cc0d8d1d4dd94304d67945112827 100644
--- a/controller/interfaces/rbac/user.go
+++ b/controller/interfaces/rbac/user.go
@@ -1,6 +1,10 @@
 package rbac
 
-import "github.com/google/uuid"
+import (
+	"github.com/google/uuid"
+
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
+)
 
 // User represents an User which is managed by rbac.
 type User interface {
@@ -11,4 +15,5 @@ type User interface {
 	GetToken() string
 	SetToken(string)
 	GetSalt() string
+	GetMetadata() conflict.Metadata
 }
diff --git a/controller/northbound/server/test_util_test.go b/controller/northbound/server/test_util_test.go
index 4a4202e0470fea150b8ad3aa74f3cb28f022c2ea..e32c7d8011801a4bfdccc6200663e5df2a487572 100644
--- a/controller/northbound/server/test_util_test.go
+++ b/controller/northbound/server/test_util_test.go
@@ -7,6 +7,7 @@ import (
 	"testing"
 
 	spb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/southbound"
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkdomain"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/networkelement"
 	rbacInterfaces "code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
@@ -110,7 +111,7 @@ func createTestUsers(userService rbacInterfaces.UserService) error {
 	}
 
 	for _, u := range users {
-		err := userService.Add(rbac.NewUser(u.ID(), u.Name(), u.Roles, u.Password, "", salt))
+		err := userService.Add(rbac.NewUser(u.ID(), u.Name(), u.Roles, u.Password, "", salt, conflict.Metadata{ResourceVersion: 0}))
 		if err != nil {
 			return err
 		}
diff --git a/controller/northbound/server/user.go b/controller/northbound/server/user.go
index 3288087fd768ece35405e6f63a82096de102e1a8..239823c2568c971e929b167f7aba0671e0bf9055 100644
--- a/controller/northbound/server/user.go
+++ b/controller/northbound/server/user.go
@@ -6,7 +6,9 @@ import (
 	"fmt"
 	"time"
 
+	cpb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
 	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/metrics"
 	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
 	"code.fbi.h-da.de/danet/gosdn/controller/store"
@@ -63,7 +65,9 @@ func (u UserServer) CreateUsers(ctx context.Context, request *apb.CreateUsersReq
 
 		hashedPassword := base64.RawStdEncoding.EncodeToString(argon2.IDKey([]byte(user.Password), []byte(salt), 1, 64*1024, 4, 32))
 
-		user := rbac.NewUser(uuid.New(), user.Name, roles, string(hashedPassword), user.Token, salt)
+		user := rbac.NewUser(uuid.New(), user.Name, roles, string(hashedPassword), user.Token, salt, conflict.Metadata{
+			ResourceVersion: int(user.Metadata.ResourceVersion),
+		})
 		err = u.userService.Add(user)
 		if err != nil {
 			log.Error(err)
@@ -97,6 +101,9 @@ func (u UserServer) GetUser(ctx context.Context, request *apb.GetUserRequest) (*
 		Id:    userData.ID().String(),
 		Name:  userData.Name(),
 		Roles: userData.GetRoles(),
+		Metadata: &cpb.Metadata{
+			ResourceVersion: int64(userData.GetMetadata().ResourceVersion),
+		},
 	}
 
 	return &apb.GetUserResponse{
@@ -123,6 +130,9 @@ func (u UserServer) GetUsers(ctx context.Context, request *apb.GetUsersRequest)
 			Id:    u.ID().String(),
 			Name:  u.Name(),
 			Roles: u.GetRoles(),
+			Metadata: &cpb.Metadata{
+				ResourceVersion: int64(u.GetMetadata().ResourceVersion),
+			},
 		})
 	}
 
@@ -152,9 +162,13 @@ func (u UserServer) UpdateUsers(ctx context.Context, request *apb.UpdateUsersReq
 
 		hashedPassword := base64.RawStdEncoding.EncodeToString(argon2.IDKey([]byte(user.Password), []byte(storedUser.GetSalt()), 1, 64*1024, 4, 32))
 
-		userToUpdate := rbac.NewUser(uid, user.Name, user.Roles, string(hashedPassword), user.Token, storedUser.GetSalt())
+		userToUpdate := rbac.NewUser(uid, user.Name, user.Roles, string(hashedPassword), user.Token, storedUser.GetSalt(), conflict.Metadata{
+			ResourceVersion: int(user.Metadata.ResourceVersion)})
+
+		usr, _ := userToUpdate.(*rbac.User)
+		usr.Metadata.ResourceVersion = int(user.Metadata.ResourceVersion)
 
-		err = u.userService.Update(userToUpdate)
+		err = u.userService.Update(usr)
 		if err != nil {
 			return nil, status.Errorf(codes.Aborted, "could not update user %v", err)
 		}
diff --git a/controller/northbound/server/user_test.go b/controller/northbound/server/user_test.go
index 1e447266e3c8503ceccaa6afd87794eddf40cfcc..41ffef625d1b955148353dc85da944c113461264 100644
--- a/controller/northbound/server/user_test.go
+++ b/controller/northbound/server/user_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 	"time"
 
+	"code.fbi.h-da.de/danet/gosdn/api/go/gosdn/conflict"
 	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
 	eventservice "code.fbi.h-da.de/danet/gosdn/controller/eventService"
 	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
@@ -53,6 +54,9 @@ func TestUser_CreateUsers(t *testing.T) {
 							Roles:    map[string]string{pndID: "userTestRole"},
 							Password: "pass",
 							Token:    "",
+							Metadata: &conflict.Metadata{
+								ResourceVersion: 0,
+							},
 						},
 					},
 				},
@@ -214,8 +218,11 @@ func TestUser_UpdateUsers(t *testing.T) {
 			name: "default update user",
 			args: args{ctx: context.TODO(),
 				request: &apb.UpdateUsersRequest{User: []*apb.User{
-					{Id: adminID,
-						Name: "sth Else"},
+					{
+						Id:       adminID,
+						Name:     "sth Else",
+						Metadata: &conflict.Metadata{},
+					},
 				},
 				},
 			},
@@ -227,8 +234,11 @@ func TestUser_UpdateUsers(t *testing.T) {
 			name: "error update user",
 			args: args{ctx: context.TODO(),
 				request: &apb.UpdateUsersRequest{User: []*apb.User{
-					{Id: uuid.NewString(),
-						Name: "not a user"},
+					{
+						Id:       uuid.NewString(),
+						Name:     "not a user",
+						Metadata: &conflict.Metadata{},
+					},
 				},
 				},
 			},
diff --git a/controller/rbac/databaseUserStore.go b/controller/rbac/databaseUserStore.go
index c478610e680913bc979a77fd03b93efbfd8d6625..fe39f26c2b12a2cbb4981ce3b2d89b970db0bac8 100644
--- a/controller/rbac/databaseUserStore.go
+++ b/controller/rbac/databaseUserStore.go
@@ -13,6 +13,7 @@ import (
 	"go.mongodb.org/mongo-driver/bson/primitive"
 	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
+	"go.mongodb.org/mongo-driver/mongo/writeconcern"
 )
 
 // DatabaseUserStore is used to store users in database.
@@ -187,24 +188,69 @@ func (s *DatabaseUserStore) Update(userToUpdate rbac.User) (err error) {
 		}
 	}()
 
-	update := bson.D{primitive.E{Key: "$set", Value: userToUpdate}}
+	// 1. Start Transaction
+	wcMajority := writeconcern.New(writeconcern.WMajority())
+	wcMajorityCollectionOpts := options.Collection().SetWriteConcern(wcMajority)
+	userCollection := client.Database(database.DatabaseName).Collection(s.userStoreName, wcMajorityCollectionOpts)
 
-	upsert := false
-	after := options.After
-	opt := options.FindOneAndUpdateOptions{
-		Upsert:         &upsert,
-		ReturnDocument: &after,
+	session, err := client.StartSession()
+	if err != nil {
+		return err
 	}
+	defer session.EndSession(ctx)
 
-	err = client.Database(database.DatabaseName).
-		Collection(s.userStoreName).
-		FindOneAndUpdate(
-			ctx, bson.M{"_id": userToUpdate.ID().String()}, update, &opt).
-		Decode(&updatedLoadedUser)
+	// 2. Fetch exisiting Entity
+	existingNode, err := s.getByID(userToUpdate.ID())
 	if err != nil {
-		log.Printf("Could not update User: %v", err)
+		return err
+	}
+
+	// 3. Check if Entity.Metadata.ResourceVersion == UpdatedEntity.Metadata.ResourceVersion
+	if userToUpdate.GetMetadata().ResourceVersion != existingNode.Metadata.ResourceVersion {
+		// 3.1.1 End transaction
+		// 3.1.2 If no -> return error
+
+		return fmt.Errorf(
+			"resource version %d of provided user %s is older or newer than %d in the store",
+			userToUpdate.GetMetadata().ResourceVersion,
+			userToUpdate.ID().String(), existingNode.Metadata.ResourceVersion,
+		)
+	}
+
+	// 3.2.1 If yes -> Update entity in callback
+	callback := func(sessCtx mongo.SessionContext) (interface{}, error) {
+		// Important: You must pass sessCtx as the Context parameter to the operations for them to be executed in the
+		// transaction.
+
+		u, _ := userToUpdate.(*User)
+		u.Metadata.ResourceVersion = u.Metadata.ResourceVersion + 1
+
+		update := bson.D{primitive.E{Key: "$set", Value: u}}
 
-		return customerrs.CouldNotUpdateError{Identifier: userToUpdate.ID(), Type: userToUpdate, Err: err}
+		upsert := false
+		after := options.After
+		opt := options.FindOneAndUpdateOptions{
+			Upsert:         &upsert,
+			ReturnDocument: &after,
+		}
+
+		err = userCollection.
+			FindOneAndUpdate(
+				ctx, bson.M{"_id": userToUpdate.ID().String()}, update, &opt).
+			Decode(&updatedLoadedUser)
+		if err != nil {
+			log.Printf("Could not update User: %v", err)
+
+			return nil, customerrs.CouldNotUpdateError{Identifier: userToUpdate.ID(), Type: userToUpdate, Err: err}
+		}
+
+		// 3.2.2 End transaction
+		return "", nil
+	}
+
+	_, err = session.WithTransaction(ctx, callback)
+	if err != nil {
+		return err
 	}
 
 	return nil
diff --git a/controller/rbac/rbacService.go b/controller/rbac/rbacService.go
index 414ad1884b8fcfe43e6f5c16c6c6ddc3ff26d9da..0a1d26a478b030824173a2e1d70589c6248ee308 100644
--- a/controller/rbac/rbacService.go
+++ b/controller/rbac/rbacService.go
@@ -126,7 +126,7 @@ func (s *UserService) GetAll() ([]rbac.User, error) {
 }
 
 func (s *UserService) createUserFromStore(loadedUser rbac.LoadedUser) rbac.User {
-	return NewUser(uuid.MustParse(loadedUser.ID), loadedUser.UserName, loadedUser.Roles, loadedUser.Password, loadedUser.Token, loadedUser.Salt)
+	return NewUser(uuid.MustParse(loadedUser.ID), loadedUser.UserName, loadedUser.Roles, loadedUser.Password, loadedUser.Token, loadedUser.Salt, loadedUser.Metadata)
 }
 
 // RoleService provides a role service implementation.
diff --git a/controller/rbac/user.go b/controller/rbac/user.go
index 19d9dc4f6e3e7ba79fbd19821248e0ac3528d3df..d0b5ae14fa35d299db531500a0b0d286d127fc89 100644
--- a/controller/rbac/user.go
+++ b/controller/rbac/user.go
@@ -3,6 +3,7 @@ package rbac
 import (
 	"encoding/json"
 
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
 	"github.com/google/uuid"
 	"go.mongodb.org/mongo-driver/bson"
@@ -11,6 +12,7 @@ import (
 // User represents the data of a user for access control and is stored in a storage.
 type User struct {
 	UserID   uuid.UUID         `json:"_id"`
+	Metadata conflict.Metadata `json:"metadata"`
 	UserName string            `json:"username"`
 	Roles    map[string]string `json:"roles,omitempty"`
 	Password string            `json:"password"`
@@ -24,7 +26,9 @@ func NewUser(id uuid.UUID,
 	roles map[string]string,
 	pw string,
 	token string,
-	salt string) rbac.User {
+	salt string,
+	metadata conflict.Metadata,
+) rbac.User {
 	return &User{
 		UserID:   id,
 		UserName: name,
@@ -32,6 +36,7 @@ func NewUser(id uuid.UUID,
 		Password: pw,
 		Token:    token,
 		Salt:     salt,
+		Metadata: metadata,
 	}
 }
 
@@ -40,6 +45,11 @@ func (u *User) ID() uuid.UUID {
 	return u.UserID
 }
 
+// GetMetadata returns the metadata of a user.
+func (u *User) GetMetadata() conflict.Metadata {
+	return u.Metadata
+}
+
 // Name returns the name of the user.
 func (u *User) Name() string {
 	return u.UserName
@@ -84,6 +94,7 @@ func (u *User) MarshalJSON() ([]byte, error) {
 		Password string            `json:"password"`
 		Token    string            `json:"token,omitempty"`
 		Salt     string            `json:"salt"`
+		Metadata conflict.Metadata `json:"metadata"`
 	}{
 		UserID:   u.ID(),
 		UserName: u.Name(),
@@ -91,6 +102,7 @@ func (u *User) MarshalJSON() ([]byte, error) {
 		Password: u.Password,
 		Token:    u.Token,
 		Salt:     u.Salt,
+		Metadata: u.Metadata,
 	})
 }
 
@@ -103,6 +115,7 @@ func (u *User) MarshalBSON() ([]byte, error) {
 		Password string            `bson:"password"`
 		Token    string            `bson:"token,omitempty"`
 		Salt     string            `bson:"salt"`
+		Metadata conflict.Metadata `bson:"metadata"`
 	}{
 		UserID:   u.ID().String(),
 		UserName: u.Name(),
@@ -110,5 +123,6 @@ func (u *User) MarshalBSON() ([]byte, error) {
 		Password: u.Password,
 		Token:    u.Token,
 		Salt:     u.Salt,
+		Metadata: u.Metadata,
 	})
 }
diff --git a/controller/rbac/userFileSystemStore_test.go b/controller/rbac/userFileSystemStore_test.go
index 29f76a6c3d019fb1940765677a91538f916e0830..847d2be830b558624871a00c75c5496fe9eab324 100644
--- a/controller/rbac/userFileSystemStore_test.go
+++ b/controller/rbac/userFileSystemStore_test.go
@@ -4,6 +4,7 @@ import (
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/rbac"
 	"code.fbi.h-da.de/danet/gosdn/controller/store"
 	"github.com/google/uuid"
@@ -17,7 +18,7 @@ func TestFileSystemUserStore_Add(t *testing.T) {
 	}
 	var idtest uuid.UUID
 	var role map[string]string
-	testingUser := NewUser(idtest, "testUser", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw")
+	testingUser := NewUser(idtest, "testUser", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
 	tests := []struct {
 		name    string
 		args    args
@@ -48,7 +49,7 @@ func TestFileSystemUserStore_Delete(t *testing.T) {
 	}
 	var idtest uuid.UUID
 	var role map[string]string
-	testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw")
+	testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
 	tests := []struct {
 		name    string
 		args    args
@@ -81,7 +82,7 @@ func TestFileSystemUserStore_Get(t *testing.T) {
 	}
 	var idtest uuid.UUID
 	var role map[string]string
-	testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw")
+	testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
 	tests := []struct {
 		name    string
 		args    args
@@ -120,9 +121,9 @@ func TestFileSystemUserStore_GetAll(t *testing.T) {
 
 	var idtest uuid.UUID
 	var role map[string]string
-	testingUser1 := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbevasf", "svswvasfbwasv")
-	testingUser2 := NewUser(idtest, "", role, "abc", "svsvsfbdwbwbevsav", "svswvasfbwadf")
-	testingUser3 := NewUser(idtest, "", role, "lmn", "svsvsfbdwbwbevscv", "svswvasfbwasd")
+	testingUser1 := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbevasf", "svswvasfbwasv", conflict.Metadata{})
+	testingUser2 := NewUser(idtest, "", role, "abc", "svsvsfbdwbwbevsav", "svswvasfbwadf", conflict.Metadata{})
+	testingUser3 := NewUser(idtest, "", role, "lmn", "svsvsfbdwbwbevscv", "svswvasfbwasd", conflict.Metadata{})
 	tests := []struct {
 		name    string
 		want    []rbac.LoadedUser
@@ -172,7 +173,7 @@ func TestFileSystemUserStore_Update(t *testing.T) {
 	}
 	var idtest uuid.UUID
 	var role map[string]string
-	testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw")
+	testingUser := NewUser(idtest, "", role, "xyz", "svsvsfbdwbwbev", "svswvasfbw", conflict.Metadata{})
 	tests := []struct {
 		name    string
 		args    args
diff --git a/controller/topology/links/link.go b/controller/topology/links/link.go
index be6a79d06441cd71129f75ba24464d1afdcd5154..44b071fd40cfe743c13d20bb6892fdaee152c2a4 100644
--- a/controller/topology/links/link.go
+++ b/controller/topology/links/link.go
@@ -1,6 +1,7 @@
 package links
 
 import (
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/topology/nodes"
 	"code.fbi.h-da.de/danet/gosdn/controller/topology/ports"
 	"github.com/google/uuid"
@@ -8,12 +9,13 @@ import (
 
 // Link is a representation of a physical or virtual link between two nodes and their ports.
 type Link struct {
-	ID         uuid.UUID  `bson:"_id"`
-	Name       string     `bson:"name,omitempty"`
-	SourceNode nodes.Node `bson:"source_node,omitempty"`
-	TargetNode nodes.Node `bson:"target_node,omitempty"`
-	SourcePort ports.Port `bson:"source_port,omitempty"`
-	TargetPort ports.Port `bson:"target_port,omitempty"`
+	ID         uuid.UUID         `bson:"_id"`
+	Metadata   conflict.Metadata `bson:"metadata"`
+	Name       string            `bson:"name,omitempty"`
+	SourceNode nodes.Node        `bson:"source_node,omitempty"`
+	TargetNode nodes.Node        `bson:"target_node,omitempty"`
+	SourcePort ports.Port        `bson:"source_port,omitempty"`
+	TargetPort ports.Port        `bson:"target_port,omitempty"`
 }
 
 // GetID returns the id of a link.
diff --git a/controller/topology/nodes/node.go b/controller/topology/nodes/node.go
index a9c836fcd8e316bb3b74f31d7ae894c9c718a630..90f689c785b3df313ffff360ef0088c176e1db1a 100644
--- a/controller/topology/nodes/node.go
+++ b/controller/topology/nodes/node.go
@@ -1,13 +1,15 @@
 package nodes
 
 import (
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"github.com/google/uuid"
 )
 
 // Node is a representation of a network element.
 type Node struct {
-	ID   uuid.UUID `bson:"_id"`
-	Name string    `bson:"name"`
+	ID       uuid.UUID         `bson:"_id"`
+	Metadata conflict.Metadata `bson:"metadata"`
+	Name     string            `bson:"name"`
 }
 
 // GetID returns the id of a node.
diff --git a/controller/topology/nodes/nodeService_test.go b/controller/topology/nodes/nodeService_test.go
index a64a1e240cddd74efb9bdaefc9b69ae6c9ded7a4..3eca6b3684c55db9c0ec42e20b3c80a2768fff65 100644
--- a/controller/topology/nodes/nodeService_test.go
+++ b/controller/topology/nodes/nodeService_test.go
@@ -4,6 +4,7 @@ import (
 	"reflect"
 	"testing"
 
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	eventservice "code.fbi.h-da.de/danet/gosdn/controller/eventService"
 	"code.fbi.h-da.de/danet/gosdn/controller/interfaces/event"
 	query "code.fbi.h-da.de/danet/gosdn/controller/store"
@@ -16,6 +17,9 @@ func getTestNode() Node {
 	return Node{
 		ID:   uuid.MustParse("44fb4aa4-c53c-4cf9-a081-5aabc61c7610"),
 		Name: "Test-Node",
+		Metadata: conflict.Metadata{
+			ResourceVersion: 0,
+		},
 	}
 }
 
@@ -163,7 +167,7 @@ func TestNodeService_Update(t *testing.T) {
 				t.Errorf("NodeService.Update() error = %v, wantErr %v", err, tt.wantErr)
 			}
 
-			updatedNode, err := p.Get(query.Query(tt.args.node))
+			updatedNode, err := p.Get(query.Query{ID: tt.args.node.ID, Name: tt.args.node.Name})
 			if err != nil {
 				t.Errorf("NodeService.Get() failed %v", err)
 			}
diff --git a/controller/topology/nodes/nodeStore.go b/controller/topology/nodes/nodeStore.go
index cd4f28fbcbda6ec972deddee4235426e8cccee6e..f5bb7f4c77ff04e48f2a40bfe94b58bfda34a4a8 100644
--- a/controller/topology/nodes/nodeStore.go
+++ b/controller/topology/nodes/nodeStore.go
@@ -2,6 +2,7 @@ package nodes
 
 import (
 	"fmt"
+	"time"
 
 	"code.fbi.h-da.de/danet/gosdn/controller/customerrs"
 	"code.fbi.h-da.de/danet/gosdn/controller/nucleus/database"
@@ -10,7 +11,9 @@ import (
 	"github.com/google/uuid"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/bson/primitive"
+	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
+	"go.mongodb.org/mongo-driver/mongo/writeconcern"
 )
 
 // Store defines a NodeStore interface.
@@ -150,6 +153,10 @@ func (s *DatabaseNodeStore) Add(node Node) (err error) {
 		}
 	}()
 
+	node.Metadata.ResourceVersion = 0
+	node.Metadata.CreatedAt = time.Now()
+	node.Metadata.LastUpdated = time.Now()
+
 	_, err = client.Database(database.DatabaseName).
 		Collection(s.storeName).
 		InsertOne(ctx, node)
@@ -173,22 +180,63 @@ func (s *DatabaseNodeStore) Update(node Node) (err error) {
 		}
 	}()
 
-	update := bson.D{primitive.E{Key: "$set", Value: node}}
+	// 1. Start Transaction
+	wcMajority := writeconcern.New(writeconcern.WMajority())
+	wcMajorityCollectionOpts := options.Collection().SetWriteConcern(wcMajority)
+	nodeCollection := client.Database(database.DatabaseName).Collection(s.storeName, wcMajorityCollectionOpts)
 
-	upsert := false
-	after := options.After
-	opt := options.FindOneAndUpdateOptions{
-		Upsert:         &upsert,
-		ReturnDocument: &after,
+	session, err := client.StartSession()
+	if err != nil {
+		return err
 	}
+	defer session.EndSession(ctx)
 
-	err = client.Database(database.DatabaseName).
-		Collection(s.storeName).
-		FindOneAndUpdate(
-			ctx, bson.M{"_id": node.ID.String()}, update, &opt).
-		Decode(&updatedLoadedNodes)
+	// 2. Fetch exisiting Entity
+	existingNode, err := s.getByID(node.ID)
 	if err != nil {
-		return customerrs.CouldNotUpdateError{Identifier: node.ID, Type: node, Err: err}
+		return err
+	}
+
+	// 3. Check if Entity.Metadata.ResourceVersion == UpdatedEntity.Metadata.ResourceVersion
+	if node.Metadata.ResourceVersion != existingNode.Metadata.ResourceVersion {
+		// 3.1.1 End transaction
+		// 3.1.2 If no -> return error
+
+		return fmt.Errorf(
+			"resource version %d of provided node %s is older or newer than %d in the store",
+			node.Metadata.ResourceVersion,
+			node.ID.String(), existingNode.Metadata.ResourceVersion,
+		)
+	}
+
+	// 3.2.1 If yes -> Update entity in callback
+	callback := func(sessCtx mongo.SessionContext) (interface{}, error) {
+		// Important: You must pass sessCtx as the Context parameter to the operations for them to be executed in the
+		// transaction.
+		update := bson.D{primitive.E{Key: "$set", Value: node}}
+
+		upsert := false
+		after := options.After
+		opt := options.FindOneAndUpdateOptions{
+			Upsert:         &upsert,
+			ReturnDocument: &after,
+		}
+
+		err = nodeCollection.
+			FindOneAndUpdate(
+				ctx, bson.M{"_id": node.ID.String()}, update, &opt).
+			Decode(&updatedLoadedNodes)
+		if err != nil {
+			return nil, customerrs.CouldNotUpdateError{Identifier: node.ID, Type: node, Err: err}
+		}
+
+		// 3.2.2 End transaction
+		return "", nil
+	}
+
+	_, err = session.WithTransaction(ctx, callback)
+	if err != nil {
+		return err
 	}
 
 	return nil
diff --git a/controller/topology/ports/port.go b/controller/topology/ports/port.go
index 2614f745c574a221f79974eaa95f11217a828187..5248c3b5a47ac63407d6e28727779ad966a105c9 100644
--- a/controller/topology/ports/port.go
+++ b/controller/topology/ports/port.go
@@ -1,6 +1,7 @@
 package ports
 
 import (
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"code.fbi.h-da.de/danet/gosdn/controller/topology/ports/configuration"
 	"github.com/google/uuid"
 )
@@ -8,6 +9,7 @@ import (
 // Port is a representation of physical port on a network element.
 type Port struct {
 	ID            uuid.UUID              `bson:"_id"`
+	Metadata      conflict.Metadata      `bson:"metadata"`
 	Name          string                 `bson:"name,omitempty"`
 	Configuration configuration.IPConfig `bson:"configuration,omitempty"`
 }
diff --git a/controller/topology/routing-tables/route.go b/controller/topology/routing-tables/route.go
index ad7da495d82a6a2fafa7fb938fdb39c1ea68c8cd..746012f37eb752fef877fd1a46c7d3bf585fa068 100644
--- a/controller/topology/routing-tables/route.go
+++ b/controller/topology/routing-tables/route.go
@@ -1,14 +1,16 @@
 package routingtables
 
 import (
+	"code.fbi.h-da.de/danet/gosdn/controller/conflict"
 	"github.com/google/uuid"
 )
 
 // Route is a routing table entry on a network element.
 type Route struct {
-	ID            uuid.UUID `bson:"_id"`
-	TargetIPRange string    `bson:"target_ip_range"`
-	NextHopIP     string    `bson:"next_hop_ip"`
-	PortID        uuid.UUID `bson:"port_id"`
-	Metric        string    `bson:"metric"`
+	ID            uuid.UUID         `bson:"_id"`
+	Metadata      conflict.Metadata `bson:"metadata"`
+	TargetIPRange string            `bson:"target_ip_range"`
+	NextHopIP     string            `bson:"next_hop_ip"`
+	PortID        uuid.UUID         `bson:"port_id"`
+	Metric        string            `bson:"metric"`
 }