From deb4455773cd71d3436510bbeb599f309106ce1d Mon Sep 17 00:00:00 2001 From: Sean Trantalis <18211470+strantalis@users.noreply.github.com> Date: Thu, 13 Feb 2025 20:47:10 -0500 Subject: [PATCH 01/34] feat: add ability to retrieve policy resources by id or name (#1901) Adds an `identifier` `oneof` on the following rpc's - GetAttribute - GetNamespace - GetAttributeValue - GetKeyAccessServer This allows for the ability to query by more than just a `uuid` On the `ListPublicKeys` and `ListPublicKeyMappings` rpc's a new `oneof` field was added so a user could filter by kas `id`, `name` or `uri`. --- Makefile | 8 +- buf.lock | 12 +- docs/grpc/index.html | 199 ++- .../policy/attributes/attributes.swagger.json | 30 +- .../key_access_server_registry.swagger.json | 21 +- .../policy/namespaces/namespaces.swagger.json | 15 +- .../go/policy/attributes/attributes.pb.go | 989 ++++++++------- .../go/policy/attributes/attributes.pb.gw.go | 36 + .../key_access_server_registry.pb.go | 1072 ++++++++++------- .../key_access_server_registry.pb.gw.go | 18 + .../go/policy/namespaces/namespaces.pb.go | 85 +- .../go/policy/namespaces/namespaces.pb.gw.go | 18 + protocol/go/policy/objects.pb.go | 198 +-- protocol/go/policy/unsafe/unsafe.pb.go | 372 +++--- service/integration/attribute_values_test.go | 90 +- service/integration/attributes_test.go | 115 +- service/integration/kas_registry_test.go | 315 ++++- service/integration/namespaces_test.go | 97 +- service/pkg/db/errors.go | 12 + service/policy/attributes/attributes.go | 24 +- service/policy/attributes/attributes.proto | 69 +- service/policy/attributes/attributes_test.go | 242 +++- service/policy/db/attribute_values.go | 35 +- service/policy/db/attributes.go | 35 +- .../policy/db/key_access_server_registry.go | 69 +- service/policy/db/namespaces.go | 33 +- service/policy/db/query.sql | 40 +- service/policy/db/query.sql.go | 153 ++- .../kasregistry/key_access_server_registry.go | 18 +- .../key_access_server_registry.proto | 114 +- .../key_access_server_registry_test.go | 682 ++++++++++- service/policy/namespaces/namespaces.go | 16 +- service/policy/namespaces/namespaces.proto | 33 +- service/policy/namespaces/namespaces_test.go | 149 ++- service/policy/objects.proto | 22 +- service/policy/unsafe/unsafe_test.go | 75 ++ test/policy-service.bats | 6 +- test/tdf-roundtrips.bats | 4 +- 38 files changed, 4074 insertions(+), 1447 deletions(-) create mode 100644 service/policy/unsafe/unsafe_test.go diff --git a/Makefile b/Makefile index d4bc7b530..223f9fa06 100644 --- a/Makefile +++ b/Makefile @@ -45,8 +45,12 @@ proto-lint: fi) go-lint: - for m in $(HAND_MODS); do (cd $$m && golangci-lint run $(LINT_OPTIONS) --path-prefix=$$m) || exit 1; done - + status=0; \ + for m in $(HAND_MODS); do \ + echo "Linting module: $$m"; \ + (cd "$$m" && golangci-lint run $(LINT_OPTIONS) --path-prefix="$$m" ) || status=1; \ + done; \ + exit $$status proto-generate: rm -rf protocol/go/[a-fh-z]* docs/grpc docs/openapi buf generate service diff --git a/buf.lock b/buf.lock index c8ac0410d..10d51eb79 100644 --- a/buf.lock +++ b/buf.lock @@ -2,11 +2,11 @@ version: v2 deps: - name: buf.build/bufbuild/protovalidate - commit: e097f827e65240ac9fd4b1158849a8fc - digest: b5:beda657a164abf9d1bac222e352f14d9a4a8c913ccdb7e5c3dfeda097690f60e8edb27b518c2d8e73b70aecb6ac47fdc3654a1f62b9e09c3566cd4e620628cfd + commit: 63bb56e204954558946a641ef0d68910 + digest: b5:ec5661b2855484eca2043fe61d27eb22673ab926ccd0e849531752eb17b08402fae1382705cee7f7b42d4d9ec56aff72bba7ec6835902cf6f86323c9ac682d16 - name: buf.build/googleapis/googleapis - commit: a86849a25cc04f4dbe9b15ddddfbc488 - digest: b5:a77a2082c596ee6800a23d8cecd021d316eb10565d6cb94532f2d7c567fe6c9a177b5bb123b51a3acb4f1f18d4f54a6da883afcb682919a137a8a37c020509a2 + commit: 83c0f6c19b2f4ea0b0fd84a80e753659 + digest: b5:e9d077ad9d2eaa08a056108a15292a69548880d3a935781c498f2e591e60e531e49e1f5fc1d7356e5f989d3a8540e9885a02df18cb0cecc4ffa439fa4438a09e - name: buf.build/grpc-ecosystem/grpc-gateway - commit: 3f42134f4c564983838425bc43c7a65f - digest: b5:291b947d8ac09492517557e4e72e294788cb8201afc7d0df7bda80fa10931adb60d4d669208a7696bf24f1ecb2a33a16d4c1e766e6f31809248b00343119569b + commit: 4c5ba75caaf84e928b7137ae5c18c26a + digest: b5:c113e62fb3b29289af785866cae062b55ec8ae19ab3f08f3004098928fbca657730a06810b2012951294326b95669547194fa84476b9e9b688d4f8bf77a0691d diff --git a/docs/grpc/index.html b/docs/grpc/index.html index 309ca58dd..3eb649815 100644 --- a/docs/grpc/index.html +++ b/docs/grpc/index.html @@ -5043,13 +5043,48 @@

GetAttributeRequest

id string -

Required

+

Deprecated. Deprecated

+ + + + attribute_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + fqn + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + @@ -5091,13 +5126,48 @@

GetAttributeValueRequest

id string -

Required

+

Deprecated. Deprecated

+ + + + value_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + fqn + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + @@ -6422,13 +6492,55 @@

GetKeyAccessServerRequest< id string -

Required

+

Deprecated. Deprecated

+ + + + kas_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + name + string + +

+ + + + uri + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + @@ -6755,13 +6867,21 @@

ListPublicKeyMappingRequ kas_id string -

Optional - -Future filter by fields -// Optional -string kas_name = 2; -// Optional -string kas_uri = 3;

+

Optional

+ + + + kas_name + string + +

Optional

+ + + + kas_uri + string + +

Optional

@@ -6951,13 +7071,21 @@

ListPublicKeysRequest

kas_id string -

Optional - -Future filter by fields -// Optional -string kas_name = 2; -// Optional -string kas_uri = 3;

+

Optional

+ + + + kas_name + string + +

Optional

+ + + + kas_uri + string + +

Optional

@@ -7574,13 +7702,48 @@

GetNamespaceRequest

id string -

Required

+

Deprecated. Deprecated

+ + + + namespace_id + string + +

option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field

+ + + + fqn + string + +

+ + +

Fields with deprecated option

+ + + + + + + + + + + + + + + +
NameOption
id

true

+ + diff --git a/docs/openapi/policy/attributes/attributes.swagger.json b/docs/openapi/policy/attributes/attributes.swagger.json index 0027fda4e..d9c4593a2 100644 --- a/docs/openapi/policy/attributes/attributes.swagger.json +++ b/docs/openapi/policy/attributes/attributes.swagger.json @@ -249,10 +249,23 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "valueId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fqn", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ @@ -543,10 +556,23 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "attributeId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fqn", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json b/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json index 9cff708cf..a3606167c 100644 --- a/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json +++ b/docs/openapi/policy/kasregistry/key_access_server_registry.swagger.json @@ -168,10 +168,29 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "kasId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "name", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "uri", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/docs/openapi/policy/namespaces/namespaces.swagger.json b/docs/openapi/policy/namespaces/namespaces.swagger.json index 7f435905c..3aa587d3f 100644 --- a/docs/openapi/policy/namespaces/namespaces.swagger.json +++ b/docs/openapi/policy/namespaces/namespaces.swagger.json @@ -189,10 +189,23 @@ "parameters": [ { "name": "id", - "description": "Required", + "description": "Deprecated", "in": "path", "required": true, "type": "string" + }, + { + "name": "namespaceId", + "description": "option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "fqn", + "in": "query", + "required": false, + "type": "string" } ], "tags": [ diff --git a/protocol/go/policy/attributes/attributes.pb.go b/protocol/go/policy/attributes/attributes.pb.go index 30d3b09da..988dcdf05 100644 --- a/protocol/go/policy/attributes/attributes.pb.go +++ b/protocol/go/policy/attributes/attributes.pb.go @@ -380,8 +380,15 @@ type GetAttributeRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/attributes/attributes.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetAttributeRequest_AttributeId + // *GetAttributeRequest_Fqn + Identifier isGetAttributeRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetAttributeRequest) Reset() { @@ -416,6 +423,7 @@ func (*GetAttributeRequest) Descriptor() ([]byte, []int) { return file_policy_attributes_attributes_proto_rawDescGZIP(), []int{6} } +// Deprecated: Marked as deprecated in policy/attributes/attributes.proto. func (x *GetAttributeRequest) GetId() string { if x != nil { return x.Id @@ -423,6 +431,44 @@ func (x *GetAttributeRequest) GetId() string { return "" } +func (m *GetAttributeRequest) GetIdentifier() isGetAttributeRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetAttributeRequest) GetAttributeId() string { + if x, ok := x.GetIdentifier().(*GetAttributeRequest_AttributeId); ok { + return x.AttributeId + } + return "" +} + +func (x *GetAttributeRequest) GetFqn() string { + if x, ok := x.GetIdentifier().(*GetAttributeRequest_Fqn); ok { + return x.Fqn + } + return "" +} + +type isGetAttributeRequest_Identifier interface { + isGetAttributeRequest_Identifier() +} + +type GetAttributeRequest_AttributeId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + AttributeId string `protobuf:"bytes,2,opt,name=attribute_id,json=attributeId,proto3,oneof"` +} + +type GetAttributeRequest_Fqn struct { + Fqn string `protobuf:"bytes,3,opt,name=fqn,proto3,oneof"` +} + +func (*GetAttributeRequest_AttributeId) isGetAttributeRequest_Identifier() {} + +func (*GetAttributeRequest_Fqn) isGetAttributeRequest_Identifier() {} + type GetAttributeResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -818,8 +864,15 @@ type GetAttributeValueRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/attributes/attributes.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetAttributeValueRequest_ValueId + // *GetAttributeValueRequest_Fqn + Identifier isGetAttributeValueRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetAttributeValueRequest) Reset() { @@ -854,6 +907,7 @@ func (*GetAttributeValueRequest) Descriptor() ([]byte, []int) { return file_policy_attributes_attributes_proto_rawDescGZIP(), []int{14} } +// Deprecated: Marked as deprecated in policy/attributes/attributes.proto. func (x *GetAttributeValueRequest) GetId() string { if x != nil { return x.Id @@ -861,6 +915,44 @@ func (x *GetAttributeValueRequest) GetId() string { return "" } +func (m *GetAttributeValueRequest) GetIdentifier() isGetAttributeValueRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetAttributeValueRequest) GetValueId() string { + if x, ok := x.GetIdentifier().(*GetAttributeValueRequest_ValueId); ok { + return x.ValueId + } + return "" +} + +func (x *GetAttributeValueRequest) GetFqn() string { + if x, ok := x.GetIdentifier().(*GetAttributeValueRequest_Fqn); ok { + return x.Fqn + } + return "" +} + +type isGetAttributeValueRequest_Identifier interface { + isGetAttributeValueRequest_Identifier() +} + +type GetAttributeValueRequest_ValueId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + ValueId string `protobuf:"bytes,2,opt,name=value_id,json=valueId,proto3,oneof"` +} + +type GetAttributeValueRequest_Fqn struct { + Fqn string `protobuf:"bytes,3,opt,name=fqn,proto3,oneof"` +} + +func (*GetAttributeValueRequest_ValueId) isGetAttributeValueRequest_Identifier() {} + +func (*GetAttributeValueRequest_Fqn) isGetAttributeValueRequest_Identifier() {} + type GetAttributeValueResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2337,10 +2429,35 @@ var file_policy_attributes_attributes_proto_rawDesc = []byte{ 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x2f, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xbe, + 0x03, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, + 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, + 0x03, 0x66, 0x71, 0x6e, 0x3a, 0xaa, 0x02, 0xba, 0x48, 0xa6, 0x02, 0x1a, 0xa2, 0x01, 0x0a, 0x10, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x50, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, + 0x66, 0x71, 0x6e, 0x27, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, + 0x74, 0x68, 0x1a, 0x3c, 0x21, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x64, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, 0x29, 0x29, 0x29, + 0x1a, 0x7f, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x33, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x71, 0x6e, 0x20, 0x6d, 0x75, 0x73, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x37, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x29, + 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, + 0x29, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, @@ -2412,447 +2529,471 @@ var file_policy_attributes_attributes_proto_rawDesc = []byte{ 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, - 0x34, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, - 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x40, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, - 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, - 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x7a, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, - 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xc5, 0x03, 0x0a, 0x1b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, - 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x64, - 0x12, 0xb4, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x9d, 0x02, 0xba, 0x48, 0x99, 0x02, 0xba, 0x01, 0x8d, 0x02, 0x0a, 0x16, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, - 0x6d, 0x61, 0x74, 0x12, 0xb5, 0x01, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, - 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, - 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, - 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, - 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, - 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, - 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, - 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, - 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, - 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, - 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x01, 0x72, 0x03, 0x18, 0xfd, 0x01, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, - 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x03, - 0x10, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0xd1, 0x01, 0x0a, 0x1b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, - 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, - 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, - 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, - 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, - 0x61, 0x76, 0x69, 0x6f, 0x72, 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x52, 0x07, 0x6d, 0x65, 0x6d, - 0x62, 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3b, 0x0a, 0x1f, 0x44, 0x65, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, - 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, 0x0a, 0x20, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, - 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0xab, 0x03, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, + 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x08, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x07, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x03, 0x66, + 0x71, 0x6e, 0x3a, 0x9a, 0x02, 0xba, 0x48, 0x96, 0x02, 0x1a, 0x9a, 0x01, 0x0a, 0x10, 0x65, 0x78, + 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x4c, + 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, 0x65, 0x70, 0x72, 0x65, + 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x66, 0x71, 0x6e, 0x27, 0x2c, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x1a, 0x38, 0x21, 0x28, + 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x26, 0x26, 0x20, + 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, + 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x66, 0x71, 0x6e, 0x29, 0x29, 0x29, 0x1a, 0x77, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, + 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2f, 0x45, 0x69, 0x74, 0x68, 0x65, + 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x71, 0x6e, 0x20, 0x6d, + 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x33, 0x68, 0x61, 0x73, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, + 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, 0x29, 0x42, + 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x40, 0x0a, + 0x19, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x81, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x66, 0x71, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0x92, 0x01, 0x05, 0x08, 0x01, 0x10, 0xfa, 0x01, 0x52, 0x04, - 0x66, 0x71, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x0a, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x09, 0x77, 0x69, 0x74, 0x68, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x9b, 0x03, 0x0a, 0x20, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7d, 0x0a, 0x14, 0x66, 0x71, 0x6e, 0x5f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, - 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x71, 0x6e, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x12, 0x66, 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, 0x69, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2f, 0x0a, 0x09, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x23, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x1a, 0x8c, 0x01, 0x0a, 0x17, 0x46, 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 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, 0x5b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x45, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, - 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x95, 0x01, 0x0a, 0x27, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6a, 0x0a, - 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x96, 0x01, 0x0a, 0x28, 0x41, 0x73, + 0xad, 0x01, 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, + 0x0a, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x64, 0x12, 0x2d, 0x0a, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, + 0x6e, 0x75, 0x6d, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, + 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x7a, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x25, + 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, + 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xc5, 0x03, 0x0a, 0x1b, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x0c, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x49, 0x64, 0x12, 0xb4, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x9d, 0x02, 0xba, 0x48, 0x99, 0x02, 0xba, + 0x01, 0x8d, 0x02, 0x0a, 0x16, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb5, 0x01, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, + 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, + 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, + 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, + 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, + 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, + 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, + 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, + 0xc8, 0x01, 0x01, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, + 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0xd1, 0x01, 0x0a, 0x1b, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x4a, 0x04, 0x08, + 0x04, 0x10, 0x05, 0x52, 0x07, 0x6d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x22, 0x43, 0x0a, 0x1c, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x3b, 0x0a, 0x1f, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x47, + 0x0a, 0x20, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x1f, 0x47, 0x65, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, + 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x66, + 0x71, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0x92, 0x01, + 0x05, 0x08, 0x01, 0x10, 0xfa, 0x01, 0x52, 0x04, 0x66, 0x71, 0x6e, 0x73, 0x12, 0x3d, 0x0a, 0x0a, + 0x77, 0x69, 0x74, 0x68, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x52, 0x09, 0x77, 0x69, 0x74, 0x68, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9b, 0x03, 0x0a, 0x20, + 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x7d, 0x0a, 0x14, 0x66, 0x71, 0x6e, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x4b, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x66, 0x71, 0x6e, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x1a, + 0x69, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x8c, 0x01, 0x0a, 0x17, 0x46, + 0x71, 0x6e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 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, 0x5b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x45, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, + 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x41, 0x6e, 0x64, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x95, 0x01, 0x0a, 0x27, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x22, 0x97, 0x01, 0x0a, 0x29, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, - 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, - 0x2a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x1b, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x85, 0x01, 0x0a, 0x23, 0x41, 0x73, 0x73, 0x69, - 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, - 0x86, 0x01, 0x0a, 0x24, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x87, 0x01, 0x0a, 0x25, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x22, 0x96, 0x01, 0x0a, 0x28, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6a, + 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x26, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, - 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x6b, 0x0a, - 0x1b, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x64, 0x0a, 0x1c, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x22, 0x6d, 0x0a, 0x1d, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, - 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, - 0x01, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, - 0x66, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x97, 0x01, 0x0a, 0x29, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x22, 0x98, 0x01, 0x0a, 0x2a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, + 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x6a, 0x0a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x5b, 0x0a, 0x17, 0x41, 0x73, 0x73, 0x69, 0x67, - 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, - 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x4b, 0x65, 0x79, 0x22, 0x54, 0x0a, 0x18, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, - 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, - 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x55, 0x0a, 0x19, 0x52, 0x65, - 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, - 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, - 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x18, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, + 0x85, 0x01, 0x0a, 0x23, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x86, 0x01, 0x0a, 0x24, 0x41, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x22, 0x87, 0x01, 0x0a, 0x25, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x88, 0x01, 0x0a, 0x26, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5e, 0x0a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, + 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, + 0x14, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x6b, 0x0a, 0x1b, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, + 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, + 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, + 0x65, 0x79, 0x22, 0x64, 0x0a, 0x1c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, + 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x6d, 0x0a, 0x1d, 0x52, 0x65, 0x6d, 0x6f, + 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, 0x0a, 0x0d, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x66, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x0d, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x52, 0x0c, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x22, + 0x5b, 0x0a, 0x17, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x40, 0x0a, 0x09, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x54, 0x0a, 0x18, + 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, + 0x65, 0x79, 0x22, 0x55, 0x0a, 0x19, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, + 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, - 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x32, 0xad, 0x17, 0x0a, 0x11, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, - 0x7d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x12, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x95, - 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x7c, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, + 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x22, 0x56, 0x0a, 0x1a, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x09, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4b, 0x65, + 0x79, 0x32, 0xad, 0x17, 0x0a, 0x11, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x7d, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x12, 0x0b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x95, 0x01, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x2d, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x12, 0x14, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x90, 0x02, 0x01, 0x12, 0x7c, + 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x26, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, - 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x90, 0x02, 0x01, 0x12, 0xa1, 0x01, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, - 0x73, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, - 0x2a, 0x2f, 0x66, 0x71, 0x6e, 0x90, 0x02, 0x01, 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0f, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, - 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, - 0x2a, 0x32, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x12, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0xa1, 0x01, 0x0a, + 0x18, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, + 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x73, 0x42, 0x79, 0x46, 0x71, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x66, 0x71, 0x6e, 0x90, 0x02, 0x01, + 0x12, 0x80, 0x01, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x16, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x10, 0x3a, 0x01, 0x2a, 0x22, 0x0b, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x12, 0x85, 0x01, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1b, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x32, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x8e, 0x01, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, - 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, - 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa5, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, + 0x75, 0x74, 0x65, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x2a, 0x10, 0x2f, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x91, 0x01, 0x0a, + 0x11, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x12, 0xa5, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, + 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x26, 0x3a, 0x01, 0x2a, 0x22, 0x21, 0x2f, - 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x61, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x69, 0x64, 0x7d, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, - 0x12, 0x9d, 0x01, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, - 0x12, 0xa6, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x32, 0x2e, + 0x73, 0x65, 0x22, 0x24, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1e, 0x3a, 0x01, 0x2a, 0x32, 0x19, 0x2f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa6, 0x01, 0x0a, 0x18, 0x44, 0x65, 0x61, + 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x32, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, + 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, + 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x20, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, + 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x22, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xcd, 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, + 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x33, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x21, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x2a, 0x19, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x2a, 0x2f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xe4, 0x01, 0x0a, 0x20, 0x41, 0x73, + 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xdb, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3a, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, - 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x47, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x41, 0x3a, - 0x1b, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x22, 0x2f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x12, 0xcd, 0x01, 0x0a, 0x22, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, - 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, - 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x2a, 0x22, 0x2f, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x12, 0xdb, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x36, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, 0x93, + 0x02, 0x44, 0x3a, 0x17, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x29, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, + 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, + 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xc8, 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, + 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, + 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x2a, 0x29, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x12, 0x79, 0x0a, 0x14, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x4a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x44, 0x3a, 0x17, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x22, 0x29, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0xc8, - 0x01, 0x0a, 0x1e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x38, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, - 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2b, 0x2a, 0x29, - 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x73, 0x2f, 0x6b, 0x65, 0x79, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x79, 0x0a, 0x14, 0x41, 0x73, 0x73, - 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, - 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, - 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x16, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, - 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x30, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, - 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, 0x10, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, - 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, - 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, - 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x12, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, - 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, - 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7f, 0x0a, 0x16, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, + 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, - 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, - 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x42, 0x0f, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0xa2, 0x02, 0x03, 0x50, 0x41, 0x58, 0xaa, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xe2, - 0x02, 0x1d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, - 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6d, 0x0a, + 0x10, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, + 0x6f, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x73, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4b, 0x65, 0x79, 0x54, 0x6f, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x73, 0x0a, 0x12, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x12, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, + 0x46, 0x72, 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x73, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x4b, 0x65, 0x79, 0x46, 0x72, + 0x6f, 0x6d, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0xc8, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x42, 0x0f, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x39, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, + 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x61, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xa2, 0x02, 0x03, 0x50, 0x41, 0x58, 0xaa, + 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x73, 0xca, 0x02, 0x11, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0xe2, 0x02, 0x1d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x5c, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x3a, 0x3a, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3536,6 +3677,14 @@ func file_policy_attributes_attributes_proto_init() { } } } + file_policy_attributes_attributes_proto_msgTypes[6].OneofWrappers = []interface{}{ + (*GetAttributeRequest_AttributeId)(nil), + (*GetAttributeRequest_Fqn)(nil), + } + file_policy_attributes_attributes_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*GetAttributeValueRequest_ValueId)(nil), + (*GetAttributeValueRequest_Fqn)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/protocol/go/policy/attributes/attributes.pb.gw.go b/protocol/go/policy/attributes/attributes.pb.gw.go index 2e8af7a7e..ed631b9f4 100644 --- a/protocol/go/policy/attributes/attributes.pb.gw.go +++ b/protocol/go/policy/attributes/attributes.pb.gw.go @@ -103,6 +103,10 @@ func local_request_AttributesService_ListAttributeValues_0(ctx context.Context, } +var ( + filter_AttributesService_GetAttribute_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_AttributesService_GetAttribute_0(ctx context.Context, marshaler runtime.Marshaler, client AttributesServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetAttributeRequest var metadata runtime.ServerMetadata @@ -124,6 +128,13 @@ func request_AttributesService_GetAttribute_0(ctx context.Context, marshaler run return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttribute_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetAttribute(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -150,6 +161,13 @@ func local_request_AttributesService_GetAttribute_0(ctx context.Context, marshal return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttribute_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetAttribute(ctx, &protoReq) return msg, metadata, err @@ -329,6 +347,10 @@ func local_request_AttributesService_DeactivateAttribute_0(ctx context.Context, } +var ( + filter_AttributesService_GetAttributeValue_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_AttributesService_GetAttributeValue_0(ctx context.Context, marshaler runtime.Marshaler, client AttributesServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetAttributeValueRequest var metadata runtime.ServerMetadata @@ -350,6 +372,13 @@ func request_AttributesService_GetAttributeValue_0(ctx context.Context, marshale return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttributeValue_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetAttributeValue(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -376,6 +405,13 @@ func local_request_AttributesService_GetAttributeValue_0(ctx context.Context, ma return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_AttributesService_GetAttributeValue_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetAttributeValue(ctx, &protoReq) return msg, metadata, err diff --git a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go index 14aeeb8cd..fd54fee6a 100644 --- a/protocol/go/policy/kasregistry/key_access_server_registry.pb.go +++ b/protocol/go/policy/kasregistry/key_access_server_registry.pb.go @@ -29,8 +29,16 @@ type GetKeyAccessServerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/kasregistry/key_access_server_registry.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetKeyAccessServerRequest_KasId + // *GetKeyAccessServerRequest_Name + // *GetKeyAccessServerRequest_Uri + Identifier isGetKeyAccessServerRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetKeyAccessServerRequest) Reset() { @@ -65,6 +73,7 @@ func (*GetKeyAccessServerRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{0} } +// Deprecated: Marked as deprecated in policy/kasregistry/key_access_server_registry.proto. func (x *GetKeyAccessServerRequest) GetId() string { if x != nil { return x.Id @@ -72,6 +81,57 @@ func (x *GetKeyAccessServerRequest) GetId() string { return "" } +func (m *GetKeyAccessServerRequest) GetIdentifier() isGetKeyAccessServerRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetKeyAccessServerRequest) GetKasId() string { + if x, ok := x.GetIdentifier().(*GetKeyAccessServerRequest_KasId); ok { + return x.KasId + } + return "" +} + +func (x *GetKeyAccessServerRequest) GetName() string { + if x, ok := x.GetIdentifier().(*GetKeyAccessServerRequest_Name); ok { + return x.Name + } + return "" +} + +func (x *GetKeyAccessServerRequest) GetUri() string { + if x, ok := x.GetIdentifier().(*GetKeyAccessServerRequest_Uri); ok { + return x.Uri + } + return "" +} + +type isGetKeyAccessServerRequest_Identifier interface { + isGetKeyAccessServerRequest_Identifier() +} + +type GetKeyAccessServerRequest_KasId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + KasId string `protobuf:"bytes,2,opt,name=kas_id,json=kasId,proto3,oneof"` +} + +type GetKeyAccessServerRequest_Name struct { + Name string `protobuf:"bytes,3,opt,name=name,proto3,oneof"` +} + +type GetKeyAccessServerRequest_Uri struct { + Uri string `protobuf:"bytes,4,opt,name=uri,proto3,oneof"` +} + +func (*GetKeyAccessServerRequest_KasId) isGetKeyAccessServerRequest_Identifier() {} + +func (*GetKeyAccessServerRequest_Name) isGetKeyAccessServerRequest_Identifier() {} + +func (*GetKeyAccessServerRequest_Uri) isGetKeyAccessServerRequest_Identifier() {} + type GetKeyAccessServerResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -825,7 +885,10 @@ type GetPublicKeyRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetPublicKeyRequest_Id + Identifier isGetPublicKeyRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetPublicKeyRequest) Reset() { @@ -860,13 +923,30 @@ func (*GetPublicKeyRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{14} } +func (m *GetPublicKeyRequest) GetIdentifier() isGetPublicKeyRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + func (x *GetPublicKeyRequest) GetId() string { - if x != nil { + if x, ok := x.GetIdentifier().(*GetPublicKeyRequest_Id); ok { return x.Id } return "" } +type isGetPublicKeyRequest_Identifier interface { + isGetPublicKeyRequest_Identifier() +} + +type GetPublicKeyRequest_Id struct { + Id string `protobuf:"bytes,1,opt,name=id,proto3,oneof"` +} + +func (*GetPublicKeyRequest_Id) isGetPublicKeyRequest_Identifier() {} + type GetPublicKeyResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -919,8 +999,12 @@ type ListPublicKeysRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Optional - KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3" json:"kas_id,omitempty"` + // Types that are assignable to KasFilter: + // + // *ListPublicKeysRequest_KasId + // *ListPublicKeysRequest_KasName + // *ListPublicKeysRequest_KasUri + KasFilter isListPublicKeysRequest_KasFilter `protobuf_oneof:"kas_filter"` // Optional Pagination *policy.PageRequest `protobuf:"bytes,10,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -957,13 +1041,34 @@ func (*ListPublicKeysRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{16} } +func (m *ListPublicKeysRequest) GetKasFilter() isListPublicKeysRequest_KasFilter { + if m != nil { + return m.KasFilter + } + return nil +} + func (x *ListPublicKeysRequest) GetKasId() string { - if x != nil { + if x, ok := x.GetKasFilter().(*ListPublicKeysRequest_KasId); ok { return x.KasId } return "" } +func (x *ListPublicKeysRequest) GetKasName() string { + if x, ok := x.GetKasFilter().(*ListPublicKeysRequest_KasName); ok { + return x.KasName + } + return "" +} + +func (x *ListPublicKeysRequest) GetKasUri() string { + if x, ok := x.GetKasFilter().(*ListPublicKeysRequest_KasUri); ok { + return x.KasUri + } + return "" +} + func (x *ListPublicKeysRequest) GetPagination() *policy.PageRequest { if x != nil { return x.Pagination @@ -971,6 +1076,31 @@ func (x *ListPublicKeysRequest) GetPagination() *policy.PageRequest { return nil } +type isListPublicKeysRequest_KasFilter interface { + isListPublicKeysRequest_KasFilter() +} + +type ListPublicKeysRequest_KasId struct { + // Optional + KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3,oneof"` +} + +type ListPublicKeysRequest_KasName struct { + // Optional + KasName string `protobuf:"bytes,2,opt,name=kas_name,json=kasName,proto3,oneof"` +} + +type ListPublicKeysRequest_KasUri struct { + // Optional + KasUri string `protobuf:"bytes,3,opt,name=kas_uri,json=kasUri,proto3,oneof"` +} + +func (*ListPublicKeysRequest_KasId) isListPublicKeysRequest_KasFilter() {} + +func (*ListPublicKeysRequest_KasName) isListPublicKeysRequest_KasFilter() {} + +func (*ListPublicKeysRequest_KasUri) isListPublicKeysRequest_KasFilter() {} + type ListPublicKeysResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1031,8 +1161,12 @@ type ListPublicKeyMappingRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Optional - KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3" json:"kas_id,omitempty"` + // Types that are assignable to KasFilter: + // + // *ListPublicKeyMappingRequest_KasId + // *ListPublicKeyMappingRequest_KasName + // *ListPublicKeyMappingRequest_KasUri + KasFilter isListPublicKeyMappingRequest_KasFilter `protobuf_oneof:"kas_filter"` // Optional Public Key ID PublicKeyId string `protobuf:"bytes,4,opt,name=public_key_id,json=publicKeyId,proto3" json:"public_key_id,omitempty"` // Optional @@ -1071,13 +1205,34 @@ func (*ListPublicKeyMappingRequest) Descriptor() ([]byte, []int) { return file_policy_kasregistry_key_access_server_registry_proto_rawDescGZIP(), []int{18} } +func (m *ListPublicKeyMappingRequest) GetKasFilter() isListPublicKeyMappingRequest_KasFilter { + if m != nil { + return m.KasFilter + } + return nil +} + func (x *ListPublicKeyMappingRequest) GetKasId() string { - if x != nil { + if x, ok := x.GetKasFilter().(*ListPublicKeyMappingRequest_KasId); ok { return x.KasId } return "" } +func (x *ListPublicKeyMappingRequest) GetKasName() string { + if x, ok := x.GetKasFilter().(*ListPublicKeyMappingRequest_KasName); ok { + return x.KasName + } + return "" +} + +func (x *ListPublicKeyMappingRequest) GetKasUri() string { + if x, ok := x.GetKasFilter().(*ListPublicKeyMappingRequest_KasUri); ok { + return x.KasUri + } + return "" +} + func (x *ListPublicKeyMappingRequest) GetPublicKeyId() string { if x != nil { return x.PublicKeyId @@ -1092,6 +1247,31 @@ func (x *ListPublicKeyMappingRequest) GetPagination() *policy.PageRequest { return nil } +type isListPublicKeyMappingRequest_KasFilter interface { + isListPublicKeyMappingRequest_KasFilter() +} + +type ListPublicKeyMappingRequest_KasId struct { + // Optional + KasId string `protobuf:"bytes,1,opt,name=kas_id,json=kasId,proto3,oneof"` +} + +type ListPublicKeyMappingRequest_KasName struct { + // Optional + KasName string `protobuf:"bytes,2,opt,name=kas_name,json=kasName,proto3,oneof"` +} + +type ListPublicKeyMappingRequest_KasUri struct { + // Optional + KasUri string `protobuf:"bytes,3,opt,name=kas_uri,json=kasUri,proto3,oneof"` +} + +func (*ListPublicKeyMappingRequest_KasId) isListPublicKeyMappingRequest_KasFilter() {} + +func (*ListPublicKeyMappingRequest_KasName) isListPublicKeyMappingRequest_KasFilter() {} + +func (*ListPublicKeyMappingRequest_KasUri) isListPublicKeyMappingRequest_KasFilter() {} + type ListPublicKeyMappingResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1806,10 +1986,37 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x16, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x61, + 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe4, 0x03, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, 0x01, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x21, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, + 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, + 0x00, 0x52, 0x03, 0x75, 0x72, 0x69, 0x3a, 0xb7, 0x02, 0xba, 0x48, 0xb3, 0x02, 0x1a, 0xa8, 0x01, + 0x0a, 0x10, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x73, 0x12, 0x4a, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, + 0x65, 0x70, 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, + 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, + 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, 0x75, 0x72, 0x69, 0x27, + 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, 0x74, 0x68, 0x1a, 0x48, + 0x21, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x26, + 0x26, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x61, 0x73, 0x5f, + 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x75, 0x72, 0x69, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, + 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, 0x29, 0x29, 0x1a, 0x85, 0x01, 0x0a, 0x0f, 0x72, 0x65, 0x71, + 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x2d, 0x45, 0x69, + 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, + 0x66, 0x20, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x75, 0x72, 0x69, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x43, 0x68, 0x61, 0x73, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, + 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x75, 0x72, 0x69, 0x29, 0x20, 0x7c, + 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x29, + 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x61, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, @@ -1831,7 +2038,7 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x22, 0xd8, 0x05, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, + 0x69, 0x6f, 0x6e, 0x22, 0xdb, 0x05, 0x0a, 0x1c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x87, 0x02, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xf4, 0x01, 0xba, 0x48, 0xf0, 0x01, 0xba, 0x01, 0xec, 0x01, 0x0a, 0x0a, 0x75, @@ -1853,8 +2060,8 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x09, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0xbe, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0xa9, 0x02, 0xba, 0x48, 0xa5, 0x02, 0xba, 0x01, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0xc1, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, 0xac, 0x02, 0xba, 0x48, 0xa8, 0x02, 0xba, 0x01, 0x9c, 0x02, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, @@ -1872,138 +2079,147 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, - 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x72, 0x03, - 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, - 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x64, - 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x22, 0xe0, 0x06, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, - 0xac, 0x02, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x02, - 0xba, 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, 0x13, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xd8, 0x01, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, - 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, - 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, - 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, - 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, - 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, - 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, - 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, - 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, - 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, - 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, - 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, - 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x1f, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, - 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, - 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x03, 0x75, 0x72, 0x69, 0x12, 0x30, - 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x12, 0xb9, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x42, - 0xa4, 0x02, 0xba, 0x48, 0xa0, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, - 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, - 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, - 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, - 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, - 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, - 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, - 0x2e, 0x1a, 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, - 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, - 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, - 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, - 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, - 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, + 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xc8, 0x01, + 0x00, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, - 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, - 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x64, 0x0a, 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x38, 0x0a, - 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, - 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, - 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x64, 0x0a, 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0x37, 0x0a, - 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xd0, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, - 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x10, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x52, 0x0a, 0x10, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0f, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, - 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0b, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, 0x96, 0x01, 0x0a, 0x16, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, - 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x22, 0x38, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x25, 0x0a, 0x13, - 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x22, 0x35, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x61, 0x22, 0x64, 0x0a, 0x1d, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x22, 0xe3, 0x06, 0x0a, 0x1c, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, + 0x69, 0x64, 0x12, 0xac, 0x02, 0x0a, 0x03, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x99, 0x02, 0xba, 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, 0x13, 0x6f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0xd8, 0x01, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x55, 0x52, 0x49, 0x20, + 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, + 0x55, 0x52, 0x4c, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, + 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, + 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, + 0x20, 0x45, 0x61, 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, + 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, + 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, + 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, + 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, + 0x6e, 0x64, 0x20, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x1f, 0x73, 0x69, 0x7a, + 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x03, 0x75, 0x72, + 0x69, 0x12, 0x30, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x12, 0xbc, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x14, 0x20, 0x01, + 0x28, 0x09, 0x42, 0xa7, 0x02, 0xba, 0x48, 0xa3, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, 0x6b, + 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, + 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, + 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, + 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, + 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, + 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, + 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, + 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, + 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, + 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, + 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, + 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, + 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, + 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, + 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x00, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x64, 0x0a, + 0x1d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, + 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x22, 0x38, 0x0a, 0x1c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x64, 0x0a, + 0x1d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, + 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x22, 0x37, 0x0a, 0x13, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x71, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xd0, 0x02, 0x0a, + 0x15, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x43, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x52, 0x0a, 0x10, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, + 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x0f, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, + 0x52, 0x0a, 0x10, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x0f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x47, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x12, 0x4a, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, + 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x4f, 0x62, 0x6a, 0x65, + 0x63, 0x74, 0x52, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x22, + 0x9e, 0x01, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1f, 0x0a, 0x06, 0x6b, 0x61, + 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, + 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x42, 0x06, + 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x33, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, + 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x22, 0x38, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x63, 0x0a, 0x15, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, - 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, + 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x3f, 0x0a, 0x13, 0x47, 0x65, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x42, 0x0c, 0x0a, + 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x35, 0x0a, 0x14, 0x47, + 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x22, 0xca, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x06, + 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, + 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, + 0x24, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, 0x52, 0x07, 0x6b, 0x61, + 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, + 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0x33, 0x0a, 0x0a, + 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x6b, 0x61, 0x73, 0x5f, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x6f, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, @@ -2011,288 +2227,296 @@ var file_policy_kasregistry_key_access_server_registry_proto_rawDesc = []byte{ 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0x8d, 0x01, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x22, 0x81, 0x02, 0x0a, 0x1b, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x70, - 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x22, 0xf6, 0x05, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x71, 0x0a, 0x13, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, - 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x52, 0x11, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, - 0x69, 0x6e, 0x67, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, - 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xba, 0x01, 0x0a, 0x10, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, - 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0x5b, 0x0a, 0x0b, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x0a, 0x70, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0xbe, 0x02, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x06, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x5e, 0x0a, 0x0b, 0x64, 0x65, - 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, - 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5c, 0x0a, 0x0a, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x2f, 0x0a, 0x0b, 0x41, 0x73, 0x73, 0x6f, - 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xb3, 0x01, 0x0a, 0x16, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, - 0x61, 0x76, 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, - 0x38, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x39, 0x0a, 0x1a, 0x44, 0x65, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, - 0x52, 0x02, 0x69, 0x64, 0x22, 0x3c, 0x0a, 0x1b, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x22, 0x37, 0x0a, 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, - 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3a, 0x0a, 0x19, 0x41, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x12, 0x21, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x05, 0x6b, 0x61, + 0x73, 0x49, 0x64, 0x12, 0x24, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, 0x02, 0x10, 0x01, 0x48, 0x00, + 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x07, 0x6b, 0x61, 0x73, + 0x5f, 0x75, 0x72, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, + 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, + 0x12, 0x2f, 0x0a, 0x0d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x5f, 0x69, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, + 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x49, + 0x64, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, + 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0c, 0x0a, 0x0a, 0x6b, 0x61, 0x73, 0x5f, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x22, 0xf6, 0x05, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x13, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x5f, 0x6d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, + 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x11, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0xba, + 0x01, 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, + 0x69, 0x6e, 0x67, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x6b, 0x61, + 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6b, 0x61, + 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0x5b, + 0x0a, 0x0b, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x05, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x1a, 0xbe, 0x02, 0x0a, 0x09, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x54, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, + 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x5e, + 0x0a, 0x0b, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5c, + 0x0a, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x1a, 0x2f, 0x0a, 0x0b, + 0x41, 0x73, 0x73, 0x6f, 0x63, 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x66, + 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0xbd, 0x01, + 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x54, 0x0a, 0x18, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x62, 0x65, 0x68, 0x61, 0x76, + 0x69, 0x6f, 0x72, 0x18, 0x65, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x16, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x65, 0x68, 0x61, 0x76, 0x69, 0x6f, 0x72, 0x22, 0x38, 0x0a, + 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, - 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x9e, 0x07, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, - 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0xcb, 0x01, 0x0a, - 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xb3, 0x01, - 0xba, 0x48, 0xaf, 0x01, 0xba, 0x01, 0xab, 0x01, 0x0a, 0x14, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x23, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6d, - 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, - 0x55, 0x49, 0x44, 0x1a, 0x6e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, - 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, - 0x5d, 0x7b, 0x38, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, - 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, - 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, - 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x31, 0x32, - 0x7d, 0x27, 0x29, 0x52, 0x05, 0x6b, 0x61, 0x73, 0x49, 0x64, 0x12, 0xb3, 0x02, 0x0a, 0x07, 0x6b, - 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x02, 0xba, - 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, 0x13, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, - 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xd8, 0x01, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, - 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, - 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, - 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, - 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, - 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, - 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, - 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, - 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, - 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, - 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, - 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x1f, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, - 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, - 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, - 0x12, 0xc0, 0x02, 0x0a, 0x08, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x42, 0xa4, 0x02, 0xba, 0x48, 0xa0, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, - 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, - 0xb3, 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, - 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, - 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, - 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, - 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, - 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, - 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, - 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, - 0x61, 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, - 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x4e, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, - 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, - 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, - 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, - 0x29, 0x3f, 0x24, 0x27, 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, - 0x61, 0x6d, 0x65, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, - 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0xa0, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73, - 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, - 0x0a, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x67, - 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, - 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x84, 0x0e, 0x0a, 0x1e, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x99, - 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, - 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x90, 0x02, 0x01, 0x12, 0x98, 0x01, 0x0a, 0x12, 0x47, - 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x12, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, - 0x64, 0x7d, 0x90, 0x02, 0x01, 0x12, 0x9c, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, - 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, - 0x13, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x73, 0x12, 0xa1, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, - 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, - 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaf, 0x01, 0x0a, 0x19, 0x4c, 0x69, + 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x36, 0x0a, 0x1a, 0x44, 0x65, 0x61, 0x63, 0x74, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x3c, 0x0a, 0x1b, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x34, 0x0a, + 0x18, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, + 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, + 0x02, 0x69, 0x64, 0x22, 0x3a, 0x0a, 0x19, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, + 0xa1, 0x07, 0x0a, 0x20, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0xcb, 0x01, 0x0a, 0x06, 0x6b, 0x61, 0x73, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xb3, 0x01, 0xba, 0x48, 0xaf, 0x01, 0xba, 0x01, 0xab, 0x01, + 0x0a, 0x14, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x75, 0x69, 0x64, 0x5f, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0x23, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, + 0x20, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, + 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x55, 0x49, 0x44, 0x1a, 0x6e, 0x73, 0x69, 0x7a, + 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, 0x7c, 0x20, + 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5b, 0x30, + 0x2d, 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x38, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, + 0x39, 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, + 0x61, 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, + 0x2d, 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x34, 0x7d, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x61, 0x2d, + 0x66, 0x41, 0x2d, 0x46, 0x5d, 0x7b, 0x31, 0x32, 0x7d, 0x27, 0x29, 0x52, 0x05, 0x6b, 0x61, 0x73, + 0x49, 0x64, 0x12, 0xb3, 0x02, 0x0a, 0x07, 0x6b, 0x61, 0x73, 0x5f, 0x75, 0x72, 0x69, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x99, 0x02, 0xba, 0x48, 0x95, 0x02, 0xba, 0x01, 0x91, 0x02, 0x0a, + 0x13, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x5f, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x12, 0xd8, 0x01, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, + 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, + 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, + 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, + 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, + 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, + 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, + 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, + 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, + 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, + 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, + 0x1f, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, + 0x20, 0x7c, 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, 0x73, 0x55, 0x72, 0x69, 0x28, 0x29, + 0x52, 0x06, 0x6b, 0x61, 0x73, 0x55, 0x72, 0x69, 0x12, 0xc3, 0x02, 0x0a, 0x08, 0x6b, 0x61, 0x73, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0xa7, 0x02, 0xba, 0x48, + 0xa3, 0x02, 0xba, 0x01, 0x97, 0x02, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x65, 0x72, 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, + 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, + 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6c, + 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, + 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x20, + 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x66, + 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, 0x61, + 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x64, 0x20, 0x4b, 0x41, 0x53, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, + 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, + 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x4e, 0x73, + 0x69, 0x7a, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x7c, + 0x7c, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, + 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, + 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0xc8, 0x01, 0x00, + 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x07, 0x6b, 0x61, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x33, + 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, 0x67, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0xa0, 0x01, 0x0a, 0x21, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x06, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, + 0x61, 0x6e, 0x74, 0x73, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, + 0x12, 0x34, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0a, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x50, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x0a, 0x70, 0x61, 0x67, 0x69, + 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x32, 0x84, 0x0e, 0x0a, 0x1e, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x99, 0x01, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x6b, - 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x73, 0x2f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x90, 0x02, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, + 0x72, 0x73, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, + 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x73, 0x90, 0x02, 0x01, 0x12, 0x98, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2d, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x2e, 0x47, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, 0x82, 0xd3, 0xe4, + 0x93, 0x02, 0x1a, 0x12, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x90, 0x02, 0x01, + 0x12, 0x9c, 0x01, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0c, 0x47, 0x65, 0x74, - 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, - 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, - 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, - 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, - 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x6b, 0x65, 0x79, + 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x12, + 0xa1, 0x01, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x14, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, - 0x67, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x6c, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x23, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1d, 0x3a, 0x01, 0x2a, 0x32, 0x18, 0x2f, 0x6b, 0x65, 0x79, 0x2d, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x7b, + 0x69, 0x64, 0x7d, 0x12, 0x9e, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x30, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x2a, 0x18, 0x2f, 0x6b, 0x65, 0x79, + 0x2d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaf, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, + 0x74, 0x73, 0x12, 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1c, 0x12, 0x1a, 0x2f, 0x6b, 0x65, 0x79, 0x2d, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x73, 0x2f, 0x67, 0x72, 0x61, + 0x6e, 0x74, 0x73, 0x90, 0x02, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, - 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x00, 0x12, 0x78, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, - 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x63, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x27, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, + 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x69, 0x0a, 0x0e, 0x4c, 0x69, 0x73, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x29, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x2e, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, - 0x0a, 0x11, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, - 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x2d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0xdb, 0x01, 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x42, 0x1c, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, - 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xa2, 0x02, 0x03, 0x50, 0x4b, 0x58, 0xaa, - 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0xca, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, - 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xe2, 0x02, 0x1e, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x5c, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x7b, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x4d, + 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, + 0x72, 0x79, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x6c, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, + 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x78, 0x0a, 0x13, 0x44, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x2e, 0x44, 0x65, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x72, 0x0a, 0x11, 0x41, 0x63, 0x74, + 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2c, + 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, + 0x74, 0x72, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xdb, 0x01, + 0x0a, 0x16, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x6b, 0x61, 0x73, + 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x42, 0x1c, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, + 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, + 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x6b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0xa2, 0x02, 0x03, 0x50, 0x4b, 0x58, 0xaa, 0x02, 0x12, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0xca, + 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0xe2, 0x02, 0x1e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x4b, 0x61, + 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, + 0x4b, 0x61, 0x73, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -2801,6 +3025,24 @@ func file_policy_kasregistry_key_access_server_registry_proto_init() { } } } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*GetKeyAccessServerRequest_KasId)(nil), + (*GetKeyAccessServerRequest_Name)(nil), + (*GetKeyAccessServerRequest_Uri)(nil), + } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[14].OneofWrappers = []interface{}{ + (*GetPublicKeyRequest_Id)(nil), + } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[16].OneofWrappers = []interface{}{ + (*ListPublicKeysRequest_KasId)(nil), + (*ListPublicKeysRequest_KasName)(nil), + (*ListPublicKeysRequest_KasUri)(nil), + } + file_policy_kasregistry_key_access_server_registry_proto_msgTypes[18].OneofWrappers = []interface{}{ + (*ListPublicKeyMappingRequest_KasId)(nil), + (*ListPublicKeyMappingRequest_KasName)(nil), + (*ListPublicKeyMappingRequest_KasUri)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go b/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go index 4d4c921c6..66ab08b0e 100644 --- a/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go +++ b/protocol/go/policy/kasregistry/key_access_server_registry.pb.gw.go @@ -67,6 +67,10 @@ func local_request_KeyAccessServerRegistryService_ListKeyAccessServers_0(ctx con } +var ( + filter_KeyAccessServerRegistryService_GetKeyAccessServer_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_KeyAccessServerRegistryService_GetKeyAccessServer_0(ctx context.Context, marshaler runtime.Marshaler, client KeyAccessServerRegistryServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetKeyAccessServerRequest var metadata runtime.ServerMetadata @@ -88,6 +92,13 @@ func request_KeyAccessServerRegistryService_GetKeyAccessServer_0(ctx context.Con return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_KeyAccessServerRegistryService_GetKeyAccessServer_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetKeyAccessServer(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -114,6 +125,13 @@ func local_request_KeyAccessServerRegistryService_GetKeyAccessServer_0(ctx conte return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_KeyAccessServerRegistryService_GetKeyAccessServer_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetKeyAccessServer(ctx, &protoReq) return msg, metadata, err diff --git a/protocol/go/policy/namespaces/namespaces.pb.go b/protocol/go/policy/namespaces/namespaces.pb.go index b51e683dd..adbe06cd0 100644 --- a/protocol/go/policy/namespaces/namespaces.pb.go +++ b/protocol/go/policy/namespaces/namespaces.pb.go @@ -143,8 +143,15 @@ type GetNamespaceRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Required + // Deprecated + // + // Deprecated: Marked as deprecated in policy/namespaces/namespaces.proto. Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // Types that are assignable to Identifier: + // + // *GetNamespaceRequest_NamespaceId + // *GetNamespaceRequest_Fqn + Identifier isGetNamespaceRequest_Identifier `protobuf_oneof:"identifier"` } func (x *GetNamespaceRequest) Reset() { @@ -179,6 +186,7 @@ func (*GetNamespaceRequest) Descriptor() ([]byte, []int) { return file_policy_namespaces_namespaces_proto_rawDescGZIP(), []int{2} } +// Deprecated: Marked as deprecated in policy/namespaces/namespaces.proto. func (x *GetNamespaceRequest) GetId() string { if x != nil { return x.Id @@ -186,6 +194,44 @@ func (x *GetNamespaceRequest) GetId() string { return "" } +func (m *GetNamespaceRequest) GetIdentifier() isGetNamespaceRequest_Identifier { + if m != nil { + return m.Identifier + } + return nil +} + +func (x *GetNamespaceRequest) GetNamespaceId() string { + if x, ok := x.GetIdentifier().(*GetNamespaceRequest_NamespaceId); ok { + return x.NamespaceId + } + return "" +} + +func (x *GetNamespaceRequest) GetFqn() string { + if x, ok := x.GetIdentifier().(*GetNamespaceRequest_Fqn); ok { + return x.Fqn + } + return "" +} + +type isGetNamespaceRequest_Identifier interface { + isGetNamespaceRequest_Identifier() +} + +type GetNamespaceRequest_NamespaceId struct { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + NamespaceId string `protobuf:"bytes,2,opt,name=namespace_id,json=namespaceId,proto3,oneof"` +} + +type GetNamespaceRequest_Fqn struct { + Fqn string `protobuf:"bytes,3,opt,name=fqn,proto3,oneof"` +} + +func (*GetNamespaceRequest_NamespaceId) isGetNamespaceRequest_Identifier() {} + +func (*GetNamespaceRequest_Fqn) isGetNamespaceRequest_Identifier() {} + type GetNamespaceResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1053,10 +1099,35 @@ var file_policy_namespaces_namespaces_proto_rawDesc = []byte{ 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, - 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x2f, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x01, 0x01, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0xbe, + 0x03, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x08, 0xd8, 0x01, 0x02, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x18, + 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2d, 0x0a, 0x0c, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, + 0x72, 0x03, 0xb0, 0x01, 0x01, 0x48, 0x00, 0x52, 0x0b, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, 0x01, 0x88, 0x01, 0x01, 0x48, 0x00, 0x52, + 0x03, 0x66, 0x71, 0x6e, 0x3a, 0xaa, 0x02, 0xba, 0x48, 0xa6, 0x02, 0x1a, 0xa2, 0x01, 0x0a, 0x10, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, + 0x12, 0x50, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x75, 0x73, 0x65, 0x20, 0x64, 0x65, 0x70, + 0x72, 0x65, 0x63, 0x61, 0x74, 0x65, 0x64, 0x20, 0x27, 0x69, 0x64, 0x27, 0x20, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x27, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x27, 0x20, 0x6f, 0x72, 0x20, 0x27, + 0x66, 0x71, 0x6e, 0x27, 0x2c, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x6f, + 0x74, 0x68, 0x1a, 0x3c, 0x21, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x69, + 0x64, 0x29, 0x20, 0x26, 0x26, 0x20, 0x28, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, + 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, 0x29, 0x29, 0x29, + 0x1a, 0x7f, 0x0a, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x12, 0x33, 0x45, 0x69, 0x74, 0x68, 0x65, 0x72, 0x20, 0x69, 0x64, 0x20, 0x6f, + 0x72, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x69, 0x64, 0x20, 0x6f, 0x72, 0x20, 0x66, 0x71, 0x6e, 0x20, 0x6d, 0x75, 0x73, + 0x74, 0x20, 0x62, 0x65, 0x20, 0x73, 0x65, 0x74, 0x1a, 0x37, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x69, 0x64, 0x29, 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, + 0x69, 0x73, 0x2e, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x29, + 0x20, 0x7c, 0x7c, 0x20, 0x68, 0x61, 0x73, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x66, 0x71, 0x6e, + 0x29, 0x42, 0x0c, 0x0a, 0x0a, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, @@ -1648,6 +1719,10 @@ func file_policy_namespaces_namespaces_proto_init() { } } } + file_policy_namespaces_namespaces_proto_msgTypes[2].OneofWrappers = []interface{}{ + (*GetNamespaceRequest_NamespaceId)(nil), + (*GetNamespaceRequest_Fqn)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ diff --git a/protocol/go/policy/namespaces/namespaces.pb.gw.go b/protocol/go/policy/namespaces/namespaces.pb.gw.go index e8b49e8be..85a45c78f 100644 --- a/protocol/go/policy/namespaces/namespaces.pb.gw.go +++ b/protocol/go/policy/namespaces/namespaces.pb.gw.go @@ -31,6 +31,10 @@ var _ = runtime.String var _ = utilities.NewDoubleArray var _ = metadata.Join +var ( + filter_NamespaceService_GetNamespace_0 = &utilities.DoubleArray{Encoding: map[string]int{"id": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + func request_NamespaceService_GetNamespace_0(ctx context.Context, marshaler runtime.Marshaler, client NamespaceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { var protoReq GetNamespaceRequest var metadata runtime.ServerMetadata @@ -52,6 +56,13 @@ func request_NamespaceService_GetNamespace_0(ctx context.Context, marshaler runt return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_NamespaceService_GetNamespace_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := client.GetNamespace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) return msg, metadata, err @@ -78,6 +89,13 @@ func local_request_NamespaceService_GetNamespace_0(ctx context.Context, marshale return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err) } + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_NamespaceService_GetNamespace_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + msg, err := server.GetNamespace(ctx, &protoReq) return msg, metadata, err diff --git a/protocol/go/policy/objects.pb.go b/protocol/go/policy/objects.pb.go index 37db1d2a4..b2d806fbb 100644 --- a/protocol/go/policy/objects.pb.go +++ b/protocol/go/policy/objects.pb.go @@ -1876,106 +1876,108 @@ var file_policy_objects_proto_rawDesc = []byte{ 0x73, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x03, 0x6b, 0x61, 0x73, 0x12, 0x2c, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x61, 0x0a, 0x0c, 0x4b, 0x61, - 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x65, - 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x70, 0x65, 0x6d, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x12, 0x2d, - 0x0a, 0x03, 0x61, 0x6c, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, 0x52, 0x03, 0x61, 0x6c, 0x67, 0x22, 0x3b, 0x0a, - 0x0f, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, - 0x12, 0x28, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0xe0, 0x03, 0x0a, 0x09, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x84, 0x03, 0x0a, 0x06, 0x72, 0x65, 0x6d, - 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xe9, 0x02, 0xba, 0x48, 0xe5, 0x02, - 0xba, 0x01, 0xe1, 0x02, 0x0a, 0x0a, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, - 0x12, 0xcf, 0x01, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, - 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x28, 0x65, 0x2e, 0x67, 0x2e, - 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x65, 0x6d, 0x6f, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x20, - 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x73, 0x65, - 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, 0x68, 0x20, 0x73, 0x65, 0x67, - 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x20, - 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x61, 0x6e, 0x20, - 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, - 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, 0x20, 0x61, 0x6c, 0x70, - 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, - 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6c, 0x61, 0x73, 0x68, 0x65, - 0x73, 0x2e, 0x1a, 0x80, 0x01, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, - 0x73, 0x28, 0x27, 0x5e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, - 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, 0x7d, 0x5b, 0x61, 0x2d, 0x7a, - 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x28, 0x5c, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, - 0x30, 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, 0x7d, 0x5b, 0x61, 0x2d, - 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x29, 0x2a, 0x28, 0x2f, 0x2e, 0x2a, - 0x29, 0x3f, 0x24, 0x27, 0x29, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x12, - 0x31, 0x0a, 0x06, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x63, 0x61, 0x63, 0x68, - 0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x2a, 0xb3, 0x01, - 0x0a, 0x15, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, - 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x54, 0x54, 0x52, 0x49, - 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, - 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, - 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4c, - 0x4c, 0x5f, 0x4f, 0x46, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, - 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, - 0x55, 0x4d, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x4f, 0x46, 0x10, 0x02, 0x12, 0x26, 0x0a, 0x22, 0x41, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x84, 0x01, 0x0a, 0x0c, 0x4b, + 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1c, 0x0a, 0x03, 0x70, + 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0x72, 0x05, 0x10, + 0x01, 0x18, 0x80, 0x40, 0x52, 0x03, 0x70, 0x65, 0x6d, 0x12, 0x1b, 0x0a, 0x03, 0x6b, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x09, 0xba, 0x48, 0x06, 0x72, 0x04, 0x10, 0x01, 0x18, + 0x20, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x03, 0x61, 0x6c, 0x67, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, + 0x42, 0x0a, 0xba, 0x48, 0x07, 0x82, 0x01, 0x04, 0x10, 0x01, 0x20, 0x00, 0x52, 0x03, 0x61, 0x6c, + 0x67, 0x22, 0x3b, 0x0a, 0x0f, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x53, 0x65, 0x74, 0x12, 0x28, 0x0a, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x04, 0x6b, 0x65, 0x79, 0x73, 0x22, 0xe0, + 0x03, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x84, 0x03, 0x0a, + 0x06, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0xe9, 0x02, + 0xba, 0x48, 0xe5, 0x02, 0xba, 0x01, 0xe1, 0x02, 0x0a, 0x0a, 0x75, 0x72, 0x69, 0x5f, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x12, 0xcf, 0x01, 0x55, 0x52, 0x49, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, + 0x62, 0x65, 0x20, 0x61, 0x20, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x55, 0x52, 0x4c, 0x20, 0x28, + 0x65, 0x2e, 0x67, 0x2e, 0x2c, 0x20, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, + 0x65, 0x6d, 0x6f, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x27, 0x29, 0x20, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x64, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x61, + 0x6c, 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x45, 0x61, 0x63, 0x68, + 0x20, 0x73, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x6e, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, + 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, 0x2c, + 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x63, 0x68, + 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x6c, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x2e, 0x1a, 0x80, 0x01, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, + 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, 0x7a, + 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, 0x7d, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x28, 0x5c, 0x5c, + 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5c, 0x5c, 0x2d, 0x5d, 0x7b, 0x30, 0x2c, 0x36, 0x31, + 0x7d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x29, 0x2a, + 0x28, 0x2f, 0x2e, 0x2a, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x48, 0x00, 0x52, 0x06, 0x72, 0x65, 0x6d, + 0x6f, 0x74, 0x65, 0x12, 0x31, 0x0a, 0x06, 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x61, 0x73, + 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, + 0x63, 0x61, 0x63, 0x68, 0x65, 0x64, 0x42, 0x0c, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x05, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x2a, 0xb3, 0x01, 0x0a, 0x15, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, + 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x28, 0x0a, 0x24, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x48, 0x49, 0x45, 0x52, 0x41, 0x52, 0x43, 0x48, - 0x59, 0x10, 0x03, 0x2a, 0xca, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4d, - 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x45, 0x6e, - 0x75, 0x6d, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, - 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, - 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, - 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x53, 0x55, 0x42, 0x4a, 0x45, - 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x49, 0x4e, 0x10, - 0x02, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, - 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, - 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x53, 0x10, 0x03, - 0x2a, 0x90, 0x01, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x6f, - 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x2b, 0x0a, - 0x27, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, - 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, - 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x43, 0x4f, - 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4e, 0x44, 0x10, 0x01, 0x12, - 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, - 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4f, - 0x52, 0x10, 0x02, 0x2a, 0x88, 0x02, 0x0a, 0x13, 0x4b, 0x61, 0x73, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x27, 0x0a, 0x23, 0x4b, - 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, - 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, - 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, + 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, + 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, + 0x4d, 0x5f, 0x41, 0x4c, 0x4c, 0x5f, 0x4f, 0x46, 0x10, 0x01, 0x12, 0x23, 0x0a, 0x1f, 0x41, 0x54, + 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, 0x45, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4e, 0x59, 0x5f, 0x4f, 0x46, 0x10, 0x02, 0x12, + 0x26, 0x0a, 0x22, 0x41, 0x54, 0x54, 0x52, 0x49, 0x42, 0x55, 0x54, 0x45, 0x5f, 0x52, 0x55, 0x4c, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x48, 0x49, 0x45, 0x52, + 0x41, 0x52, 0x43, 0x48, 0x59, 0x10, 0x03, 0x2a, 0xca, 0x01, 0x0a, 0x1a, 0x53, 0x75, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x4d, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x45, 0x6e, 0x75, 0x6d, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, + 0x54, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, + 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, + 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x28, 0x0a, 0x24, 0x53, + 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, + 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x49, 0x4e, 0x10, 0x02, 0x12, 0x2d, 0x0a, 0x29, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, + 0x5f, 0x4d, 0x41, 0x50, 0x50, 0x49, 0x4e, 0x47, 0x5f, 0x4f, 0x50, 0x45, 0x52, 0x41, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, + 0x4e, 0x53, 0x10, 0x03, 0x2a, 0x90, 0x01, 0x0a, 0x18, 0x43, 0x6f, 0x6e, 0x64, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, + 0x6d, 0x12, 0x2b, 0x0a, 0x27, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, + 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, + 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x23, + 0x0a, 0x1f, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x4f, 0x4f, 0x4c, + 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x41, 0x4e, + 0x44, 0x10, 0x01, 0x12, 0x22, 0x0a, 0x1e, 0x43, 0x4f, 0x4e, 0x44, 0x49, 0x54, 0x49, 0x4f, 0x4e, + 0x5f, 0x42, 0x4f, 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x4e, + 0x55, 0x4d, 0x5f, 0x4f, 0x52, 0x10, 0x02, 0x2a, 0x88, 0x02, 0x0a, 0x13, 0x4b, 0x61, 0x73, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x41, 0x6c, 0x67, 0x45, 0x6e, 0x75, 0x6d, 0x12, + 0x27, 0x0a, 0x23, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, + 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, + 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x24, 0x0a, 0x20, 0x4b, 0x41, 0x53, 0x5f, + 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, + 0x4e, 0x55, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x01, 0x12, 0x24, + 0x0a, 0x20, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, + 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x34, 0x30, + 0x39, 0x36, 0x10, 0x02, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, - 0x52, 0x53, 0x41, 0x5f, 0x32, 0x30, 0x34, 0x38, 0x10, 0x01, 0x12, 0x24, 0x0a, 0x20, 0x4b, 0x41, - 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, - 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x52, 0x53, 0x41, 0x5f, 0x34, 0x30, 0x39, 0x36, 0x10, 0x02, - 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, - 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, - 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, 0x31, 0x10, 0x05, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, - 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, - 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x33, 0x38, 0x34, - 0x52, 0x31, 0x10, 0x06, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, - 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, - 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, 0x10, 0x07, 0x42, 0x82, - 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x0c, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2e, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, - 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xa2, 0x02, 0x03, - 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xca, 0x02, 0x06, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xe2, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x47, - 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x06, 0x50, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x32, 0x35, 0x36, 0x52, 0x31, 0x10, 0x05, 0x12, 0x28, + 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, + 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, + 0x50, 0x33, 0x38, 0x34, 0x52, 0x31, 0x10, 0x06, 0x12, 0x28, 0x0a, 0x24, 0x4b, 0x41, 0x53, 0x5f, + 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x41, 0x4c, 0x47, 0x5f, 0x45, + 0x4e, 0x55, 0x4d, 0x5f, 0x45, 0x43, 0x5f, 0x53, 0x45, 0x43, 0x50, 0x35, 0x32, 0x31, 0x52, 0x31, + 0x10, 0x07, 0x42, 0x82, 0x01, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x42, 0x0c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x2e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, + 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0xa2, 0x02, 0x03, 0x50, 0x58, 0x58, 0xaa, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0xca, 0x02, 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0xe2, 0x02, 0x12, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, + 0x06, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protocol/go/policy/unsafe/unsafe.pb.go b/protocol/go/policy/unsafe/unsafe.pb.go index 08aa3c1fb..858516b55 100644 --- a/protocol/go/policy/unsafe/unsafe.pb.go +++ b/protocol/go/policy/unsafe/unsafe.pb.go @@ -1160,12 +1160,12 @@ var file_policy_unsafe_unsafe_proto_rawDesc = []byte{ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xdf, 0x03, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x22, 0xe2, 0x03, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, - 0x64, 0x12, 0xc4, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x42, 0xaf, 0x02, 0xba, 0x48, 0xab, 0x02, 0xba, 0x01, 0xa2, 0x02, 0x0a, 0x15, 0x61, 0x74, 0x74, + 0x64, 0x12, 0xc7, 0x02, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x42, 0xb2, 0x02, 0xba, 0x48, 0xae, 0x02, 0xba, 0x01, 0xa2, 0x02, 0x0a, 0x15, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb3, 0x01, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, @@ -1183,206 +1183,206 @@ var file_policy_unsafe_unsafe_proto_rawDesc = []byte{ 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x72, 0x03, 0x18, - 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x72, 0x75, 0x6c, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, 0x54, 0x79, 0x70, - 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, - 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x5f, - 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x1d, 0x55, 0x6e, 0x73, 0x61, + 0x5d, 0x29, 0x3f, 0x24, 0x27, 0x29, 0x20, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xc8, 0x01, 0x00, + 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3b, 0x0a, 0x04, 0x72, + 0x75, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x75, 0x6c, 0x65, + 0x54, 0x79, 0x70, 0x65, 0x45, 0x6e, 0x75, 0x6d, 0x42, 0x08, 0xba, 0x48, 0x05, 0x82, 0x01, 0x02, + 0x10, 0x01, 0x52, 0x04, 0x72, 0x75, 0x6c, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x73, 0x5f, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x4f, 0x72, 0x64, 0x65, 0x72, 0x22, 0x50, 0x0a, 0x1d, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, + 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3c, 0x0a, + 0x20, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x54, 0x0a, 0x21, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, + 0x65, 0x22, 0x52, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, + 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x03, 0x66, + 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, + 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0x50, 0x0a, 0x1d, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0xe7, 0x02, 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, - 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x3c, 0x0a, 0x20, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, - 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x54, 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, - 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, - 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x22, 0x52, - 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, - 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, - 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x03, 0x66, 0x71, 0x6e, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x03, 0x66, - 0x71, 0x6e, 0x22, 0x50, 0x0a, 0x1d, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x2f, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x22, 0xe7, 0x02, 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, - 0x52, 0x02, 0x69, 0x64, 0x12, 0xa7, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x90, 0x02, 0xba, 0x48, 0x8c, 0x02, 0xba, 0x01, 0x83, 0x02, 0x0a, - 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x12, 0xb5, 0x01, - 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x20, - 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, 0x70, 0x68, 0x61, - 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x2c, 0x20, - 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, 0x65, 0x6e, 0x73, - 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, 0x72, 0x65, 0x73, - 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, - 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, 0x20, 0x63, 0x68, - 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x74, 0x6f, - 0x72, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, 0x6f, 0x72, 0x6d, - 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, - 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, 0x61, 0x74, 0x63, - 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, - 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5f, 0x2d, - 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x29, 0x3f, 0x24, - 0x27, 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x49, - 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x41, 0x0a, 0x25, 0x55, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, - 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4d, 0x0a, 0x26, + 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, + 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0xa7, 0x02, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x90, 0x02, 0xba, 0x48, 0x8c, 0x02, 0xba, 0x01, + 0x83, 0x02, 0x0a, 0x0c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x12, 0xb5, 0x01, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x20, 0x6d, 0x75, 0x73, 0x74, 0x20, 0x62, 0x65, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x6c, + 0x70, 0x68, 0x61, 0x6e, 0x75, 0x6d, 0x65, 0x72, 0x69, 0x63, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x2c, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x69, 0x6e, 0x67, 0x20, 0x68, 0x79, 0x70, 0x68, + 0x65, 0x6e, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x73, 0x63, 0x6f, + 0x72, 0x65, 0x73, 0x20, 0x62, 0x75, 0x74, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x20, 0x6f, 0x72, 0x20, 0x6c, 0x61, 0x73, 0x74, + 0x20, 0x63, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, + 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x20, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x20, 0x77, 0x69, 0x6c, 0x6c, 0x20, 0x62, 0x65, 0x20, 0x6e, + 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x69, 0x7a, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6c, 0x6f, 0x77, + 0x65, 0x72, 0x20, 0x63, 0x61, 0x73, 0x65, 0x2e, 0x1a, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x27, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, + 0x30, 0x2d, 0x39, 0x5d, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, + 0x39, 0x5f, 0x2d, 0x5d, 0x2a, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, + 0x29, 0x3f, 0x24, 0x27, 0x29, 0x72, 0x03, 0x18, 0xfd, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x49, 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x41, 0x0a, 0x25, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, 0x0a, 0x21, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, - 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, 0x03, 0x66, 0x71, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, - 0x03, 0x66, 0x71, 0x6e, 0x22, 0x49, 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, - 0x38, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, - 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3e, 0x0a, 0x1d, 0x55, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x32, 0xd2, 0x0c, 0x0a, 0x0d, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, - 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, - 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x12, 0xaa, 0x01, 0x0a, 0x19, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, - 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, - 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, - 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, - 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, - 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, 0x75, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, 0x7b, - 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x93, - 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, + 0x4d, 0x0a, 0x26, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x57, + 0x0a, 0x21, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x08, 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x12, 0x18, 0x0a, + 0x03, 0x66, 0x71, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x03, 0x66, 0x71, 0x6e, 0x22, 0x49, 0x0a, 0x22, 0x55, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x23, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x70, + 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x38, 0x0a, 0x1c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x18, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x08, + 0xba, 0x48, 0x05, 0x72, 0x03, 0xb0, 0x01, 0x01, 0x52, 0x02, 0x69, 0x64, 0x22, 0x3e, 0x0a, 0x1d, + 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x2e, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x32, 0xd2, 0x0c, 0x0a, + 0x0d, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x93, + 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, - 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x75, 0x6e, + 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x2f, - 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2b, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, + 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaa, 0x01, 0x0a, 0x19, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, + 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, + 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, + 0x76, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, + 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, + 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, + 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaa, 0x01, 0x0a, 0x19, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, - 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, - 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, - 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xa9, 0x01, - 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x2e, 0x70, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, - 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, - 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x32, 0x1e, 0x2f, 0x75, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc0, 0x01, 0x0a, 0x1e, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, - 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x34, 0x2e, 0x70, + 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x19, 0x32, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xaa, 0x01, + 0x0a, 0x19, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, + 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x70, 0x6f, + 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, + 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, 0xe4, 0x93, 0x02, - 0x2b, 0x22, 0x29, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, - 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, - 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0xa9, 0x01, 0x0a, - 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x2e, 0x70, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, - 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x74, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, - 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, - 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x24, 0x22, 0x22, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, + 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x2f, + 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, 0x93, 0x01, 0x0a, 0x15, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, + 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x1f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x2a, 0x17, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, + 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, + 0x12, 0xa9, 0x01, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, + 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, + 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x32, 0x1e, 0x2f, 0x75, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, + 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0xc0, 0x01, 0x0a, + 0x1e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, + 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x34, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, + 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x35, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x52, 0x65, 0x61, 0x63, + 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x31, 0x82, 0xd3, + 0xe4, 0x93, 0x02, 0x2b, 0x22, 0x29, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, + 0x7b, 0x69, 0x64, 0x7d, 0x2f, 0x72, 0x65, 0x61, 0x63, 0x74, 0x69, 0x76, 0x61, 0x74, 0x65, 0x12, + 0xa9, 0x01, 0x0a, 0x1a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x30, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, + 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, + 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x31, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, + 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x2a, 0x1e, 0x2f, 0x75, 0x6e, + 0x73, 0x61, 0x66, 0x65, 0x2f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x2f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x12, 0x74, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0xac, - 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, - 0x73, 0x61, 0x66, 0x65, 0x42, 0x0b, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x50, 0x72, 0x6f, 0x74, - 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x70, 0x6f, 0x6c, - 0x69, 0x63, 0x79, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0xa2, 0x02, 0x03, 0x50, 0x55, 0x58, - 0xaa, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0xca, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0xe2, 0x02, 0x19, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, - 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0e, 0x50, - 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2b, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, + 0x73, 0x61, 0x66, 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, + 0x65, 0x2e, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x42, 0xac, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, + 0x2e, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x42, 0x0b, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, + 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2f, 0x75, 0x6e, 0x73, 0x61, 0x66, 0x65, 0xa2, 0x02, 0x03, + 0x50, 0x55, 0x58, 0xaa, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x55, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0xca, 0x02, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0xe2, 0x02, 0x19, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5c, 0x55, 0x6e, 0x73, + 0x61, 0x66, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, + 0x02, 0x0e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x3a, 0x3a, 0x55, 0x6e, 0x73, 0x61, 0x66, 0x65, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/service/integration/attribute_values_test.go b/service/integration/attribute_values_test.go index a5ef247df..bb3636f3b 100644 --- a/service/integration/attribute_values_test.go +++ b/service/integration/attribute_values_test.go @@ -183,26 +183,84 @@ func (s *AttributeValuesSuite) Test_ListAttributeValues_Offset_Succeeds() { func (s *AttributeValuesSuite) Test_GetAttributeValue() { f := s.f.GetAttributeValueKey("example.com/attr/attr1/value/value1") - v, err := s.db.PolicyClient.GetAttributeValue(s.ctx, f.ID) - s.Require().NoError(err) - s.NotNil(v) - s.Equal(f.ID, v.GetId()) - s.Equal(f.Value, v.GetValue()) - // s.Equal(f.AttributeDefinitionId, v.AttributeId) - s.Equal("https://example.com/attr/attr1/value/value1", v.GetFqn()) - metadata := v.GetMetadata() - createdAt := metadata.GetCreatedAt() - updatedAt := metadata.GetUpdatedAt() - s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0) - s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0) + testCases := []struct { + name string + input interface{} + identifierType string + }{ + { + name: "Deprecated ID", + input: f.ID, + identifierType: "Deprecated ID", + }, + { + name: "New Identifier - ID", + input: &attributes.GetAttributeValueRequest_ValueId{ValueId: f.ID}, + identifierType: "New ID", + }, + { + name: "New Identifier - FQN", + input: &attributes.GetAttributeValueRequest_Fqn{Fqn: "https://example.com/attr/attr1/value/value1"}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + v, err := s.db.PolicyClient.GetAttributeValue(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get AttributeValue by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(v, "Expected non-nil AttributeValue for %s: %v", tc.identifierType, tc.input) + + s.Equal(f.ID, v.GetId(), "ID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.Value, v.GetValue(), "Value mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.AttributeDefinitionID, v.GetAttribute().GetId(), "AttributeDefinitionID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal("https://example.com/attr/attr1/value/value1", v.GetFqn(), "FQN mismatch for %s: %v", tc.identifierType, tc.input) + + metadata := v.GetMetadata() + s.Require().NotNil(metadata, "Metadata should not be nil for %s: %v", tc.identifierType, tc.input) + createdAt := metadata.GetCreatedAt() + updatedAt := metadata.GetUpdatedAt() + s.Require().NotNil(createdAt, "CreatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(updatedAt, "UpdatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + + s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0, "CreatedAt is invalid for %s: %v", tc.identifierType, tc.input) + s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0, "UpdatedAt is invalid for %s: %v", tc.identifierType, tc.input) + }) + } } func (s *AttributeValuesSuite) Test_GetAttributeValue_NotFound() { - attr, err := s.db.PolicyClient.GetAttributeValue(s.ctx, absentAttributeValueUUID) - s.Require().Error(err) - s.Nil(attr) - s.Require().ErrorIs(err, db.ErrNotFound) + testCases := []struct { + name string + input interface{} // Could be string ID or identifier struct if you want to test different not-found scenarios later + identifierType string // For clarity in case you expand test cases + }{ + { + name: "Not Found - Deprecated ID", // Or just "Not Found" if only one case + input: absentAttributeValueUUID, + identifierType: "Deprecated ID", // Or "UUID" or "ID" + }, + { + name: "Not Found - New Identifier - ID", + input: &attributes.GetAttributeValueRequest_ValueId{ValueId: absentAttributeValueUUID}, + identifierType: "New ID", + }, + { + name: "Not Found - New Identifier - FQN", + input: &attributes.GetAttributeValueRequest_Fqn{Fqn: "https://example.com/attr/attr1/value/absent_value"}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + attr, err := s.db.PolicyClient.GetAttributeValue(s.ctx, tc.input) + s.Require().Error(err, "Expected an error when AttributeValue is not found by %s: %v", tc.identifierType, tc.input) + s.Nil(attr, "Expected nil AttributeValue when not found by %s: %v", tc.identifierType, tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound when AttributeValue is not found by %s: %v", tc.identifierType, tc.input) + }) + } } func (s *AttributeValuesSuite) Test_GetAttributeValue_ContainsKASGrants() { diff --git a/service/integration/attributes_test.go b/service/integration/attributes_test.go index e7a41c49d..7c09e7567 100644 --- a/service/integration/attributes_test.go +++ b/service/integration/attributes_test.go @@ -52,16 +52,16 @@ func (s *AttributesSuite) TearDownSuite() { s.f.TearDown() } -func (s *AttributesSuite) getAttributeFixtures() []fixtures.FixtureDataAttribute { - return []fixtures.FixtureDataAttribute{ - s.f.GetAttributeKey("example.com/attr/attr1"), - s.f.GetAttributeKey("example.com/attr/attr2"), - s.f.GetAttributeKey("example.net/attr/attr1"), - s.f.GetAttributeKey("example.net/attr/attr2"), - s.f.GetAttributeKey("example.net/attr/attr3"), - s.f.GetAttributeKey("example.org/attr/attr1"), - s.f.GetAttributeKey("example.org/attr/attr2"), - s.f.GetAttributeKey("example.org/attr/attr3"), +func (s *AttributesSuite) getAttributeFixtures() map[string]fixtures.FixtureDataAttribute { + return map[string]fixtures.FixtureDataAttribute{ + "example.com/attr/attr1": s.f.GetAttributeKey("example.com/attr/attr1"), + "example.com/attr/attr2": s.f.GetAttributeKey("example.com/attr/attr2"), + "example.net/attr/attr1": s.f.GetAttributeKey("example.net/attr/attr1"), + "example.net/attr/attr2": s.f.GetAttributeKey("example.net/attr/attr2"), + "example.net/attr/attr3": s.f.GetAttributeKey("example.net/attr/attr3"), + "example.org/attr/attr1": s.f.GetAttributeKey("example.org/attr/attr1"), + "example.org/attr/attr2": s.f.GetAttributeKey("example.org/attr/attr2"), + "example.org/attr/attr3": s.f.GetAttributeKey("example.org/attr/attr3"), } } @@ -290,28 +290,85 @@ func (s *AttributesSuite) Test_GetAttribute_OrderOfValuesIsPreserved() { func (s *AttributesSuite) Test_GetAttribute() { fixtures := s.getAttributeFixtures() - for _, f := range fixtures { - gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, f.ID) - s.Require().NoError(err) - s.NotNil(gotAttr) - s.Equal(f.ID, gotAttr.GetId()) - s.Equal(f.Name, gotAttr.GetName()) - s.Equal(fmt.Sprintf("%s%s", policydb.AttributeRuleTypeEnumPrefix, f.Rule), gotAttr.GetRule().Enum().String()) - s.Equal(f.NamespaceID, gotAttr.GetNamespace().GetId()) - metadata := gotAttr.GetMetadata() - createdAt := metadata.GetCreatedAt() - updatedAt := metadata.GetUpdatedAt() - s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0) - s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0) + for fqn, f := range fixtures { + testCases := []struct { + name string + input interface{} + identifierType string + }{ + { + name: "Deprecated ID", + input: f.ID, + identifierType: "Deprecated ID", + }, + { + name: "New Identifier - ID", + input: &attributes.GetAttributeRequest_AttributeId{AttributeId: f.ID}, + identifierType: "New ID", + }, + { + name: "New Identifier - FQN", + input: &attributes.GetAttributeRequest_Fqn{Fqn: fqn}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(fmt.Sprintf("%s - %s", fqn, tc.name), func() { // Include fqn in test name for clarity + gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get Attribute by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(gotAttr, "Expected non-nil Attribute for %s: %v", tc.identifierType, tc.input) + + s.Equal(f.ID, gotAttr.GetId(), "ID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.Name, gotAttr.GetName(), "Name mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(fmt.Sprintf("%s%s", policydb.AttributeRuleTypeEnumPrefix, f.Rule), gotAttr.GetRule().Enum().String(), "Rule mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(f.NamespaceID, gotAttr.GetNamespace().GetId(), "NamespaceID mismatch for %s: %v", tc.identifierType, tc.input) + + metadata := gotAttr.GetMetadata() + s.Require().NotNil(metadata, "Metadata should not be nil for %s: %v", tc.identifierType, tc.input) + createdAt := metadata.GetCreatedAt() + updatedAt := metadata.GetUpdatedAt() + s.Require().NotNil(createdAt, "CreatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(updatedAt, "UpdatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + + s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0, "CreatedAt is invalid for %s: %v", tc.identifierType, tc.input) + s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0, "UpdatedAt is invalid for %s: %v", tc.identifierType, tc.input) + }) + } } } -func (s *AttributesSuite) Test_GetAttribute_WithInvalidIdFails() { - // this uuid does not exist - gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, nonExistentAttrID) - s.Require().Error(err) - s.Nil(gotAttr) - s.Require().ErrorIs(err, db.ErrNotFound) +func (s *AttributesSuite) Test_GetAttribute_NotFound() { + testCases := []struct { + name string + input interface{} // Could be string ID or identifier struct if needed later + identifierType string + }{ + { + name: "Not Found - Deprecated ID", // Or just "Not Found" if only one case is needed + input: nonExistentAttrID, + identifierType: "Deprecated ID", // Or "UUID", "ID" + }, + { + name: "Not Found - New Identifier - ID", + input: &attributes.GetAttributeRequest_AttributeId{AttributeId: nonExistentAttrID}, + identifierType: "New ID", + }, + { + name: "Not Found - New Identifier - FQN", + input: &attributes.GetAttributeRequest_Fqn{Fqn: "https://example.com/attr/non_existent_attr"}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + gotAttr, err := s.db.PolicyClient.GetAttribute(s.ctx, tc.input) + s.Require().Error(err, "Expected error when Attribute is not found by %s: %v", tc.identifierType, tc.input) + s.Nil(gotAttr, "Expected nil Attribute when not found by %s: %v", tc.identifierType, tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound when Attribute is not found by %s: %v", tc.identifierType, tc.input) + }) + } } func (s *AttributesSuite) Test_GetAttribute_Deactivated_Succeeds() { diff --git a/service/integration/kas_registry_test.go b/service/integration/kas_registry_test.go index 56a31a609..a31b82cd0 100644 --- a/service/integration/kas_registry_test.go +++ b/service/integration/kas_registry_test.go @@ -145,35 +145,130 @@ func (s *KasRegistrySuite) Test_GetKeyAccessServer() { remoteFixture := s.f.GetKasRegistryKey("key_access_server_1") localFixture := s.f.GetKasRegistryKey("key_access_server_2") - remote, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, remoteFixture.ID) - s.Require().NoError(err) - s.NotNil(remote) - s.Equal(remoteFixture.ID, remote.GetId()) - s.Equal(remoteFixture.URI, remote.GetUri()) - s.Equal(remoteFixture.Name, remote.GetName()) - s.Equal(remoteFixture.PubKey.Remote, remote.GetPublicKey().GetRemote()) + testCases := []struct { + name string + input interface{} // Can be string or struct + expected fixtures.FixtureDataKasRegistry + identifierType string // For clearer test case names + }{ + { + name: "Deprecated ID - Remote", + input: remoteFixture.ID, + expected: remoteFixture, + identifierType: "ID", + }, + { + name: "Deprecated ID - Local", + input: localFixture.ID, + expected: localFixture, + identifierType: "ID", + }, + { + name: "Name Identifier - Remote", + input: &kasregistry.GetKeyAccessServerRequest_Name{Name: remoteFixture.Name}, + expected: remoteFixture, + identifierType: "Name", + }, + { + name: "Name Identifier - Local", + input: &kasregistry.GetKeyAccessServerRequest_Name{Name: localFixture.Name}, + expected: localFixture, + identifierType: "Name", + }, + { + name: "URI Identifier - Remote", + input: &kasregistry.GetKeyAccessServerRequest_Uri{Uri: remoteFixture.URI}, + expected: remoteFixture, + identifierType: "URI", + }, + { + name: "URI Identifier - Local", + input: &kasregistry.GetKeyAccessServerRequest_Uri{Uri: localFixture.URI}, + expected: localFixture, + identifierType: "URI", + }, + } - local, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, localFixture.ID) - s.Require().NoError(err) - s.NotNil(local) - s.Equal(localFixture.ID, local.GetId()) - s.Equal(localFixture.URI, local.GetUri()) - s.Equal(localFixture.Name, local.GetName()) - s.Equal(localFixture.PubKey.Cached, local.GetPublicKey().GetCached()) + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get KeyAccessServer by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(resp, "Expected non-nil response for %s: %v", tc.identifierType, tc.input) + + s.Equal(tc.expected.ID, resp.GetId(), "ID mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(tc.expected.URI, resp.GetUri(), "URI mismatch for %s: %v", tc.identifierType, tc.input) + s.Equal(tc.expected.Name, resp.GetName(), "Name mismatch for %s: %v", tc.identifierType, tc.input) + + switch tc.expected { + case remoteFixture: + s.Equal(tc.expected.PubKey.Remote, resp.GetPublicKey().GetRemote(), "PublicKey.Remote mismatch for %s: %v", tc.identifierType, tc.input) + case localFixture: + s.Equal(tc.expected.PubKey.Cached, resp.GetPublicKey().GetCached(), "PublicKey.Cached mismatch for %s: %v", tc.identifierType, tc.input) + default: + s.Fail("Unexpected fixture in test case: %s", tc.name) // Should not happen, but good to have for safety + } + }) + } } func (s *KasRegistrySuite) Test_GetKeyAccessServer_WithNonExistentId_Fails() { - resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, nonExistentKasRegistryID) - s.Require().Error(err) - s.Nil(resp) - s.Require().ErrorIs(err, db.ErrNotFound) + testCases := []struct { + name string + input interface{} + }{ + { + name: "string non-existent UUID", + input: nonExistentKasRegistryID, + }, + { + name: "struct non-existent UUID", + input: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: nonExistentKasRegistryID, + }, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, tc.input) + s.Require().Error(err, "Expected an error for input: %s", tc.input) + s.Nil(resp, "Expected nil response for input: %s", tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound for input: %s", tc.input) + }) + } } func (s *KasRegistrySuite) Test_GetKeyAccessServer_WithInvalidID_Fails() { - resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, "hello") - s.Require().Error(err) - s.Nil(resp) - s.Require().ErrorIs(err, db.ErrUUIDInvalid) + testCases := []struct { + name string + input interface{} + }{ + { + name: "string invalid UUID", + input: "hello", + }, + { + name: "struct invalid UUID", + input: &kasregistry.GetKeyAccessServerRequest_KasId{KasId: "hello"}, + }, + { + name: "empty string", + input: "", + }, + { + name: "struct empty string", + input: &kasregistry.GetKeyAccessServerRequest_KasId{KasId: ""}, + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + resp, err := s.db.PolicyClient.GetKeyAccessServer(s.ctx, tc.input) + s.Require().Error(err) + s.Nil(resp) + s.Require().ErrorIs(err, db.ErrUUIDInvalid) + }) + } } func (s *KasRegistrySuite) Test_CreateKeyAccessServer_Remote() { @@ -1023,7 +1118,9 @@ func (s *KasRegistrySuite) Test_Create_Public_Key() { // The initial rsa2048 public key is created in the fixture and should be active kID := s.f.GetPublicKey("key_1").ID - r1, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: kID}) + r1, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: kID}, + }) s.Require().NoError(err) s.NotNil(r1) s.True(r1.GetKey().GetIsActive().GetValue()) @@ -1047,7 +1144,9 @@ func (s *KasRegistrySuite) Test_Create_Public_Key() { publicKeyTestUUID = r2.GetKey().GetId() // Now the old key should be inactive - r3, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: kID}) + r3, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: kID}, + }) s.Require().NoError(err) s.NotNil(r3) s.False(r3.GetKey().GetIsActive().GetValue()) @@ -1150,7 +1249,9 @@ func (s *KasRegistrySuite) Test_Update_Public_Key() { s.Equal(labels, resp.GetKey().GetMetadata().GetLabels()) // Get Key to validate update - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: kID}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: kID}, + }) s.Require().NoError(err) s.NotNil(r) s.Equal(labels, r.GetKey().GetMetadata().GetLabels()) @@ -1161,7 +1262,9 @@ func (s *KasRegistrySuite) Test_Get_Public_Key() { keyID := s.f.GetPublicKey("key_1").Key.Kid id := s.f.GetPublicKey("key_1").ID - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().NoError(err) s.NotNil(r) @@ -1171,7 +1274,9 @@ func (s *KasRegistrySuite) Test_Get_Public_Key() { } func (s *KasRegistrySuite) Test_Get_Public_Key_WithInvalidID_Fails() { - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: "invalid-id"}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: "invalid-id"}, + }) s.Require().Error(err) s.Nil(r) @@ -1179,7 +1284,9 @@ func (s *KasRegistrySuite) Test_Get_Public_Key_WithInvalidID_Fails() { } func (s *KasRegistrySuite) Test_Get_Public_Key_WithNotFoundID_Fails() { - r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: nonExistentKasRegistryID}) + r, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: nonExistentKasRegistryID}, + }) s.Require().Error(err) s.Nil(r) @@ -1193,26 +1300,63 @@ func (s *KasRegistrySuite) Test_List_Public_Keys() { s.GreaterOrEqual(len(r.GetKeys()), 2) } -func (s *KasRegistrySuite) Test_List_Public_Keys_ByKasID() { - kasID := s.f.GetKasRegistryKey("key_access_server_1").ID - r, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{KasId: kasID}) +func (s *KasRegistrySuite) Test_List_Public_Keys_By_KAS() { + rAllKeys, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{}) s.Require().NoError(err) - s.NotNil(r) - s.GreaterOrEqual(len(r.GetKeys()), 1) - for _, key := range r.GetKeys() { - s.Equal(kasID, key.GetKas().GetId()) - } + s.NotNil(rAllKeys) + totalKeys := rAllKeys.GetPagination().GetTotal() - filteredTotalKeys := r.GetPagination().GetTotal() + kas1 := s.f.GetKasRegistryKey("key_access_server_1") - r, err = s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{}) - s.Require().NoError(err) - s.NotNil(r) + testCases := []struct { + name string + req *kasregistry.ListPublicKeysRequest + identifierType string + }{ + { + name: "List by KAS ID", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: kas1.ID, + }, + }, + identifierType: "KAS ID", + }, + { + name: "List by KAS URI", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: kas1.URI, + }, + }, + identifierType: "KAS URI", + }, + { + name: "List by KAS Name", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasName{ + KasName: kas1.Name, + }, + }, + identifierType: "KAS Name", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + rFilteredKeys, err := s.db.PolicyClient.ListPublicKeys(s.ctx, tc.req) + s.Require().NoError(err, "Failed to list keys by %s", tc.identifierType) + s.Require().NotNil(rFilteredKeys, "Expected non-nil response when listing keys by %s", tc.identifierType) + s.GreaterOrEqual(len(rFilteredKeys.GetKeys()), 1, "Expected at least 1 key when listing by %s", tc.identifierType) - totalKeys := r.GetPagination().GetTotal() + for _, key := range rFilteredKeys.GetKeys() { + s.Equal(kas1.ID, key.GetKas().GetId(), "Key KAS ID mismatch when listing by %s", tc.identifierType) + } - // Fixtures have multiple kas keys, so the total keys should be greater than the filtered total keys - s.NotEqual(totalKeys, filteredTotalKeys) + filteredTotalKeys := rFilteredKeys.GetPagination().GetTotal() + s.NotEqual(totalKeys, filteredTotalKeys, "Total keys should be different after filtering by %s", tc.identifierType) + }) + } } func (s *KasRegistrySuite) Test_List_Public_Keys_WithLimit_1() { @@ -1227,7 +1371,11 @@ func (s *KasRegistrySuite) Test_List_Public_Keys_WithLimit_1() { } func (s *KasRegistrySuite) Test_List_Public_Keys_WithNonExistentKasID() { - r, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{KasId: nonExistentKasRegistryID}) + r, err := s.db.PolicyClient.ListPublicKeys(s.ctx, &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: nonExistentKasRegistryID, + }, + }) s.Require().NoError(err) s.NotNil(r) s.Empty(r.GetKeys()) @@ -1236,7 +1384,11 @@ func (s *KasRegistrySuite) Test_List_Public_Keys_WithNonExistentKasID() { func (s *KasRegistrySuite) Test_List_Public_Key_Mappings() { kasid := s.f.GetPublicKey("key_1").KasID id := s.f.GetPublicKey("key_1").ID - r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, &kasregistry.ListPublicKeyMappingRequest{KasId: kasid}) + r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: kasid, + }, + }) s.Require().NoError(err) s.NotNil(r) s.Len(r.GetPublicKeyMappings(), 1) @@ -1271,15 +1423,60 @@ func (s *KasRegistrySuite) Test_List_Public_Key_Mappings_WithLimit_1() { s.Len(r.GetPublicKeyMappings(), 1) } -func (s *KasRegistrySuite) Test_List_Public_Key_Mappings_By_KAS_ID() { - kasID := s.f.GetKasRegistryKey("key_access_server_1").ID - r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, &kasregistry.ListPublicKeyMappingRequest{KasId: kasID}) - s.Require().NoError(err) - s.NotNil(r) - s.Len(r.GetPublicKeyMappings(), 1) +func (s *KasRegistrySuite) Test_List_Public_Key_Mappings_By_KAS() { + kas := s.f.GetKasRegistryKey("key_access_server_1") + pk := s.f.GetPublicKey("key_1") + + testCases := []struct { + name string + req *kasregistry.ListPublicKeyMappingRequest + identifierType string + }{ + { + name: "List by KAS ID", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: kas.ID, + }, + }, + identifierType: "KAS ID", + }, + { + name: "List by KAS URI", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: kas.URI, + }, + }, + identifierType: "KAS URI", + }, + { + name: "List by KAS Name", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasName{ + KasName: kas.Name, + }, + }, + identifierType: "KAS Name", + }, + } - for _, m := range r.GetPublicKeyMappings() { - s.Equal(kasID, m.GetKasId()) + for _, tc := range testCases { + s.Run(tc.name, func() { + r, err := s.db.PolicyClient.ListPublicKeyMappings(s.ctx, tc.req) + s.Require().NoError(err, "Failed to list mappings by %s", tc.identifierType) + s.Require().NotNil(r, "Expected non-nil response when listing mappings by %s", tc.identifierType) + s.Len(r.GetPublicKeyMappings(), 1, "Expected 1 mapping when listing by %s", tc.identifierType) // Assuming fixture setup ensures 1 mapping + + for _, m := range r.GetPublicKeyMappings() { + s.Equal(kas.ID, m.GetKasId(), "KasId mismatch when listing by %s", tc.identifierType) + s.Equal(kas.URI, m.GetKasUri(), "KasUri mismatch when listing by %s", tc.identifierType) + s.Equal(kas.Name, m.GetKasName(), "KasName mismatch when listing by %s", tc.identifierType) + s.True(slices.ContainsFunc(m.GetPublicKeys(), func(key *kasregistry.ListPublicKeyMappingResponse_PublicKey) bool { + return key.GetKey().GetId() == pk.ID + }), "PublicKey not found in mappings when listing by %s", tc.identifierType) + } + }) } } @@ -1303,7 +1500,9 @@ func (s *KasRegistrySuite) Test_Deactivate_Public_Key() { s.NotNil(r) s.Equal(id, r.GetKey().GetId()) - rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().NoError(err) s.NotNil(rr) s.False(rr.GetKey().GetIsActive().GetValue()) @@ -1323,7 +1522,9 @@ func (s *KasRegistrySuite) Test_Activate_Public_Key() { s.NotNil(r) s.Equal(id, r.GetKey().GetId()) - rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().NoError(err) s.NotNil(rr) s.True(rr.GetKey().GetIsActive().GetValue()) @@ -1343,7 +1544,9 @@ func (s *KasRegistrySuite) Test_UnsafeDelete_Public_Key() { s.NotNil(r) s.Equal(id, r.GetId()) - rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + rr, err := s.db.PolicyClient.GetPublicKey(s.ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{Id: id}, + }) s.Require().Error(err) s.Require().ErrorIs(err, db.ErrNotFound) s.Nil(rr) diff --git a/service/integration/namespaces_test.go b/service/integration/namespaces_test.go index 1409db647..802440324 100644 --- a/service/integration/namespaces_test.go +++ b/service/integration/namespaces_test.go @@ -2,6 +2,7 @@ package integration import ( "context" + "fmt" "log/slog" "strings" "testing" @@ -93,22 +94,83 @@ func (s *NamespacesSuite) Test_GetNamespace() { testData := s.getActiveNamespaceFixtures() for _, test := range testData { - gotNamespace, err := s.db.PolicyClient.GetNamespace(s.ctx, test.ID) - s.Require().NoError(err) - s.NotNil(gotNamespace) - // name retrieved by ID equal to name used to create - s.Equal(test.Name, gotNamespace.GetName()) - metadata := gotNamespace.GetMetadata() - createdAt := metadata.GetCreatedAt() - updatedAt := metadata.GetUpdatedAt() - s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0) - s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0) + testCases := []struct { + name string + input interface{} + identifierType string + }{ + { + name: "Deprecated ID", + input: test.ID, + identifierType: "Deprecated ID", + }, + { + name: "New Identifier - ID", + input: &namespaces.GetNamespaceRequest_NamespaceId{NamespaceId: test.ID}, + identifierType: "New ID", + }, + { + name: "New Identifier - FQN", + input: &namespaces.GetNamespaceRequest_Fqn{Fqn: test.Name}, + identifierType: "FQN", + }, + } + + for _, tc := range testCases { + s.Run(fmt.Sprintf("%s - %s", test.Name, tc.name), func() { // Include namespace name in test name + gotNamespace, err := s.db.PolicyClient.GetNamespace(s.ctx, tc.input) + s.Require().NoError(err, "Failed to get Namespace by %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(gotNamespace, "Expected non-nil Namespace for %s: %v", tc.identifierType, tc.input) + + // name retrieved by ID equal to name used to create + s.Equal(test.Name, gotNamespace.GetName(), "Name mismatch for %s: %v", tc.identifierType, tc.input) + + metadata := gotNamespace.GetMetadata() + s.Require().NotNil(metadata, "Metadata should not be nil for %s: %v", tc.identifierType, tc.input) + createdAt := metadata.GetCreatedAt() + updatedAt := metadata.GetUpdatedAt() + s.Require().NotNil(createdAt, "CreatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + s.Require().NotNil(updatedAt, "UpdatedAt should not be nil for %s: %v", tc.identifierType, tc.input) + + s.True(createdAt.IsValid() && createdAt.AsTime().Unix() > 0, "CreatedAt is invalid for %s: %v", tc.identifierType, tc.input) + s.True(updatedAt.IsValid() && updatedAt.AsTime().Unix() > 0, "UpdatedAt is invalid for %s: %v", tc.identifierType, tc.input) + }) + } } +} - // Getting a namespace with an nonExistent id should fail - _, err := s.db.PolicyClient.GetNamespace(s.ctx, nonExistentNamespaceID) - s.Require().Error(err) - s.Require().ErrorIs(err, db.ErrNotFound) +func (s *NamespacesSuite) Test_GetNamespace_NotFound() { + testCases := []struct { + name string + input interface{} // Input to GetNamespace - could be ID string or identifier struct + identifierType string // For descriptive error messages + }{ + { + name: "Not Found - Deprecated ID", + input: nonExistentNamespaceID, // Assuming nonExistentNamespaceID is defined in your test suite + identifierType: "Deprecated ID", + }, + { + name: "Not Found - New Identifier ID", + input: &namespaces.GetNamespaceRequest_NamespaceId{NamespaceId: nonExistentNamespaceID}, + identifierType: "New ID", + }, + { + name: "Not Found - New Identifier FQN", + input: &namespaces.GetNamespaceRequest_Fqn{Fqn: "non-existent-namespace-fqn"}, // Example non-existent FQN + identifierType: "FQN", + }, + // Add more test cases here if you want to test other "not found" scenarios + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + gotNamespace, err := s.db.PolicyClient.GetNamespace(s.ctx, tc.input) + s.Require().Error(err, "Expected error when Namespace is not found by %s: %v", tc.identifierType, tc.input) + s.Nil(gotNamespace, "Expected nil Namespace when not found by %s: %v", tc.identifierType, tc.input) + s.Require().ErrorIs(err, db.ErrNotFound, "Expected ErrNotFound when Namespace is not found by %s: %v", tc.identifierType, tc.input) + }) + } } func (s *NamespacesSuite) Test_GetNamespace_InactiveState_Succeeds() { @@ -122,13 +184,6 @@ func (s *NamespacesSuite) Test_GetNamespace_InactiveState_Succeeds() { s.Equal(inactive.Name, got.GetName()) } -func (s *NamespacesSuite) Test_GetNamespace_DoesNotExist_ShouldFail() { - ns, err := s.db.PolicyClient.GetNamespace(s.ctx, nonExistentNamespaceID) - s.Require().Error(err) - s.Require().ErrorIs(err, db.ErrNotFound) - s.Nil(ns) -} - func (s *NamespacesSuite) Test_ListNamespaces_NoPagination_Succeeds() { testData := s.getActiveNamespaceFixtures() diff --git a/service/pkg/db/errors.go b/service/pkg/db/errors.go index c848483a5..dafd3b975 100644 --- a/service/pkg/db/errors.go +++ b/service/pkg/db/errors.go @@ -25,6 +25,8 @@ var ( ErrTxBeginFailed = errors.New("ErrTxBeginFailed: failed to begin DB transaction") ErrTxRollbackFailed = errors.New("ErrTxRollbackFailed: failed to rollback DB transaction") ErrTxCommitFailed = errors.New("ErrTxCommitFailed: failed to commit DB transaction") + ErrSelectIdentifierInvalid = errors.New("ErrSelectIdentifierInvalid: invalid identifier value for select query") + ErrUnknownSelectIdentifier = errors.New("ErrUnknownSelectIdentifier: unknown identifier type for select query") ) // Get helpful error message for PostgreSQL violation @@ -102,6 +104,8 @@ const ( ErrTextRestrictViolation = "intended action would violate a restriction" ErrTextFqnMissingValue = "FQN must specify a valid value and be of format 'https:///attr//value/'" ErrTextListLimitTooLarge = "requested pagination limit must be less than or equal to configured limit" + ErrTextInvalidIdentifier = "value sepcified as the identifier is invalid" + ErrorTextUnknownIdentifier = "could not match identifier to known type" ) func StatusifyError(err error, fallbackErr string, log ...any) error { @@ -134,6 +138,14 @@ func StatusifyError(err error, fallbackErr string, log ...any) error { slog.Error(ErrTextListLimitTooLarge, l...) return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextListLimitTooLarge)) } + if errors.Is(err, ErrSelectIdentifierInvalid) { + slog.Error(ErrTextInvalidIdentifier, l...) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrTextInvalidIdentifier)) + } + if errors.Is(err, ErrUnknownSelectIdentifier) { + slog.Error(ErrorTextUnknownIdentifier, l...) + return connect.NewError(connect.CodeInvalidArgument, errors.New(ErrorTextUnknownIdentifier)) + } slog.Error(err.Error(), l...) return connect.NewError(connect.CodeInternal, errors.New(fallbackErr)) } diff --git a/service/policy/attributes/attributes.go b/service/policy/attributes/attributes.go index 3400f3b30..7e5e65ab8 100644 --- a/service/policy/attributes/attributes.go +++ b/service/policy/attributes/attributes.go @@ -96,9 +96,17 @@ func (s *AttributesService) GetAttribute(ctx context.Context, ) (*connect.Response[attributes.GetAttributeResponse], error) { rsp := &attributes.GetAttributeResponse{} - item, err := s.dbClient.GetAttribute(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + item, err := s.dbClient.GetAttribute(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.Attribute = item @@ -236,9 +244,17 @@ func (s *AttributesService) ListAttributeValues(ctx context.Context, req *connec func (s *AttributesService) GetAttributeValue(ctx context.Context, req *connect.Request[attributes.GetAttributeValueRequest]) (*connect.Response[attributes.GetAttributeValueResponse], error) { rsp := &attributes.GetAttributeValueResponse{} - item, err := s.dbClient.GetAttributeValue(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + item, err := s.dbClient.GetAttributeValue(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.Value = item diff --git a/service/policy/attributes/attributes.proto b/service/policy/attributes/attributes.proto index 42f01708d..f7b614ca5 100644 --- a/service/policy/attributes/attributes.proto +++ b/service/policy/attributes/attributes.proto @@ -86,10 +86,38 @@ message ListAttributesResponse { } message GetAttributeRequest { - // Required + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.attribute_id) || has(this.fqn)))", + message: "Either use deprecated 'id' field or one of 'attribute_id' or 'fqn', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.attribute_id) || has(this.fqn)", + message: "Either id or one of attribute_id or fqn must be set" + }; + + // Deprecated string id = 1 [ - (buf.validate.field).string.uuid = true - ]; + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true + ];; + + oneof identifier { + //option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string attribute_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string fqn = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } } message GetAttributeResponse { policy.Attribute attribute = 1; @@ -167,10 +195,39 @@ message DeactivateAttributeResponse { /// Value RPC messages /// message GetAttributeValueRequest { - // Required + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.value_id) || has(this.fqn)))", + message: "Either use deprecated 'id' field or one of 'value_id' or 'fqn', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.value_id) || has(this.fqn)", + message: "Either id or one of value_id or fqn must be set" + }; + + // Deprecated string id = 1 [ - (buf.validate.field).string.uuid = true - ]; + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true + ];; + + oneof identifier { + //option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string value_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string fqn = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } + } message GetAttributeValueResponse { policy.Value value = 1; diff --git a/service/policy/attributes/attributes_test.go b/service/policy/attributes/attributes_test.go index 7cf1f9d3f..075678bca 100644 --- a/service/policy/attributes/attributes_test.go +++ b/service/policy/attributes/attributes_test.go @@ -29,6 +29,10 @@ const ( errMessageAttrNameFormat = "attribute_name_format" errMessageAttrValueFormat = "attribute_value_format" errMessageRequired = "required" + errMessageMinLen = "string.min_len" + errMessageURI = "string.uri" + errRequiredField = "required_fields" + errExclusiveFields = "exclusive_fields" ) // Create Attributes (definitions) @@ -233,17 +237,118 @@ func TestAttributeKeyAccessServer_Fails(t *testing.T) { } } -func TestGetAttributeRequest(t *testing.T) { - req := &attributes.GetAttributeRequest{} - err := getValidator().Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) +func Test_GetAttributeRequest(t *testing.T) { + testCases := []struct { + name string + req *attributes.GetAttributeRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid AttributeId in Identifier (empty string)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_AttributeId{ + AttributeId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid AttributeId in Identifier (invalid UUID)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_AttributeId{ + AttributeId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid Deprecated Id", + req: &attributes.GetAttributeRequest{ + Id: validUUID, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &attributes.GetAttributeRequest{ + Id: "", + }, + expectError: true, + errorMessage: errRequiredField, + }, + { + name: "Valid AttributeId in Identifier", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_AttributeId{ + AttributeId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Valid FQN Identifier", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "https://example.com/valid_fqn", + }, + }, + expectError: false, + }, + { + name: "Invalid FQN Identifier (missing scheme)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "example.com/valid_fqn", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid FQN Identifier (empty string)", + req: &attributes.GetAttributeRequest{ + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Invalid can't have both Id and Identifier", + req: &attributes.GetAttributeRequest{ + Id: validUUID, + Identifier: &attributes.GetAttributeRequest_Fqn{ + Fqn: "https://example.com/valid_fqn", + }, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &attributes.GetAttributeRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - req = &attributes.GetAttributeRequest{ - Id: validUUID, + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) } - err = getValidator().Validate(req) - require.NoError(t, err) } func TestUpdateAttributeRequest(t *testing.T) { @@ -401,17 +506,118 @@ func TestValueKeyAccessServer_Fails(t *testing.T) { } } -func TestGetAttributeValueRequest(t *testing.T) { - req := &attributes.GetAttributeValueRequest{} - err := getValidator().Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) +func Test_GetAttributeValueRequest(t *testing.T) { + testCases := []struct { + name string + req *attributes.GetAttributeValueRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid ValueId in Identifier (empty string)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_ValueId{ + ValueId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid ValueId in Identifier (invalid UUID)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_ValueId{ + ValueId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid Deprecated Id", + req: &attributes.GetAttributeValueRequest{ + Id: validUUID, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &attributes.GetAttributeValueRequest{ + Id: "", + }, + expectError: true, + errorMessage: errRequiredField, + }, + { + name: "Valid ValueId in Identifier", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_ValueId{ + ValueId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Valid FQN Identifier", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "https://example.com/valid_fqn_value", + }, + }, + expectError: false, + }, + { + name: "Invalid FQN Identifier (missing scheme)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "example.com/valid_fqn_value", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid FQN Identifier (empty string)", + req: &attributes.GetAttributeValueRequest{ + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Invalid can't have both Id and Identifier", + req: &attributes.GetAttributeValueRequest{ + Id: validUUID, + Identifier: &attributes.GetAttributeValueRequest_Fqn{ + Fqn: "https://example.com/valid_fqn_value", + }, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &attributes.GetAttributeValueRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - req = &attributes.GetAttributeValueRequest{ - Id: validUUID, + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) } - err = getValidator().Validate(req) - require.NoError(t, err) } func TestListAttributeValuesRequest(t *testing.T) { diff --git a/service/policy/db/attribute_values.go b/service/policy/db/attribute_values.go index 6f6af26cb..22ac86fa2 100644 --- a/service/policy/db/attribute_values.go +++ b/service/policy/db/attribute_values.go @@ -2,6 +2,7 @@ package db import ( "context" + "errors" "fmt" "log/slog" "strings" @@ -41,8 +42,38 @@ func (c PolicyDBClient) CreateAttributeValue(ctx context.Context, attributeID st return c.GetAttributeValue(ctx, createdID) } -func (c PolicyDBClient) GetAttributeValue(ctx context.Context, id string) (*policy.Value, error) { - av, err := c.Queries.GetAttributeValue(ctx, id) +func (c PolicyDBClient) GetAttributeValue(ctx context.Context, identifier any) (*policy.Value, error) { + var ( + av GetAttributeValueRow + err error + params GetAttributeValueParams + ) + + switch i := identifier.(type) { + case *attributes.GetAttributeValueRequest_ValueId: + id := pgtypeUUID(i.ValueId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeValueParams{ID: id} + case *attributes.GetAttributeValueRequest_Fqn: + fqn := pgtypeText(i.Fqn) + if !fqn.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetAttributeValueParams{Fqn: fqn} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeValueParams{ID: pgtypeUUID(i)} + default: + // unexpected type + return nil, errors.Join(db.ErrUnknownSelectIdentifier, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + av, err = c.Queries.GetAttributeValue(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } diff --git a/service/policy/db/attributes.go b/service/policy/db/attributes.go index d6c76a9c6..087ae7461 100644 --- a/service/policy/db/attributes.go +++ b/service/policy/db/attributes.go @@ -4,6 +4,7 @@ import ( "context" "database/sql" "encoding/json" + "errors" "fmt" "strings" @@ -218,8 +219,38 @@ func (c PolicyDBClient) ListAllAttributes(ctx context.Context) ([]*policy.Attrib return attrsList, nil } -func (c PolicyDBClient) GetAttribute(ctx context.Context, id string) (*policy.Attribute, error) { - attr, err := c.Queries.GetAttribute(ctx, id) +func (c PolicyDBClient) GetAttribute(ctx context.Context, identifier any) (*policy.Attribute, error) { + var ( + attr GetAttributeRow + err error + params GetAttributeParams + ) + + switch i := identifier.(type) { + case *attributes.GetAttributeRequest_AttributeId: + id := pgtypeUUID(i.AttributeId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeParams{ID: id} + case *attributes.GetAttributeRequest_Fqn: + fqn := pgtypeText(i.Fqn) + if !fqn.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetAttributeParams{Fqn: pgtypeText(i.Fqn)} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetAttributeParams{ID: id} + default: + // unexpected type + return nil, errors.Join(db.ErrSelectIdentifierInvalid, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + attr, err = c.Queries.GetAttribute(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } diff --git a/service/policy/db/key_access_server_registry.go b/service/policy/db/key_access_server_registry.go index d089cea7f..038ff57dc 100644 --- a/service/policy/db/key_access_server_registry.go +++ b/service/policy/db/key_access_server_registry.go @@ -2,6 +2,7 @@ package db import ( "context" + "errors" "fmt" "strings" @@ -72,8 +73,44 @@ func (c PolicyDBClient) ListKeyAccessServers(ctx context.Context, r *kasregistry }, nil } -func (c PolicyDBClient) GetKeyAccessServer(ctx context.Context, id string) (*policy.KeyAccessServer, error) { - kas, err := c.Queries.GetKeyAccessServer(ctx, id) +func (c PolicyDBClient) GetKeyAccessServer(ctx context.Context, identifier any) (*policy.KeyAccessServer, error) { + var ( + kas GetKeyAccessServerRow + err error + params GetKeyAccessServerParams + ) + + switch i := identifier.(type) { + case *kasregistry.GetKeyAccessServerRequest_KasId: + id := pgtypeUUID(i.KasId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetKeyAccessServerParams{ID: id} + case *kasregistry.GetKeyAccessServerRequest_Name: + name := pgtypeText(i.Name) + if !name.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetKeyAccessServerParams{Name: name} + case *kasregistry.GetKeyAccessServerRequest_Uri: + uri := pgtypeText(i.Uri) + if !uri.Valid { + return nil, db.ErrSelectIdentifierInvalid + } + params = GetKeyAccessServerParams{Uri: uri} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetKeyAccessServerParams{ID: id} + default: + // unexpected type + return nil, errors.Join(db.ErrUnknownSelectIdentifier, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + kas, err = c.Queries.GetKeyAccessServer(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } @@ -287,7 +324,11 @@ func (c PolicyDBClient) CreatePublicKey(ctx context.Context, r *kasregistry.Crea } // Get freshly created key - ck, err = txClient.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{Id: id}) + ck, err = txClient.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: id, + }, + }) if err != nil { return db.WrapIfKnownInvalidQueryErr(err) } @@ -352,11 +393,11 @@ func (c PolicyDBClient) ListPublicKeys(ctx context.Context, r *kasregistry.ListP } params := listPublicKeysParams{ - KasID: r.GetKasId(), - // KasUri: r.GetKasUri(), - // KasName: r.GetKasName(), - Offset: offset, - Limit: limit, + KasID: r.GetKasId(), + KasUri: r.GetKasUri(), + KasName: r.GetKasName(), + Offset: offset, + Limit: limit, } listRows, err := c.Queries.listPublicKeys(ctx, params) if err != nil { @@ -411,9 +452,9 @@ func (c PolicyDBClient) ListPublicKeyMappings(ctx context.Context, r *kasregistr } params := listPublicKeyMappingsParams{ - KasID: r.GetKasId(), - // KasUri: r.GetKasUri(), - // KasName: r.GetKasName(), + KasID: r.GetKasId(), + KasUri: r.GetKasUri(), + KasName: r.GetKasName(), PublicKeyID: r.GetPublicKeyId(), Offset: offset, Limit: limit, @@ -455,7 +496,11 @@ func (c PolicyDBClient) UpdatePublicKey(ctx context.Context, r *kasregistry.Upda keyID := r.GetId() mdJSON, metadata, err := db.MarshalUpdateMetadata(r.GetMetadata(), r.GetMetadataUpdateBehavior(), func() (*common.Metadata, error) { - k, err := c.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{Id: keyID}) + k, err := c.GetPublicKey(ctx, &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: keyID, + }, + }) if err != nil { return nil, err } diff --git a/service/policy/db/namespaces.go b/service/policy/db/namespaces.go index b3dbb8ac3..7bb94b24c 100644 --- a/service/policy/db/namespaces.go +++ b/service/policy/db/namespaces.go @@ -2,6 +2,7 @@ package db import ( "context" + "errors" "fmt" "log/slog" "strings" @@ -14,8 +15,34 @@ import ( "google.golang.org/protobuf/types/known/wrapperspb" ) -func (c PolicyDBClient) GetNamespace(ctx context.Context, id string) (*policy.Namespace, error) { - ns, err := c.Queries.GetNamespace(ctx, id) +func (c PolicyDBClient) GetNamespace(ctx context.Context, identifier any) (*policy.Namespace, error) { + var ( + ns GetNamespaceRow + err error + params GetNamespaceParams + ) + + switch i := identifier.(type) { + case *namespaces.GetNamespaceRequest_NamespaceId: + id := pgtypeUUID(i.NamespaceId) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetNamespaceParams{ID: id} + case *namespaces.GetNamespaceRequest_Fqn: + params = GetNamespaceParams{Name: pgtypeText(i.Fqn)} + case string: + id := pgtypeUUID(i) + if !id.Valid { + return nil, db.ErrUUIDInvalid + } + params = GetNamespaceParams{ID: id} + default: + // unexpected type + return nil, errors.Join(db.ErrUnknownSelectIdentifier, fmt.Errorf("type [%T] value [%v]", i, i)) + } + + ns, err = c.Queries.GetNamespace(ctx, params) if err != nil { return nil, db.WrapIfKnownInvalidQueryErr(err) } @@ -44,7 +71,7 @@ func (c PolicyDBClient) GetNamespace(ctx context.Context, id string) (*policy.Na } return &policy.Namespace{ - Id: id, + Id: ns.ID, Name: ns.Name, Active: &wrapperspb.BoolValue{Value: ns.Active}, Grants: grants, diff --git a/service/policy/db/query.sql b/service/policy/db/query.sql index 03d700ee5..17fb3c83e 100644 --- a/service/policy/db/query.sql +++ b/service/policy/db/query.sql @@ -87,13 +87,15 @@ OFFSET @offset_; -- name: GetKeyAccessServer :one SELECT - id, - uri, - public_key, - name, + kas.id, + kas.uri, + kas.public_key, + kas.name, JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', metadata -> 'labels', 'created_at', created_at, 'updated_at', updated_at)) AS metadata -FROM key_access_servers -WHERE id = $1; +FROM key_access_servers AS kas +WHERE (sqlc.narg('id')::uuid IS NULL OR kas.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('name')::text IS NULL OR kas.name = sqlc.narg('name')::text) + AND (sqlc.narg('uri')::text IS NULL OR kas.uri = sqlc.narg('uri')::text); -- name: CreateKeyAccessServer :one INSERT INTO key_access_servers (uri, public_key, name, metadata) @@ -490,7 +492,8 @@ LEFT JOIN attribute_definition_key_access_grants adkag ON adkag.attribute_defini LEFT JOIN key_access_servers kas ON kas.id = adkag.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.attribute_id = ad.id AND fqns.value_id IS NULL LEFT JOIN active_definition_public_keys_view k ON ad.id = k.definition_id -WHERE ad.id = $1 +WHERE (sqlc.narg('id')::uuid IS NULL OR ad.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('fqn')::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE(sqlc.narg('fqn')::text, '^https?://', '')) GROUP BY ad.id, n.name, fqns.fqn, k.keys; -- name: CreateAttribute :one @@ -569,7 +572,8 @@ LEFT JOIN attribute_fqns fqns ON av.id = fqns.value_id LEFT JOIN attribute_value_key_access_grants avkag ON av.id = avkag.attribute_value_id LEFT JOIN key_access_servers kas ON avkag.key_access_server_id = kas.id LEFT JOIN active_value_public_keys_view k ON av.id = k.value_id -WHERE av.id = $1 +WHERE (sqlc.narg('id')::uuid IS NULL OR av.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('fqn')::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE(sqlc.narg('fqn')::text, '^https?://', '')) GROUP BY av.id, fqns.fqn, k.keys; -- name: CreateAttributeValue :one @@ -765,7 +769,9 @@ LEFT JOIN attribute_namespace_key_access_grants kas_ns_grants ON kas_ns_grants.n LEFT JOIN key_access_servers kas ON kas.id = kas_ns_grants.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = ns.id LEFT JOIN active_namespace_public_keys_view k ON ns.id = k.namespace_id -WHERE ns.id = $1 AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL +WHERE fqns.attribute_id IS NULL AND fqns.value_id IS NULL + AND (sqlc.narg('id')::uuid IS NULL OR ns.id = sqlc.narg('id')::uuid) + AND (sqlc.narg('name')::text IS NULL OR ns.name = REGEXP_REPLACE(sqlc.narg('name')::text, '^https?://', '')) GROUP BY ns.id, fqns.fqn, k.keys; -- name: CreateNamespace :one @@ -958,8 +964,11 @@ WHERE k.id = $1; -- name: listPublicKeys :many WITH counted AS ( - SELECT COUNT(k.id) AS total FROM public_keys AS k - WHERE (NULLIF(@kas_id, '') IS NULL OR k.key_access_server_id = @kas_id::uuid) + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id + WHERE (NULLIF(@kas_id, '') IS NULL OR kas.id = @kas_id::uuid) + AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) + AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) ) SELECT @@ -980,13 +989,18 @@ CROSS JOIN counted WHERE ( NULLIF(@kas_id, '') IS NULL OR k.key_access_server_id = @kas_id::uuid ) +AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) +AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) LIMIT @limit_ OFFSET @offset_; -- name: listPublicKeyMappings :many WITH counted AS ( - SELECT COUNT(pk.id) AS total FROM public_keys AS pk + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE (NULLIF(@kas_id, '') IS NULL OR pk.key_access_server_id = @kas_id::uuid) + AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) + AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) AND ( NULLIF(@public_key_id, '') IS NULL OR pk.id = @public_key_id::uuid ) ), base_keys AS ( @@ -1003,6 +1017,8 @@ base_keys AS ( FROM public_keys pk JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE ( NULLIF(@kas_id, '') IS NULL OR kas.id = @kas_id::uuid ) + AND (NULLIF(@kas_name, '') IS NULL OR kas.name = @kas_name) + AND (NULLIF(@kas_uri, '') IS NULL OR kas.uri = @kas_uri) AND ( NULLIF(@public_key_id, '') IS NULL OR pk.id = @public_key_id::uuid ) ), namespace_mappings AS ( diff --git a/service/policy/db/query.sql.go b/service/policy/db/query.sql.go index fcb009d56..2da4cb511 100644 --- a/service/policy/db/query.sql.go +++ b/service/policy/db/query.sql.go @@ -487,10 +487,16 @@ LEFT JOIN attribute_definition_key_access_grants adkag ON adkag.attribute_defini LEFT JOIN key_access_servers kas ON kas.id = adkag.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.attribute_id = ad.id AND fqns.value_id IS NULL LEFT JOIN active_definition_public_keys_view k ON ad.id = k.definition_id -WHERE ad.id = $1 +WHERE ($1::uuid IS NULL OR ad.id = $1::uuid) + AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) GROUP BY ad.id, n.name, fqns.fqn, k.keys ` +type GetAttributeParams struct { + ID pgtype.UUID `json:"id"` + Fqn pgtype.Text `json:"fqn"` +} + type GetAttributeRow struct { ID string `json:"id"` AttributeName string `json:"attribute_name"` @@ -551,10 +557,11 @@ type GetAttributeRow struct { // LEFT JOIN key_access_servers kas ON kas.id = adkag.key_access_server_id // LEFT JOIN attribute_fqns fqns ON fqns.attribute_id = ad.id AND fqns.value_id IS NULL // LEFT JOIN active_definition_public_keys_view k ON ad.id = k.definition_id -// WHERE ad.id = $1 +// WHERE ($1::uuid IS NULL OR ad.id = $1::uuid) +// AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) // GROUP BY ad.id, n.name, fqns.fqn, k.keys -func (q *Queries) GetAttribute(ctx context.Context, id string) (GetAttributeRow, error) { - row := q.db.QueryRow(ctx, getAttribute, id) +func (q *Queries) GetAttribute(ctx context.Context, arg GetAttributeParams) (GetAttributeRow, error) { + row := q.db.QueryRow(ctx, getAttribute, arg.ID, arg.Fqn) var i GetAttributeRow err := row.Scan( &i.ID, @@ -594,10 +601,16 @@ LEFT JOIN attribute_fqns fqns ON av.id = fqns.value_id LEFT JOIN attribute_value_key_access_grants avkag ON av.id = avkag.attribute_value_id LEFT JOIN key_access_servers kas ON avkag.key_access_server_id = kas.id LEFT JOIN active_value_public_keys_view k ON av.id = k.value_id -WHERE av.id = $1 +WHERE ($1::uuid IS NULL OR av.id = $1::uuid) + AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) GROUP BY av.id, fqns.fqn, k.keys ` +type GetAttributeValueParams struct { + ID pgtype.UUID `json:"id"` + Fqn pgtype.Text `json:"fqn"` +} + type GetAttributeValueRow struct { ID string `json:"id"` Value string `json:"value"` @@ -632,10 +645,11 @@ type GetAttributeValueRow struct { // LEFT JOIN attribute_value_key_access_grants avkag ON av.id = avkag.attribute_value_id // LEFT JOIN key_access_servers kas ON avkag.key_access_server_id = kas.id // LEFT JOIN active_value_public_keys_view k ON av.id = k.value_id -// WHERE av.id = $1 +// WHERE ($1::uuid IS NULL OR av.id = $1::uuid) +// AND ($2::text IS NULL OR REGEXP_REPLACE(fqns.fqn, '^https?://', '') = REGEXP_REPLACE($2::text, '^https?://', '')) // GROUP BY av.id, fqns.fqn, k.keys -func (q *Queries) GetAttributeValue(ctx context.Context, id string) (GetAttributeValueRow, error) { - row := q.db.QueryRow(ctx, getAttributeValue, id) +func (q *Queries) GetAttributeValue(ctx context.Context, arg GetAttributeValueParams) (GetAttributeValueRow, error) { + row := q.db.QueryRow(ctx, getAttributeValue, arg.ID, arg.Fqn) var i GetAttributeValueRow err := row.Scan( &i.ID, @@ -652,15 +666,23 @@ func (q *Queries) GetAttributeValue(ctx context.Context, id string) (GetAttribut const getKeyAccessServer = `-- name: GetKeyAccessServer :one SELECT - id, - uri, - public_key, - name, + kas.id, + kas.uri, + kas.public_key, + kas.name, JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', metadata -> 'labels', 'created_at', created_at, 'updated_at', updated_at)) AS metadata -FROM key_access_servers -WHERE id = $1 +FROM key_access_servers AS kas +WHERE ($1::uuid IS NULL OR kas.id = $1::uuid) + AND ($2::text IS NULL OR kas.name = $2::text) + AND ($3::text IS NULL OR kas.uri = $3::text) ` +type GetKeyAccessServerParams struct { + ID pgtype.UUID `json:"id"` + Name pgtype.Text `json:"name"` + Uri pgtype.Text `json:"uri"` +} + type GetKeyAccessServerRow struct { ID string `json:"id"` Uri string `json:"uri"` @@ -672,15 +694,17 @@ type GetKeyAccessServerRow struct { // GetKeyAccessServer // // SELECT -// id, -// uri, -// public_key, -// name, +// kas.id, +// kas.uri, +// kas.public_key, +// kas.name, // JSON_STRIP_NULLS(JSON_BUILD_OBJECT('labels', metadata -> 'labels', 'created_at', created_at, 'updated_at', updated_at)) AS metadata -// FROM key_access_servers -// WHERE id = $1 -func (q *Queries) GetKeyAccessServer(ctx context.Context, id string) (GetKeyAccessServerRow, error) { - row := q.db.QueryRow(ctx, getKeyAccessServer, id) +// FROM key_access_servers AS kas +// WHERE ($1::uuid IS NULL OR kas.id = $1::uuid) +// AND ($2::text IS NULL OR kas.name = $2::text) +// AND ($3::text IS NULL OR kas.uri = $3::text) +func (q *Queries) GetKeyAccessServer(ctx context.Context, arg GetKeyAccessServerParams) (GetKeyAccessServerRow, error) { + row := q.db.QueryRow(ctx, getKeyAccessServer, arg.ID, arg.Name, arg.Uri) var i GetKeyAccessServerRow err := row.Scan( &i.ID, @@ -711,10 +735,17 @@ LEFT JOIN attribute_namespace_key_access_grants kas_ns_grants ON kas_ns_grants.n LEFT JOIN key_access_servers kas ON kas.id = kas_ns_grants.key_access_server_id LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = ns.id LEFT JOIN active_namespace_public_keys_view k ON ns.id = k.namespace_id -WHERE ns.id = $1 AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL +WHERE fqns.attribute_id IS NULL AND fqns.value_id IS NULL + AND ($1::uuid IS NULL OR ns.id = $1::uuid) + AND ($2::text IS NULL OR ns.name = REGEXP_REPLACE($2::text, '^https?://', '')) GROUP BY ns.id, fqns.fqn, k.keys ` +type GetNamespaceParams struct { + ID pgtype.UUID `json:"id"` + Name pgtype.Text `json:"name"` +} + type GetNamespaceRow struct { ID string `json:"id"` Name string `json:"name"` @@ -745,10 +776,12 @@ type GetNamespaceRow struct { // LEFT JOIN key_access_servers kas ON kas.id = kas_ns_grants.key_access_server_id // LEFT JOIN attribute_fqns fqns ON fqns.namespace_id = ns.id // LEFT JOIN active_namespace_public_keys_view k ON ns.id = k.namespace_id -// WHERE ns.id = $1 AND fqns.attribute_id IS NULL AND fqns.value_id IS NULL +// WHERE fqns.attribute_id IS NULL AND fqns.value_id IS NULL +// AND ($1::uuid IS NULL OR ns.id = $1::uuid) +// AND ($2::text IS NULL OR ns.name = REGEXP_REPLACE($2::text, '^https?://', '')) // GROUP BY ns.id, fqns.fqn, k.keys -func (q *Queries) GetNamespace(ctx context.Context, id string) (GetNamespaceRow, error) { - row := q.db.QueryRow(ctx, getNamespace, id) +func (q *Queries) GetNamespace(ctx context.Context, arg GetNamespaceParams) (GetNamespaceRow, error) { + row := q.db.QueryRow(ctx, getNamespace, arg.ID, arg.Name) var i GetNamespaceRow err := row.Scan( &i.ID, @@ -3371,9 +3404,12 @@ func (q *Queries) getPublicKey(ctx context.Context, id string) (getPublicKeyRow, const listPublicKeyMappings = `-- name: listPublicKeyMappings :many WITH counted AS ( - SELECT COUNT(pk.id) AS total FROM public_keys AS pk + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE (NULLIF($3, '') IS NULL OR pk.key_access_server_id = $3::uuid) - AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) + AND (NULLIF($4, '') IS NULL OR kas.name = $4) + AND (NULLIF($5, '') IS NULL OR kas.uri = $5) + AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) ), base_keys AS ( SELECT @@ -3389,7 +3425,9 @@ base_keys AS ( FROM public_keys pk JOIN key_access_servers kas ON pk.key_access_server_id = kas.id WHERE ( NULLIF($3, '') IS NULL OR kas.id = $3::uuid ) - AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) + AND (NULLIF($4, '') IS NULL OR kas.name = $4) + AND (NULLIF($5, '') IS NULL OR kas.uri = $5) + AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) ), namespace_mappings AS ( SELECT @@ -3480,6 +3518,8 @@ type listPublicKeyMappingsParams struct { Offset int32 `json:"offset_"` Limit int32 `json:"limit_"` KasID interface{} `json:"kas_id"` + KasName interface{} `json:"kas_name"` + KasUri interface{} `json:"kas_uri"` PublicKeyID interface{} `json:"public_key_id"` } @@ -3491,9 +3531,12 @@ type listPublicKeyMappingsRow struct { // listPublicKeyMappings // // WITH counted AS ( -// SELECT COUNT(pk.id) AS total FROM public_keys AS pk +// SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk +// JOIN key_access_servers kas ON pk.key_access_server_id = kas.id // WHERE (NULLIF($3, '') IS NULL OR pk.key_access_server_id = $3::uuid) -// AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) +// AND (NULLIF($4, '') IS NULL OR kas.name = $4) +// AND (NULLIF($5, '') IS NULL OR kas.uri = $5) +// AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) // ), // base_keys AS ( // SELECT @@ -3509,7 +3552,9 @@ type listPublicKeyMappingsRow struct { // FROM public_keys pk // JOIN key_access_servers kas ON pk.key_access_server_id = kas.id // WHERE ( NULLIF($3, '') IS NULL OR kas.id = $3::uuid ) -// AND ( NULLIF($4, '') IS NULL OR pk.id = $4::uuid ) +// AND (NULLIF($4, '') IS NULL OR kas.name = $4) +// AND (NULLIF($5, '') IS NULL OR kas.uri = $5) +// AND ( NULLIF($6, '') IS NULL OR pk.id = $6::uuid ) // ), // namespace_mappings AS ( // SELECT @@ -3599,6 +3644,8 @@ func (q *Queries) listPublicKeyMappings(ctx context.Context, arg listPublicKeyMa arg.Offset, arg.Limit, arg.KasID, + arg.KasName, + arg.KasUri, arg.PublicKeyID, ) if err != nil { @@ -3621,8 +3668,11 @@ func (q *Queries) listPublicKeyMappings(ctx context.Context, arg listPublicKeyMa const listPublicKeys = `-- name: listPublicKeys :many WITH counted AS ( - SELECT COUNT(k.id) AS total FROM public_keys AS k - WHERE (NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid) + SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk + JOIN key_access_servers kas ON pk.key_access_server_id = kas.id + WHERE (NULLIF($1, '') IS NULL OR kas.id = $1::uuid) + AND (NULLIF($2, '') IS NULL OR kas.name = $2) + AND (NULLIF($3, '') IS NULL OR kas.uri = $3) ) SELECT @@ -3643,14 +3693,18 @@ CROSS JOIN counted WHERE ( NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid ) -LIMIT $3 -OFFSET $2 +AND (NULLIF($2, '') IS NULL OR kas.name = $2) +AND (NULLIF($3, '') IS NULL OR kas.uri = $3) +LIMIT $5 +OFFSET $4 ` type listPublicKeysParams struct { - KasID interface{} `json:"kas_id"` - Offset int32 `json:"offset_"` - Limit int32 `json:"limit_"` + KasID interface{} `json:"kas_id"` + KasName interface{} `json:"kas_name"` + KasUri interface{} `json:"kas_uri"` + Offset int32 `json:"offset_"` + Limit int32 `json:"limit_"` } type listPublicKeysRow struct { @@ -3670,8 +3724,11 @@ type listPublicKeysRow struct { // listPublicKeys // // WITH counted AS ( -// SELECT COUNT(k.id) AS total FROM public_keys AS k -// WHERE (NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid) +// SELECT COUNT(DISTINCT kas.id) AS total FROM public_keys AS pk +// JOIN key_access_servers kas ON pk.key_access_server_id = kas.id +// WHERE (NULLIF($1, '') IS NULL OR kas.id = $1::uuid) +// AND (NULLIF($2, '') IS NULL OR kas.name = $2) +// AND (NULLIF($3, '') IS NULL OR kas.uri = $3) // ) // // SELECT @@ -3692,10 +3749,18 @@ type listPublicKeysRow struct { // WHERE ( // NULLIF($1, '') IS NULL OR k.key_access_server_id = $1::uuid // ) -// LIMIT $3 -// OFFSET $2 +// AND (NULLIF($2, '') IS NULL OR kas.name = $2) +// AND (NULLIF($3, '') IS NULL OR kas.uri = $3) +// LIMIT $5 +// OFFSET $4 func (q *Queries) listPublicKeys(ctx context.Context, arg listPublicKeysParams) ([]listPublicKeysRow, error) { - rows, err := q.db.Query(ctx, listPublicKeys, arg.KasID, arg.Offset, arg.Limit) + rows, err := q.db.Query(ctx, listPublicKeys, + arg.KasID, + arg.KasName, + arg.KasUri, + arg.Offset, + arg.Limit, + ) if err != nil { return nil, err } diff --git a/service/policy/kasregistry/key_access_server_registry.go b/service/policy/kasregistry/key_access_server_registry.go index cd8895c3e..c13596c9d 100644 --- a/service/policy/kasregistry/key_access_server_registry.go +++ b/service/policy/kasregistry/key_access_server_registry.go @@ -102,9 +102,17 @@ func (s KeyAccessServerRegistry) GetKeyAccessServer(ctx context.Context, ) (*connect.Response[kasr.GetKeyAccessServerResponse], error) { rsp := &kasr.GetKeyAccessServerResponse{} - keyAccessServer, err := s.dbClient.GetKeyAccessServer(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + keyAccessServer, err := s.dbClient.GetKeyAccessServer(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.String("id", req.Msg.GetId())) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.KeyAccessServer = keyAccessServer @@ -311,7 +319,11 @@ func (s KeyAccessServerRegistry) UpdatePublicKey(ctx context.Context, req *conne ObjectID: req.Msg.GetId(), } - original, err := s.dbClient.GetPublicKey(ctx, &kasr.GetPublicKeyRequest{Id: req.Msg.GetId()}) + original, err := s.dbClient.GetPublicKey(ctx, &kasr.GetPublicKeyRequest{ + Identifier: &kasr.GetPublicKeyRequest_Id{ + Id: req.Msg.GetId(), + }, + }) if err != nil { s.logger.Audit.PolicyCRUDFailure(ctx, auditParams) return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed) diff --git a/service/policy/kasregistry/key_access_server_registry.proto b/service/policy/kasregistry/key_access_server_registry.proto index 6235fd3b0..e1a1bef3e 100644 --- a/service/policy/kasregistry/key_access_server_registry.proto +++ b/service/policy/kasregistry/key_access_server_registry.proto @@ -9,8 +9,41 @@ import "policy/objects.proto"; import "policy/selectors.proto"; message GetKeyAccessServerRequest { - // Required - string id = 1 [ (buf.validate.field).string.uuid = true ]; + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.kas_id) || has(this.uri) || has(this.name)))", + message: "Either use deprecated 'id' field or one of 'kas_id' or 'uri', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.kas_id) || has(this.uri) || has(this.name)", + message: "Either id or one of kas_id or uri must be set" + }; + + // Deprecated + string id = 1 [ + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true + ];; + + oneof identifier { + // option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string kas_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string name = 3 [ + (buf.validate.field).string.min_len = 1 + ]; + string uri = 4 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } } message GetKeyAccessServerResponse { KeyAccessServer key_access_server = 1; } @@ -126,7 +159,9 @@ message CreatePublicKeyRequest { string kas_id = 1 [ (buf.validate.field).string.uuid = true ]; // Required - KasPublicKey key = 2; + KasPublicKey key = 2 [ + (buf.validate.field).required = true + ]; // Common metadata common.MetadataMutable metadata = 100; @@ -134,18 +169,34 @@ message CreatePublicKeyRequest { message CreatePublicKeyResponse { Key key = 1; } -message GetPublicKeyRequest { string id = 1; } +message GetPublicKeyRequest { + oneof identifier { + string id = 1 [ + (buf.validate.field).string.uuid = true + ]; + } +} message GetPublicKeyResponse { Key key = 1; } message ListPublicKeysRequest { - // Optional - string kas_id = 1; - // Future filter by fields - // // Optional - // string kas_name = 2; - // // Optional - // string kas_uri = 3; + oneof kas_filter { + // Optional + string kas_id = 1 [ + (buf.validate.field).string.uuid = true + ]; + // Optional + string kas_name = 2 [ + (buf.validate.field).string.min_len = 1 + ]; + // Optional + string kas_uri = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } // Optional policy.PageRequest pagination = 10; @@ -158,16 +209,29 @@ message ListPublicKeysResponse { } message ListPublicKeyMappingRequest { - // Optional - string kas_id = 1; - // Future filter by fields - // // Optional - // string kas_name = 2; - // // Optional - // string kas_uri = 3; + oneof kas_filter { + // Optional + string kas_id = 1 [ + (buf.validate.field).string.uuid = true + ]; + // Optional + string kas_name = 2 [ + (buf.validate.field).string.min_len = 1 + ]; + // Optional + string kas_uri = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } // Optional Public Key ID - string public_key_id = 4; + string public_key_id = 4 [ + (buf.validate.field).string.uuid = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + ]; // Optional policy.PageRequest pagination = 10; @@ -199,7 +263,9 @@ message ListPublicKeyMappingResponse { message UpdatePublicKeyRequest { // Required - string id = 1; + string id = 1 [ + (buf.validate.field).string.uuid = true + ]; // Optional // Common metadata @@ -211,8 +277,7 @@ message UpdatePublicKeyResponse { Key key = 1;} message DeactivatePublicKeyRequest { string id = 1 [ - (buf.validate.field).string.uuid = true, - (buf.validate.field).required = true + (buf.validate.field).string.uuid = true ]; } @@ -220,14 +285,13 @@ message DeactivatePublicKeyResponse { Key key = 1; } message ActivatePublicKeyRequest { string id = 1 [ - (buf.validate.field).string.uuid = true, - (buf.validate.field).required = true + (buf.validate.field).string.uuid = true ]; } message ActivatePublicKeyResponse { Key key = 1; } -//Deprecated +// Deprecated in favor of ListPublicKeyMapping // TODO: optional validation below should be through a custom validator, which // is too bleeding edge at present without full plugin support diff --git a/service/policy/kasregistry/key_access_server_registry_test.go b/service/policy/kasregistry/key_access_server_registry_test.go index e8af44695..0a4f7b4ef 100644 --- a/service/policy/kasregistry/key_access_server_registry_test.go +++ b/service/policy/kasregistry/key_access_server_registry_test.go @@ -19,10 +19,15 @@ func getValidator() *protovalidate.Validator { } const ( - validSecureURI = "https://example.net" - validInsecureURI = "http://local.something.com" - validUUID = "00000000-0000-0000-0000-000000000000" - errMessageUUID = "string.uuid" + validSecureURI = "https://example.net" + validInsecureURI = "http://local.something.com" + validUUID = "00000000-0000-0000-0000-000000000000" + errMessageUUID = "string.uuid" + errRequiredField = "required_fields" + errExclusiveFields = "exclusive_fields" + errMessageURI = "string.uri" + errMessageMinLen = "string.min_len" + errMessageRequired = "required" ) var ( @@ -38,6 +43,8 @@ var ( Keys: []*policy.KasPublicKey{ { Pem: "fake PEM", + Kid: "fake KID", + Alg: policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP256R1, }, }, }, @@ -47,17 +54,153 @@ var ( fakeID = "6321ea85-ca04-466f-aefb-174bcdbc0612" ) -func Test_GetKeyAccessServerRequest_Succeeds(t *testing.T) { - req := &kasregistry.GetKeyAccessServerRequest{} - v := getValidator() +func Test_GetKeyAccessServerRequest(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.GetKeyAccessServerRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid KasId in Identifier (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, // Assuming errMessageUUID is defined elsewhere + }, + { + name: "Invalid KasId in Identifier (invalid UUID)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KasId in Identifier", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, // Assuming errMessageUUID is defined elsewhere + }, + { + name: "Invalid Deprecated Id (invalid UUID)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid Deprecated Id", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid Kas Identifier URI", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Uri{ + Uri: "invalid-uri", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid Kas Identifier URI (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Uri{ + Uri: "", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid Kas Identifier URI", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Uri{ + Uri: validSecureURI, + }, + }, + expectError: false, + }, + { + name: "Invalid Kas Identifier Name (empty string)", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Name{ + Name: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Valid Kas Identifier Name", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Name{ + Name: "kas-name", + }, + }, + expectError: false, + }, + { + name: "Invalid can't have both Deprecated Id and Identifier", + req: &kasregistry.GetKeyAccessServerRequest{ + Identifier: &kasregistry.GetKeyAccessServerRequest_Name{ + Name: "kas-name", + }, + Id: validUUID, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &kasregistry.GetKeyAccessServerRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - err := v.Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) + v := getValidator() // Get the validator instance (assuming this is defined elsewhere) - req.Id = validUUID - err = v.Validate(req) - require.NoError(t, err) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := v.Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } } func Test_DeleteKeyAccessServerRequest_Succeeds(t *testing.T) { @@ -587,3 +730,516 @@ func Test_Verify_Public_Keys(t *testing.T) { require.Equal(t, key.expectedErr, err, key.description) } } + +func Test_ListPublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.ListPublicKeysRequest + expectError bool + errorMessage string + }{ + { + name: "Valid ListPublicKeyRequest", + req: &kasregistry.ListPublicKeysRequest{}, + expectError: false, + }, + { + name: "Invalid KasId filter (empty string)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId filter (invalid UUID)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KasId filter", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid KasUri filter (empty string)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: "", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid KasUri filter (invalid URI)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: "invalid-uri", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid KasUri filter", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasUri{ + KasUri: fakeURI, + }, + }, + expectError: false, + }, + { + name: "Invalid KasName filter (empty string)", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasName{ + KasName: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Valid KasName filter", + req: &kasregistry.ListPublicKeysRequest{ + KasFilter: &kasregistry.ListPublicKeysRequest_KasName{ + KasName: "kas-name", + }, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_ListPublicKeyMappings_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.ListPublicKeyMappingRequest + expectError bool + errorMessage string + }{ + { + name: "Valid ListPublicKeyMappingsRequest", + req: &kasregistry.ListPublicKeyMappingRequest{}, + expectError: false, + }, + { + name: "Invalid KasId filter (empty string)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId filter (invalid UUID)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KasId filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasId{ + KasId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Invalid KasUri filter (empty string)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: "", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid KasUri filter (invalid URI)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: "invalid-uri", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid KasUri filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasUri{ + KasUri: fakeURI, + }, + }, + expectError: false, + }, + { + name: "Invalid KasName filter (empty string)", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasName{ + KasName: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Valid KasName filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + KasFilter: &kasregistry.ListPublicKeyMappingRequest_KasName{ + KasName: "kas-name", + }, + }, + expectError: false, + }, + { + name: "Invalid KeyId filter (invalid UUID)", + req: &kasregistry.ListPublicKeyMappingRequest{ + PublicKeyId: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId filter", + req: &kasregistry.ListPublicKeyMappingRequest{ + PublicKeyId: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_GetPublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.GetPublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Valid GetPublicKeyRequest", + req: &kasregistry.GetPublicKeyRequest{}, + expectError: false, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.GetPublicKeyRequest{ + Identifier: &kasregistry.GetPublicKeyRequest_Id{ + Id: validUUID, + }, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_CreatePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.CreatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid CreatePublicKeyRequest (empty)", + req: &kasregistry.CreatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId (empty string)", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: "", + Key: &policy.KasPublicKey{}, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KasId (invalid UUID)", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: "invalid-uuid", + Key: &policy.KasPublicKey{}, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid PublicKey (empty)", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: validUUID, + Key: nil, + }, + expectError: true, + errorMessage: errMessageRequired, + }, + { + name: "Valid PublicKey", + req: &kasregistry.CreatePublicKeyRequest{ + KasId: validUUID, + Key: &policy.KasPublicKey{ + Pem: "-----BEGIN PUBLIC KEY-----\nMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAGvC9aOQpUifTgBQ+aSFm1fn2m5Fb\nOv5Xc+qrT1LcHlX2vYPVfKVsqkjb0dg6LrrKWB6+UuS44y0GDAMln1KPfnkBb2+b\n6gLkYlAUpLV7RtyzBSktmLOkViGauYlR+9gKT2B5+hiL8lsLeh7khj6XEL+CVVgS\nswYGVPb345XuIdrvhBs=\n-----END PUBLIC KEY-----\n", + Kid: "ec384", + Alg: policy.KasPublicKeyAlgEnum_KAS_PUBLIC_KEY_ALG_ENUM_EC_SECP384R1, + }, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_UpdatePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.UpdatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid UpdatePublicKeyRequest (empty)", + req: &kasregistry.UpdatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.UpdatePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.UpdatePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.UpdatePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_DeactivePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.DeactivatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid DeactivatePublicKeyRequest (empty)", + req: &kasregistry.DeactivatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.DeactivatePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.DeactivatePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.DeactivatePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} + +func Test_ActivatePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *kasregistry.ActivatePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid ActivatePublicKeyRequest (empty)", + req: &kasregistry.ActivatePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &kasregistry.ActivatePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &kasregistry.ActivatePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &kasregistry.ActivatePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} diff --git a/service/policy/namespaces/namespaces.go b/service/policy/namespaces/namespaces.go index ae33d8359..4fe43caca 100644 --- a/service/policy/namespaces/namespaces.go +++ b/service/policy/namespaces/namespaces.go @@ -75,13 +75,21 @@ func (ns NamespacesService) ListNamespaces(ctx context.Context, req *connect.Req } func (ns NamespacesService) GetNamespace(ctx context.Context, req *connect.Request[namespaces.GetNamespaceRequest]) (*connect.Response[namespaces.GetNamespaceResponse], error) { - ns.logger.Debug("getting namespace", slog.String("id", req.Msg.GetId())) - rsp := &namespaces.GetNamespaceResponse{} - namespace, err := ns.dbClient.GetNamespace(ctx, req.Msg.GetId()) + var identifier any + + if req.Msg.GetId() != "" { //nolint:staticcheck // Id can still be used until removed + identifier = req.Msg.GetId() //nolint:staticcheck // Id can still be used until removed + } else { + identifier = req.Msg.GetIdentifier() + } + + ns.logger.Debug("getting namespace", slog.Any("id", identifier)) + + namespace, err := ns.dbClient.GetNamespace(ctx, identifier) if err != nil { - return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, "id", req.Msg.GetId()) + return nil, db.StatusifyError(err, db.ErrTextGetRetrievalFailed, slog.Any("id", identifier)) } rsp.Namespace = namespace diff --git a/service/policy/namespaces/namespaces.proto b/service/policy/namespaces/namespaces.proto index de97117f1..1a63f5628 100644 --- a/service/policy/namespaces/namespaces.proto +++ b/service/policy/namespaces/namespaces.proto @@ -48,11 +48,40 @@ message NamespaceKey { */ message GetNamespaceRequest { - // Required + // Temporary message level validation until we remove the deprecated id field + option (buf.validate.message).cel = { + id: "exclusive_fields", + expression: "!(has(this.id) && (has(this.namespace_id) || has(this.fqn)))", + message: "Either use deprecated 'id' field or one of 'namespace_id' or 'fqn', but not both" + }; + + option (buf.validate.message).cel = { + id: "required_fields", + expression: "has(this.id) || has(this.namespace_id) || has(this.fqn)", + message: "Either id or one of namespace_id or fqn must be set" + }; + + // Deprecated string id = 1 [ - (buf.validate.field).string.uuid = true + deprecated = true, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE, + (buf.validate.field).string.uuid= true ]; + + oneof identifier { + //option (buf.validate.oneof).required = true; // TODO: enable this when we remove the deprecated field + string namespace_id = 2 [ + (buf.validate.field).string.uuid = true + ]; + string fqn = 3 [ + (buf.validate.field).string = { + min_len : 1 + uri : true + } + ]; + } } + message GetNamespaceResponse { policy.Namespace namespace = 1; } diff --git a/service/policy/namespaces/namespaces_test.go b/service/policy/namespaces/namespaces_test.go index 58c73c40e..adce58a5e 100644 --- a/service/policy/namespaces/namespaces_test.go +++ b/service/policy/namespaces/namespaces_test.go @@ -10,9 +10,13 @@ import ( ) const ( - validName = "namespace.org" - validUUID = "390e0058-7ae8-48f6-821c-9db07c831276" - errMessageUUID = "string.uuid" + validName = "namespace.org" + validUUID = "390e0058-7ae8-48f6-821c-9db07c831276" + errMessageUUID = "string.uuid" + errMessageMinLen = "string.min_len" + errMessageURI = "string.uri" + errRequiredField = "required_fields" + errExclusiveFields = "exclusive_fields" ) func getValidator() *protovalidate.Validator { @@ -114,17 +118,136 @@ func TestCreateNamespace_NameMissing_Fails(t *testing.T) { require.Contains(t, err.Error(), "[required]") } -func Test_GetNamespaceRequest_Succeeds(t *testing.T) { - req := &namespaces.GetNamespaceRequest{} - v := getValidator() - - err := v.Validate(req) - require.Error(t, err) - require.Contains(t, err.Error(), errMessageUUID) +func Test_GetNamespaceRequest(t *testing.T) { + testCases := []struct { + name string + req *namespaces.GetNamespaceRequest + expectError bool + errorMessage string // Optional: expected error message substring + }{ + { + name: "Invalid NamespaceId in Identifier (empty string)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_NamespaceId{ + NamespaceId: "", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid NamespaceId in Identifier (invalid UUID)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_NamespaceId{ + NamespaceId: "invalid-uuid", + }, + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid NamespaceId in Identifier", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_NamespaceId{ + NamespaceId: validUUID, + }, + }, + expectError: false, + }, + { + name: "Valid Deprecated Id", + req: &namespaces.GetNamespaceRequest{ + Id: validUUID, + }, + expectError: false, + }, + { + name: "Invalid Deprecated Id (empty string)", + req: &namespaces.GetNamespaceRequest{ + Id: "", + }, + expectError: true, + errorMessage: errRequiredField, + }, + { + name: "Invalid Deprecated Id (invalid UUID)", + req: &namespaces.GetNamespaceRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid Namespace Identifier URI", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "invalid-fqn", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Invalid Namespace Identifier URI (empty string)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "", + }, + }, + expectError: true, + errorMessage: errMessageMinLen, + }, + { + name: "Invalid Namespace Identifier URI (missing scheme)", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "namespace.org", + }, + }, + expectError: true, + errorMessage: errMessageURI, + }, + { + name: "Valid Namespace Identifier URI", + req: &namespaces.GetNamespaceRequest{ + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "https://namespace.org", + }, + }, + expectError: false, + }, + { + name: "Invalid can't have both Id and Identifier", + req: &namespaces.GetNamespaceRequest{ + Id: validUUID, + Identifier: &namespaces.GetNamespaceRequest_Fqn{ + Fqn: "https://namespace.org", + }, + }, + expectError: true, + errorMessage: errExclusiveFields, + }, + { + name: "Invalid no Id or Identifier", + req: &namespaces.GetNamespaceRequest{}, + expectError: true, + errorMessage: errRequiredField, + }, + } - req.Id = validUUID - err = v.Validate(req) - require.NoError(t, err) + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } } func Test_UpdateNamespaceRequest_Succeeds(t *testing.T) { diff --git a/service/policy/objects.proto b/service/policy/objects.proto index f9e209f67..593e4c228 100644 --- a/service/policy/objects.proto +++ b/service/policy/objects.proto @@ -328,15 +328,31 @@ enum KasPublicKeyAlgEnum { // A KAS public key and some associated metadata for further identifcation message KasPublicKey { // x509 ASN.1 content in PEM envelope, usually - string pem = 1; + string pem = 1 [ + (buf.validate.field).string = { + min_len: 1, + max_len: 8192 + } + ]; // A unique string identifier for this key - string kid = 2; + string kid = 2 [ + (buf.validate.field).string = { + min_len : 1, + max_len : 32 + } + ]; // A known algorithm type with any additional parameters encoded. // To start, these may be `rsa:2048` for encrypting ZTDF files and // `ec:secp256r1` for nanoTDF, but more formats may be added as needed. - KasPublicKeyAlgEnum alg = 3; + KasPublicKeyAlgEnum alg = 3 [ + (buf.validate.field).enum = { + defined_only: true, + not_in: [0] + } + + ]; } // Deprecated diff --git a/service/policy/unsafe/unsafe_test.go b/service/policy/unsafe/unsafe_test.go new file mode 100644 index 000000000..8e7d59bcb --- /dev/null +++ b/service/policy/unsafe/unsafe_test.go @@ -0,0 +1,75 @@ +package unsafe + +import ( + "testing" + + "github.com/bufbuild/protovalidate-go" + "github.com/opentdf/platform/protocol/go/policy/unsafe" + "github.com/stretchr/testify/require" +) + +var ( + errMessageUUID = "string.uuid" + validUUID = "00000000-0000-0000-0000-000000000000" +) + +func getValidator() *protovalidate.Validator { + v, err := protovalidate.New() + if err != nil { + panic(err) + } + return v +} + +func Test_UnsafeDeletePublicKey_Validation(t *testing.T) { + testCases := []struct { + name string + req *unsafe.UnsafeDeletePublicKeyRequest + expectError bool + errorMessage string + }{ + { + name: "Invalid UnsafeDeletePublicKey (empty)", + req: &unsafe.UnsafeDeletePublicKeyRequest{}, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (empty string)", + req: &unsafe.UnsafeDeletePublicKeyRequest{ + Id: "", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Invalid KeyId (invalid UUID)", + req: &unsafe.UnsafeDeletePublicKeyRequest{ + Id: "invalid-uuid", + }, + expectError: true, + errorMessage: errMessageUUID, + }, + { + name: "Valid KeyId", + req: &unsafe.UnsafeDeletePublicKeyRequest{ + Id: validUUID, + }, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := getValidator().Validate(tc.req) + if tc.expectError { + require.Error(t, err, "Expected error for test case: %s", tc.name) + if tc.errorMessage != "" { + require.Contains(t, err.Error(), tc.errorMessage, "Expected error message to contain '%s' for test case: %s", tc.errorMessage, tc.name) + } + } else { + require.NoError(t, err, "Expected no error for test case: %s", tc.name) + } + }) + } +} diff --git a/test/policy-service.bats b/test/policy-service.bats index 47908d0c1..1b31ad5d1 100755 --- a/test/policy-service.bats +++ b/test/policy-service.bats @@ -60,9 +60,9 @@ } @test "gRPC: kas grants assignment" { - go run ./examples --creds opentdf:secret kas add --kas https://a.example.io --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" - go run ./examples --creds opentdf:secret kas add --kas https://b.example.io --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" - go run ./examples --creds opentdf:secret kas add --kas https://c.example.io --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas https://a.example.io --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas https://b.example.io --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas https://c.example.io --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" run go run ./examples --creds opentdf:secret kas ls -l echo "$output" diff --git a/test/tdf-roundtrips.bats b/test/tdf-roundtrips.bats index 72604164a..d79007ebd 100755 --- a/test/tdf-roundtrips.bats +++ b/test/tdf-roundtrips.bats @@ -6,7 +6,7 @@ @test "examples: roundtrip Z-TDF" { # TODO: add subject mapping here to remove reliance on `provision fixtures` echo "[INFO] configure attribute with grant for local kas" - go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 -v value1 go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 go run ./examples --creds opentdf:secret attributes assign -a https://example.com/attr/attr1 -v value1 -k http://localhost:8080 @@ -30,7 +30,7 @@ @test "examples: roundtrip Z-TDF with extra unnecessary, invalid kas" { # TODO: add subject mapping here to remove reliance on `provision fixtures` echo "[INFO] configure attribute with grant for local kas" - go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" + go run ./examples --creds opentdf:secret kas add --kas http://localhost:8080 --algorithm "rsa:2048" --kid r1 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" go run ./examples --creds opentdf:secret kas add --kas http://localhost:9090 --algorithm "rsa:2048" --kid r2 --public-key "$(<${BATS_TEST_DIRNAME}/../kas-cert.pem)" go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 -v value1 go run ./examples --creds opentdf:secret attributes unassign -a https://example.com/attr/attr1 From a9b10629805e47dfd16453ae02eaa7c8be35fb31 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2025 02:12:29 +0000 Subject: [PATCH 02/34] chore(main): release protocol/go 0.2.26 (#1916) :robot: I have created a release *beep* *boop* --- ## [0.2.26](https://github.com/opentdf/platform/compare/protocol/go/v0.2.25...protocol/go/v0.2.26) (2025-02-14) ### Features * add ability to retrieve policy resources by id or name ([#1901](https://github.com/opentdf/platform/issues/1901)) ([deb4455](https://github.com/opentdf/platform/commit/deb4455773cd71d3436510bbeb599f309106ce1d)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- protocol/go/CHANGELOG.md | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index af353cb6c..27439d625 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -2,7 +2,7 @@ "lib/fixtures": "0.2.10", "lib/ocrypto": "0.1.7", "lib/flattening": "0.1.3", - "protocol/go": "0.2.25", + "protocol/go": "0.2.26", "sdk": "0.3.26", "service": "0.4.38" } diff --git a/protocol/go/CHANGELOG.md b/protocol/go/CHANGELOG.md index 43469e82d..fd49adf11 100644 --- a/protocol/go/CHANGELOG.md +++ b/protocol/go/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.2.26](https://github.com/opentdf/platform/compare/protocol/go/v0.2.25...protocol/go/v0.2.26) (2025-02-14) + + +### Features + +* add ability to retrieve policy resources by id or name ([#1901](https://github.com/opentdf/platform/issues/1901)) ([deb4455](https://github.com/opentdf/platform/commit/deb4455773cd71d3436510bbeb599f309106ce1d)) + ## [0.2.25](https://github.com/opentdf/platform/compare/protocol/go/v0.2.24...protocol/go/v0.2.25) (2025-01-31) From de68d952ff8a2dbf1811198577ec8f1c4edfc502 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2025 06:51:45 -0500 Subject: [PATCH 03/34] fix(core): Autobump examples (#1918) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- examples/go.mod | 2 +- examples/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index 40049e454..1a4260a0c 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.25 + github.com/opentdf/platform/protocol/go v0.2.26 github.com/opentdf/platform/sdk v0.3.23 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 diff --git a/examples/go.sum b/examples/go.sum index a0e575291..438ed4cf2 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -109,8 +109,8 @@ github.com/opentdf/platform/lib/fixtures v0.2.8 h1:lGYrMnbORtU62lxsJi8qPsxjFuNIk github.com/opentdf/platform/lib/fixtures v0.2.8/go.mod h1:8yCSe+oUzW9jbM573r9qgE68rjwDMNzktObiGVsO/W8= github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.25 h1:MzjZzzforN0RDmQh4uMXBloDp8JM0PE3K1PQ/XfyFLs= -github.com/opentdf/platform/protocol/go v0.2.25/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/protocol/go v0.2.26 h1:22ugJFhAjlz7BRAky3eBljIQrsLzmsdkKVM+pjuG09k= +github.com/opentdf/platform/protocol/go v0.2.26/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentdf/platform/sdk v0.3.23 h1:lTjWiqCGcA1fvMNOMUPIiOl8FNNQTaEK/+xyGvpbMZs= github.com/opentdf/platform/sdk v0.3.23/go.mod h1:KpT/m5zXQ19WqhGePKfIC39Ly8LOipKdKGbJ1B/59a8= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= From edeeb74e9c38b2e6eef7fefa29768912371ec949 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2025 06:51:59 -0500 Subject: [PATCH 04/34] fix(core): Autobump sdk (#1917) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- sdk/go.mod | 2 +- sdk/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/go.mod b/sdk/go.mod index c8a11f0d7..d3115010c 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -9,7 +9,7 @@ require ( github.com/lestrrat-go/jwx/v2 v2.0.21 github.com/opentdf/platform/lib/fixtures v0.2.10 github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.25 + github.com/opentdf/platform/protocol/go v0.2.26 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.32.0 github.com/xeipuuv/gojsonschema v1.2.0 diff --git a/sdk/go.sum b/sdk/go.sum index dbd686c04..daff7dde6 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -116,8 +116,8 @@ github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXv github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.25 h1:MzjZzzforN0RDmQh4uMXBloDp8JM0PE3K1PQ/XfyFLs= -github.com/opentdf/platform/protocol/go v0.2.25/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/protocol/go v0.2.26 h1:22ugJFhAjlz7BRAky3eBljIQrsLzmsdkKVM+pjuG09k= +github.com/opentdf/platform/protocol/go v0.2.26/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= From f90229560e8f09b64b4bf650b271c5fbb428bc7f Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Fri, 14 Feb 2025 06:52:12 -0500 Subject: [PATCH 05/34] fix(core): Autobump service (#1919) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- service/go.mod | 2 +- service/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/service/go.mod b/service/go.mod index 9f2b3ea49..c8a1c6a2a 100644 --- a/service/go.mod +++ b/service/go.mod @@ -25,7 +25,7 @@ require ( github.com/opentdf/platform/lib/fixtures v0.2.10 github.com/opentdf/platform/lib/flattening v0.1.3 github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.25 + github.com/opentdf/platform/protocol/go v0.2.26 github.com/opentdf/platform/sdk v0.3.26 github.com/pressly/goose/v3 v3.19.1 github.com/spf13/cobra v1.8.1 diff --git a/service/go.sum b/service/go.sum index 2dba37554..6bf197419 100644 --- a/service/go.sum +++ b/service/go.sum @@ -279,8 +279,8 @@ github.com/opentdf/platform/lib/flattening v0.1.3 h1:IuOm/wJVXNrzOV676Ticgr0wyBk github.com/opentdf/platform/lib/flattening v0.1.3/go.mod h1:Gs/T+6FGZKk9OAdz2Jf1R8CTGeNRYrq1lZGDeYT3hrY= github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.25 h1:MzjZzzforN0RDmQh4uMXBloDp8JM0PE3K1PQ/XfyFLs= -github.com/opentdf/platform/protocol/go v0.2.25/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/protocol/go v0.2.26 h1:22ugJFhAjlz7BRAky3eBljIQrsLzmsdkKVM+pjuG09k= +github.com/opentdf/platform/protocol/go v0.2.26/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentdf/platform/sdk v0.3.26 h1:cXNQsLd7Ef2Nq6HJ/L+4tvdJ+Op42vplkA6C53rcPW8= github.com/opentdf/platform/sdk v0.3.26/go.mod h1:rw/4l0qfhkhD9bdwqhXARV2CSpV+18m7Ks1wPRGLzkI= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= From 652266f212ba10b2492a84741f68391a1d39e007 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 14 Feb 2025 10:17:14 -0500 Subject: [PATCH 06/34] feat(core): EXPERIMENTAL: EC-wrapped key support (#1902) ### Proposed Changes - Lets KAS use an elliptic key based mechanism for key (split) encapsulation - Adds a new `ec-wrapped` KAO type that uses a hybrid EC encryption scheme to wrap the values - Adds a feature flag (`services.kas.ec_tdf_enabled`) on the server. - Exposes feature flag to service launcher workflows as `ec-tdf-enabled` - To use with SDK, adds a new `WithWrappingKeyAlg` functional option ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions - `main` - \#1902 :point\_left: - \#1907 --------- Co-authored-by: sujan kota --- docs/grpc/index.html | 7 + examples/cmd/decrypt.go | 13 +- examples/cmd/encrypt.go | 23 +- lib/ocrypto/asym_decryption.go | 134 ++++++++- lib/ocrypto/asym_encrypt_decrypt_test.go | 40 ++- lib/ocrypto/asym_encryption.go | 190 ++++++++++-- lib/ocrypto/ec_key_pair.go | 129 ++++++++ lib/ocrypto/rsa_key_pair.go | 5 + protocol/go/kas/kas.pb.go | 294 ++++++++++--------- sdk/kas_client.go | 68 ++++- sdk/manifest.go | 19 +- sdk/schema/manifest-lax.schema.json | 4 + sdk/schema/manifest.schema.json | 8 +- sdk/tdf.go | 179 ++++++++--- sdk/tdf_config.go | 77 +++-- service/internal/security/crypto_provider.go | 1 + service/internal/security/standard_crypto.go | 31 ++ service/kas/access/provider.go | 5 + service/kas/access/rewrap.go | 169 ++++++++--- service/kas/kas.proto | 3 + test/start-additional-kas/action.yaml | 6 + test/start-up-with-containers/action.yaml | 9 + test/tdf-roundtrips.bats | 29 ++ 23 files changed, 1146 insertions(+), 297 deletions(-) diff --git a/docs/grpc/index.html b/docs/grpc/index.html index 3eb649815..5a9fee706 100644 --- a/docs/grpc/index.html +++ b/docs/grpc/index.html @@ -3557,6 +3557,13 @@

KeyAccess

header is only used for NanoTDFs

+ + ephemeral_public_key + bytes + +

For wrapping with an ECDH derived key, when type=ec-wrapped

+ + diff --git a/examples/cmd/decrypt.go b/examples/cmd/decrypt.go index 430465e1d..f8040cc5a 100644 --- a/examples/cmd/decrypt.go +++ b/examples/cmd/decrypt.go @@ -8,6 +8,8 @@ import ( "os" "path/filepath" + "github.com/opentdf/platform/sdk" + "github.com/spf13/cobra" ) @@ -18,6 +20,7 @@ func init() { RunE: decrypt, Args: cobra.MinimumNArgs(1), } + decryptCmd.Flags().StringVarP(&alg, "rewrap-encapsulation-algorithm", "A", "rsa:2048", "Key wrap response algorithm algorithm:parameters") ExamplesCmd.AddCommand(decryptCmd) } @@ -81,7 +84,15 @@ func decrypt(cmd *cobra.Command, args []string) error { } if !isNano { - tdfreader, err := client.LoadTDF(file) + opts := []sdk.TDFReaderOption{} + if alg != "" { + kt, err := keyTypeForKeyType(alg) + if err != nil { + return err + } + opts = append(opts, sdk.WithSessionKeyType(kt)) + } + tdfreader, err := client.LoadTDF(file, opts...) if err != nil { return err } diff --git a/examples/cmd/encrypt.go b/examples/cmd/encrypt.go index fdf242792..7287facd5 100644 --- a/examples/cmd/encrypt.go +++ b/examples/cmd/encrypt.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/opentdf/platform/lib/ocrypto" - "github.com/opentdf/platform/sdk" "github.com/spf13/cobra" ) @@ -23,6 +22,7 @@ var ( outputName string dataAttributes []string collection int + alg string ) func init() { @@ -38,6 +38,7 @@ func init() { encryptCmd.Flags().BoolVar(&noKIDInKAO, "no-kid-in-kao", false, "[deprecated] Disable storing key identifiers in TDF KAOs") encryptCmd.Flags().BoolVar(&noKIDInNano, "no-kid-in-nano", true, "Disable storing key identifiers in nanoTDF KAS ResourceLocator") encryptCmd.Flags().StringVarP(&outputName, "output", "o", "sensitive.txt.tdf", "name or path of output file; - for stdout") + encryptCmd.Flags().StringVarP(&alg, "key-encapsulation-algorithm", "A", "rsa:2048", "Key wrap algorithm algorithm:parameters") encryptCmd.Flags().IntVarP(&collection, "collection", "c", 0, "number of nano's to create for collection. If collection >0 (default) then output will be _") ExamplesCmd.AddCommand(&encryptCmd) @@ -102,6 +103,7 @@ func encrypt(cmd *cobra.Command, args []string) error { opts := []sdk.TDFOption{sdk.WithDataAttributes(dataAttributes...)} if !autoconfigure { opts = append(opts, sdk.WithAutoconfigure(autoconfigure)) + opts = append(opts, sdk.WithWrappingKeyAlg(ocrypto.EC256Key)) opts = append(opts, sdk.WithKasInformation( sdk.KASInfo{ // examples assume insecure http @@ -109,6 +111,13 @@ func encrypt(cmd *cobra.Command, args []string) error { PublicKey: "", })) } + if alg != "" { + kt, err := keyTypeForKeyType(alg) + if err != nil { + return err + } + opts = append(opts, sdk.WithWrappingKeyAlg(kt)) + } tdf, err := client.CreateTDF(out, in, opts...) if err != nil { return err @@ -156,6 +165,18 @@ func encrypt(cmd *cobra.Command, args []string) error { return nil } +func keyTypeForKeyType(alg string) (ocrypto.KeyType, error) { + switch alg { + case string(ocrypto.RSA2048Key): + return ocrypto.RSA2048Key, nil + case string(ocrypto.EC256Key): + return ocrypto.EC256Key, nil + default: + // do not submit add ocrypto.UnknownKey + return ocrypto.RSA2048Key, fmt.Errorf("unsupported key type [%s]", alg) + } +} + func cat(cmd *cobra.Command, nTdfFile string) error { f, err := os.Open(nTdfFile) if err != nil { diff --git a/lib/ocrypto/asym_decryption.go b/lib/ocrypto/asym_decryption.go index 1cf2eba9d..4744eb91a 100644 --- a/lib/ocrypto/asym_decryption.go +++ b/lib/ocrypto/asym_decryption.go @@ -2,20 +2,34 @@ package ocrypto import ( "crypto" + "crypto/aes" + "crypto/cipher" + "crypto/ecdh" + "crypto/ecdsa" + "crypto/elliptic" "crypto/rsa" + "crypto/sha256" "crypto/x509" "encoding/pem" "errors" "fmt" + "io" "strings" + + "golang.org/x/crypto/hkdf" ) type AsymDecryption struct { PrivateKey *rsa.PrivateKey } -// NewAsymDecryption creates and returns a new AsymDecryption. -func NewAsymDecryption(privateKeyInPem string) (AsymDecryption, error) { +type PrivateKeyDecryptor interface { + // Decrypt decrypts ciphertext with private key. + Decrypt(data []byte) ([]byte, error) +} + +// FromPrivatePEM creates and returns a new AsymDecryption. +func FromPrivatePEM(privateKeyInPem string) (PrivateKeyDecryptor, error) { block, _ := pem.Decode([]byte(privateKeyInPem)) if block == nil { return AsymDecryption{}, errors.New("failed to parse PEM formatted private key") @@ -40,13 +54,34 @@ func NewAsymDecryption(privateKeyInPem string) (AsymDecryption, error) { } switch privateKey := priv.(type) { + case *ecdsa.PrivateKey: + if sk, err := privateKey.ECDH(); err != nil { + return nil, fmt.Errorf("unable to create ECDH key: %w", err) + } else { + return NewECDecryptor(sk) + } + case *ecdh.PrivateKey: + return NewECDecryptor(privateKey) case *rsa.PrivateKey: return AsymDecryption{privateKey}, nil default: break } - return AsymDecryption{}, errors.New("not an rsa PEM formatted private key") + return nil, errors.New("not a supported PEM formatted private key") +} + +func NewAsymDecryption(privateKeyInPem string) (AsymDecryption, error) { + d, err := FromPrivatePEM(privateKeyInPem) + if err != nil { + return AsymDecryption{}, err + } + switch d := d.(type) { + case AsymDecryption: + return d, nil + default: + return AsymDecryption{}, errors.New("not an RSA private key") + } } // Decrypt decrypts ciphertext with private key. @@ -64,3 +99,96 @@ func (asymDecryption AsymDecryption) Decrypt(data []byte) ([]byte, error) { return bytes, nil } + +type ECDecryptor struct { + sk *ecdh.PrivateKey + salt []byte + info []byte +} + +func NewECDecryptor(sk *ecdh.PrivateKey) (ECDecryptor, error) { + // TK Make these reasonable? IIRC salt should be longer, info maybe a parameters? + salt := []byte("salt") + return ECDecryptor{sk, salt, nil}, nil +} + +func (e ECDecryptor) Decrypt(_ []byte) ([]byte, error) { + // TK How to get the ephmeral key into here? + return nil, errors.New("ecdh standard decrypt unimplemented") +} + +func (e ECDecryptor) DecryptWithEphemeralKey(data, ephemeral []byte) ([]byte, error) { + var ek *ecdh.PublicKey + + if pubFromDSN, err := x509.ParsePKIXPublicKey(ephemeral); err == nil { + switch pubFromDSN := pubFromDSN.(type) { + case *ecdsa.PublicKey: + ek, err = ConvertToECDHPublicKey(pubFromDSN) + if err != nil { + return nil, fmt.Errorf("ecdh conversion failure: %w", err) + } + case *ecdh.PublicKey: + ek = pubFromDSN + default: + return nil, errors.New("not an supported type of public key") + } + } else { + ekDSA, err := UncompressECPubKey(convCurve(e.sk.Curve()), ephemeral) + if err != nil { + return nil, err + } + ek, err = ekDSA.ECDH() + if err != nil { + return nil, fmt.Errorf("ecdh failure: %w", err) + } + } + + ikm, err := e.sk.ECDH(ek) + if err != nil { + return nil, fmt.Errorf("ecdh failure: %w", err) + } + + hkdfObj := hkdf.New(sha256.New, ikm, e.salt, e.info) + + derivedKey := make([]byte, len(ikm)) + if _, err := io.ReadFull(hkdfObj, derivedKey); err != nil { + return nil, fmt.Errorf("hkdf failure: %w", err) + } + + // Encrypt data with derived key using aes-gcm + block, err := aes.NewCipher(derivedKey) + if err != nil { + return nil, fmt.Errorf("aes.NewCipher failure: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, fmt.Errorf("cipher.NewGCM failure: %w", err) + } + + nonceSize := gcm.NonceSize() + if len(data) < nonceSize { + return nil, errors.New("ciphertext too short") + } + + nonce, ciphertext := data[:nonceSize], data[nonceSize:] + plaintext, err := gcm.Open(nil, nonce, ciphertext, nil) + if err != nil { + return nil, fmt.Errorf("gcm.Open failure: %w", err) + } + + return plaintext, nil +} + +func convCurve(c ecdh.Curve) elliptic.Curve { + switch c { + case ecdh.P256(): + return elliptic.P256() + case ecdh.P384(): + return elliptic.P384() + case ecdh.P521(): + return elliptic.P521() + default: + return nil + } +} diff --git a/lib/ocrypto/asym_encrypt_decrypt_test.go b/lib/ocrypto/asym_encrypt_decrypt_test.go index a40e93834..29a9d33de 100644 --- a/lib/ocrypto/asym_encrypt_decrypt_test.go +++ b/lib/ocrypto/asym_encrypt_decrypt_test.go @@ -5,7 +5,7 @@ import ( ) func TestAsymEncryptionAndDecryption(t *testing.T) { - var rsaKeys = []struct { + var keypairs = []struct { privateKey string publicKey string }{ @@ -215,10 +215,25 @@ I099IoRfC5djHUYYLMU/VkOIHuPC3sb7J65pSN26eR8bTMVNagk187V/xNwUuvkf wVyElqp317Ksz+GtTIc+DE6oryxK3tZd4hrj9fXT4KiJvQ4pcRjpePgH7B8= -----END CERTIFICATE-----`, }, + {`-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgwQlQvwfqC0sEaPVi +l1CdHNqAndukGsrqMsfiIefXHQChRANCAAQSZSoVakwpWhKBZIR9dmmTkKv7GK6n +6d0yFeGzOyqB7l9LOzOwlCDdm9k0jBQBw597Dyy7KQzW73zi+pSpgfYr +-----END PRIVATE KEY----- +`, `-----BEGIN CERTIFICATE----- +MIIBcTCCARegAwIBAgIUQBzVxCvhpTzXU+i7qyiTNniBL4owCgYIKoZIzj0EAwIw +DjEMMAoGA1UEAwwDa2FzMB4XDTI1MDExMDE2MzQ1NVoXDTI2MDExMDE2MzQ1NVow +DjEMMAoGA1UEAwwDa2FzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEmUqFWpM +KVoSgWSEfXZpk5Cr+xiup+ndMhXhszsqge5fSzszsJQg3ZvZNIwUAcOfew8suykM +1u984vqUqYH2K6NTMFEwHQYDVR0OBBYEFCAo/c694aHwmw/0kUTKuFvAQ4OcMB8G +A1UdIwQYMBaAFCAo/c694aHwmw/0kUTKuFvAQ4OcMA8GA1UdEwEB/wQFMAMBAf8w +CgYIKoZIzj0EAwIDSAAwRQIgUzKsJS6Pcu2aZ6BFfuqob552Ebdel4uFGZMqWrwW +bW0CIQDT5QED+8mHFot9JXSx2q1c5mnRvl4yElK0fiHeatBdqw== +-----END CERTIFICATE-----`}, } - for _, test := range rsaKeys { - asymEncryptor, err := NewAsymEncryption(test.publicKey) + for _, test := range keypairs { + asymEncryptor, err := FromPublicPEM(test.publicKey) if err != nil { t.Fatalf("NewAsymEncryption - failed: %v", err) } @@ -229,14 +244,25 @@ wVyElqp317Ksz+GtTIc+DE6oryxK3tZd4hrj9fXT4KiJvQ4pcRjpePgH7B8= t.Fatalf("AsymEncryption encrypt failed: %v", err) } - asymDecryptor, err := NewAsymDecryption(test.privateKey) + asymDecryptor, err := FromPrivatePEM(test.privateKey) if err != nil { t.Fatalf("NewAsymDecryption - failed: %v", err) } - decryptedText, err := asymDecryptor.Decrypt(cipherText) - if err != nil { - t.Fatalf("AsymDecryption decrypt failed: %v", err) + var decryptedText []byte + ek := asymEncryptor.EphemeralKey() + if ek == nil { + decryptedText, err = asymDecryptor.Decrypt(cipherText) + if err != nil { + t.Fatalf("AsymDecryption decrypt failed: %v", err) + } + } else if ecd, ok := asymDecryptor.(ECDecryptor); ok { + decryptedText, err = ecd.DecryptWithEphemeralKey(cipherText, ek) + if err != nil { + t.Fatalf("AsymDecryption decrypt failed: %v", err) + } + } else { + t.Fatalf("AsymDecryption wrong type: %T", asymDecryptor) } if string(decryptedText) != plainText { diff --git a/lib/ocrypto/asym_encryption.go b/lib/ocrypto/asym_encryption.go index 65ef5a115..f8cfd68b9 100644 --- a/lib/ocrypto/asym_encryption.go +++ b/lib/ocrypto/asym_encryption.go @@ -1,63 +1,169 @@ package ocrypto import ( + "crypto/aes" + "crypto/cipher" + "crypto/ecdh" + "crypto/ecdsa" "crypto/rand" "crypto/rsa" "crypto/sha1" //nolint:gosec // used for padding which is safe + "crypto/sha256" "crypto/x509" "encoding/pem" "errors" "fmt" + "io" "strings" + + "golang.org/x/crypto/hkdf" ) +type SchemeType string + +const ( + RSA SchemeType = "wrapped" + EC SchemeType = "ec-wrapped" +) + +type PublicKeyEncryptor interface { + // Encrypt encrypts data with public key. + Encrypt(data []byte) ([]byte, error) + + // PublicKeyInPemFormat Returns public key in pem format, or the empty string if not present + PublicKeyInPemFormat() (string, error) + + // Type required to use the scheme for encryption - notably, if it procduces extra metadata. + Type() SchemeType + + // For EC schemes, this method returns the public part of the ephemeral key. + // Otherwise, it returns nil. + EphemeralKey() []byte + + // Any extra metadata, e.g. the ephemeral public key for EC scheme keys. + Metadata() (map[string]string, error) +} + type AsymEncryption struct { PublicKey *rsa.PublicKey } +type ECEncryptor struct { + pub *ecdh.PublicKey + ek *ecdh.PrivateKey + salt []byte + info []byte +} + +func FromPublicPEM(publicKeyInPem string) (PublicKeyEncryptor, error) { + pub, err := getPublicPart(publicKeyInPem) + if err != nil { + return nil, err + } + + switch pub := pub.(type) { + case *rsa.PublicKey: + return &AsymEncryption{pub}, nil + case *ecdsa.PublicKey: + e, err := pub.ECDH() + if err != nil { + return nil, err + } + return newECIES(e) + case *ecdh.PublicKey: + return newECIES(pub) + default: + break + } + + return nil, errors.New("not an supported type of public key") +} + +func newECIES(pub *ecdh.PublicKey) (ECEncryptor, error) { + ek, err := pub.Curve().GenerateKey(rand.Reader) + // TK Make these reasonable? IIRC salt should be longer, info maybe a parameters? + salt := []byte("salt") + return ECEncryptor{pub, ek, salt, nil}, err +} + // NewAsymEncryption creates and returns a new AsymEncryption. +// Deprecated: Use FromPublicPEM instead. func NewAsymEncryption(publicKeyInPem string) (AsymEncryption, error) { + pub, err := getPublicPart(publicKeyInPem) + if err != nil { + return AsymEncryption{}, err + } + + switch pub := pub.(type) { + case *rsa.PublicKey: + return AsymEncryption{pub}, nil + default: + break + } + + return AsymEncryption{}, errors.New("not an supported type of public key") +} + +func getPublicPart(publicKeyInPem string) (any, error) { block, _ := pem.Decode([]byte(publicKeyInPem)) if block == nil { - return AsymEncryption{}, errors.New("failed to parse PEM formatted public key") + return nil, errors.New("failed to parse PEM formatted public key") } var pub any if strings.Contains(publicKeyInPem, "BEGIN CERTIFICATE") { cert, err := x509.ParseCertificate(block.Bytes) if err != nil { - return AsymEncryption{}, fmt.Errorf("x509.ParseCertificate failed: %w", err) + return nil, fmt.Errorf("x509.ParseCertificate failed: %w", err) } - var ok bool - if pub, ok = cert.PublicKey.(*rsa.PublicKey); !ok { - return AsymEncryption{}, errors.New("failed to parse PEM formatted public key") - } + pub = cert.PublicKey } else { var err error pub, err = x509.ParsePKIXPublicKey(block.Bytes) if err != nil { - return AsymEncryption{}, fmt.Errorf("x509.ParsePKIXPublicKey failed: %w", err) + return nil, fmt.Errorf("x509.ParsePKIXPublicKey failed: %w", err) } } + return pub, nil +} - switch pub := pub.(type) { - case *rsa.PublicKey: - return AsymEncryption{pub}, nil - default: - break +func (e AsymEncryption) Type() SchemeType { + return RSA +} + +func (e ECEncryptor) Type() SchemeType { + return EC +} + +func (e AsymEncryption) EphemeralKey() []byte { + return nil +} + +func (e ECEncryptor) EphemeralKey() []byte { + publicKeyBytes, err := x509.MarshalPKIXPublicKey(e.ek.PublicKey()) + if err != nil { + return nil } + return publicKeyBytes +} - return AsymEncryption{}, errors.New("not an rsa PEM formatted public key") +func (e AsymEncryption) Metadata() (map[string]string, error) { + return make(map[string]string), nil } -// Encrypt encrypts data with public key. -func (asymEncryption AsymEncryption) Encrypt(data []byte) ([]byte, error) { - if asymEncryption.PublicKey == nil { +func (e ECEncryptor) Metadata() (map[string]string, error) { + m := make(map[string]string) + m["ephemeralPublicKey"] = string(e.EphemeralKey()) + return m, nil +} + +func (e AsymEncryption) Encrypt(data []byte) ([]byte, error) { + if e.PublicKey == nil { return nil, errors.New("failed to encrypt, public key is empty") } - bytes, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, asymEncryption.PublicKey, data, nil) //nolint:gosec // used for padding which is safe + bytes, err := rsa.EncryptOAEP(sha1.New(), rand.Reader, e.PublicKey, data, nil) //nolint:gosec // used for padding which is safe if err != nil { return nil, fmt.Errorf("rsa.EncryptOAEP failed: %w", err) } @@ -65,13 +171,12 @@ func (asymEncryption AsymEncryption) Encrypt(data []byte) ([]byte, error) { return bytes, nil } -// PublicKeyInPemFormat Returns public key in pem format. -func (asymEncryption AsymEncryption) PublicKeyInPemFormat() (string, error) { - if asymEncryption.PublicKey == nil { +func publicKeyInPemFormat(pk any) (string, error) { + if pk == nil { return "", errors.New("failed to generate PEM formatted public key") } - publicKeyBytes, err := x509.MarshalPKIXPublicKey(asymEncryption.PublicKey) + publicKeyBytes, err := x509.MarshalPKIXPublicKey(pk) if err != nil { return "", fmt.Errorf("x509.MarshalPKIXPublicKey failed: %w", err) } @@ -85,3 +190,46 @@ func (asymEncryption AsymEncryption) PublicKeyInPemFormat() (string, error) { return string(publicKeyPem), nil } + +func (e AsymEncryption) PublicKeyInPemFormat() (string, error) { + return publicKeyInPemFormat(e.PublicKey) +} + +// Encrypts the data with the EC public key. +func (e ECEncryptor) Encrypt(data []byte) ([]byte, error) { + ikm, err := e.ek.ECDH(e.pub) + if err != nil { + return nil, fmt.Errorf("ecdh failure: %w", err) + } + + hkdfObj := hkdf.New(sha256.New, ikm, e.salt, e.info) + + derivedKey := make([]byte, len(ikm)) + if _, err := io.ReadFull(hkdfObj, derivedKey); err != nil { + return nil, fmt.Errorf("hkdf failure: %w", err) + } + + // Encrypt data with derived key using aes-gcm + block, err := aes.NewCipher(derivedKey) + if err != nil { + return nil, fmt.Errorf("aes.NewCipher failed: %w", err) + } + + gcm, err := cipher.NewGCM(block) + if err != nil { + return nil, fmt.Errorf("cipher.NewGCM failed: %w", err) + } + + nonce := make([]byte, gcm.NonceSize()) + if _, err := io.ReadFull(rand.Reader, nonce); err != nil { + return nil, fmt.Errorf("nonce generation failed: %w", err) + } + + ciphertext := gcm.Seal(nonce, nonce, data, nil) + return ciphertext, nil +} + +// PublicKeyInPemFormat Returns public key in pem format. +func (e ECEncryptor) PublicKeyInPemFormat() (string, error) { + return publicKeyInPemFormat(e.ek.Public()) +} diff --git a/lib/ocrypto/ec_key_pair.go b/lib/ocrypto/ec_key_pair.go index 6b9d0a960..504c13408 100644 --- a/lib/ocrypto/ec_key_pair.go +++ b/lib/ocrypto/ec_key_pair.go @@ -19,6 +19,15 @@ import ( type ECCMode uint8 +type KeyType string + +const ( + RSA2048Key KeyType = "rsa:2048" + EC256Key KeyType = "ec:secp256r1" + EC384Key KeyType = "ec:secp384r1" + EC521Key KeyType = "ec:secp521r1" +) + const ( ECCModeSecp256r1 ECCMode = 0 ECCModeSecp384r1 ECCMode = 1 @@ -26,10 +35,60 @@ const ( ECCModeSecp256k1 ECCMode = 3 ) +const ( + ECCurveP256Size = 256 + ECCurveP384Size = 384 + ECCurveP521Size = 521 + RSA2048Size = 2048 +) + +type KeyPair interface { + PublicKeyInPemFormat() (string, error) + PrivateKeyInPemFormat() (string, error) + GetKeyType() KeyType +} + +func NewKeyPair(kt KeyType) (KeyPair, error) { + switch kt { + case RSA2048Key: + bits, err := RSAKeyTypeToBits(kt) + if err != nil { + return nil, err + } + return NewRSAKeyPair(bits) + case EC256Key, EC384Key, EC521Key: + mode, err := ECKeyTypeToMode(kt) + if err != nil { + return nil, err + } + return NewECKeyPair(mode) + default: + return nil, fmt.Errorf("unsupported key type: %v", kt) + } +} + type ECKeyPair struct { PrivateKey *ecdsa.PrivateKey } +func IsECKeyType(kt KeyType) bool { + switch kt { //nolint:exhaustive // only handle ec types + case EC256Key, EC384Key, EC521Key: + return true + default: + return false + } +} + +func IsRSAKeyType(kt KeyType) bool { + switch kt { //nolint:exhaustive // only handle rsa types + case RSA2048Key: + return true + default: + return false + } +} + // GetECCurveFromECCMode return elliptic curve from ecc mode func GetECCurveFromECCMode(mode ECCMode) (elliptic.Curve, error) { var c elliptic.Curve @@ -65,6 +124,42 @@ func (mode ECCMode) String() string { return "unspecified" } +// ECSizeToMode converts a curve size to an ECCMode +func ECSizeToMode(size int) (ECCMode, error) { + switch size { + case ECCurveP256Size: + return ECCModeSecp256r1, nil + case ECCurveP384Size: + return ECCModeSecp384r1, nil + case ECCurveP521Size: + return ECCModeSecp521r1, nil + default: + return 0, fmt.Errorf("unsupported EC curve size: %d", size) + } +} + +func ECKeyTypeToMode(kt KeyType) (ECCMode, error) { + switch kt { //nolint:exhaustive // only handle ec types + case EC256Key: + return ECCModeSecp256r1, nil + case EC384Key: + return ECCModeSecp384r1, nil + case EC521Key: + return ECCModeSecp521r1, nil + default: + return 0, fmt.Errorf("unsupported type: %v", kt) + } +} + +func RSAKeyTypeToBits(kt KeyType) (int, error) { + switch kt { //nolint:exhaustive // only handle rsa types + case RSA2048Key: + return RSA2048Size, nil + default: + return 0, fmt.Errorf("unsupported type: %v", kt) + } +} + // NewECKeyPair Generates an EC key pair of the given bit size. func NewECKeyPair(mode ECCMode) (ECKeyPair, error) { var c elliptic.Curve @@ -361,3 +456,37 @@ func ECPublicKeyInPemFormat(publicKey ecdsa.PublicKey) (string, error) { return string(publicKeyPem), nil } + +// GetECKeySize returns the curve size from a PEM-encoded EC public key +func GetECKeySize(pemData []byte) (int, error) { + block, _ := pem.Decode(pemData) + if block == nil { + return 0, fmt.Errorf("failed to parse PEM block") + } + + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return 0, fmt.Errorf("failed to parse public key: %w", err) + } + + ecKey, ok := pub.(*ecdsa.PublicKey) + if !ok { + return 0, fmt.Errorf("not an EC key") + } + + switch ecKey.Curve { + case elliptic.P256(): + return ECCurveP256Size, nil + case elliptic.P384(): + return ECCurveP384Size, nil + case elliptic.P521(): + return ECCurveP521Size, nil + default: + return 0, fmt.Errorf("unknown curve") + } +} + +// GetKeyType returns the key type (ECKey) +func (keyPair ECKeyPair) GetKeyType() KeyType { + return EC256Key +} diff --git a/lib/ocrypto/rsa_key_pair.go b/lib/ocrypto/rsa_key_pair.go index e52a5428a..914eb8f80 100644 --- a/lib/ocrypto/rsa_key_pair.go +++ b/lib/ocrypto/rsa_key_pair.go @@ -76,3 +76,8 @@ func (keyPair RsaKeyPair) KeySize() (int, error) { } return keyPair.privateKey.N.BitLen(), nil } + +// GetKeyType returns the key type (RSAKey) +func (keyPair RsaKeyPair) GetKeyType() KeyType { + return RSA2048Key +} diff --git a/protocol/go/kas/kas.pb.go b/protocol/go/kas/kas.pb.go index 7451da9c9..a78c98a81 100644 --- a/protocol/go/kas/kas.pb.go +++ b/protocol/go/kas/kas.pb.go @@ -227,6 +227,8 @@ type KeyAccess struct { WrappedKey []byte `protobuf:"bytes,8,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` // header is only used for NanoTDFs Header []byte `protobuf:"bytes,9,opt,name=header,proto3" json:"header,omitempty"` + // For wrapping with an ECDH derived key, when type=ec-wrapped + EphemeralPublicKey []byte `protobuf:"bytes,10,opt,name=ephemeral_public_key,json=ephemeralPublicKey,proto3" json:"ephemeral_public_key,omitempty"` } func (x *KeyAccess) Reset() { @@ -324,6 +326,13 @@ func (x *KeyAccess) GetHeader() []byte { return nil } +func (x *KeyAccess) GetEphemeralPublicKey() []byte { + if x != nil { + return x.EphemeralPublicKey + } + return nil +} + type UnsignedRewrapRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -986,7 +995,7 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x6d, 0x22, 0x3b, 0x0a, 0x0d, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x12, 0x16, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x61, 0x6c, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0xa1, + 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x22, 0xd3, 0x02, 0x0a, 0x09, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, @@ -1005,147 +1014,150 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x22, 0x95, 0x04, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, - 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, - 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x48, 0x0a, 0x08, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6b, 0x61, 0x73, - 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x73, 0x1a, 0x30, 0x0a, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x82, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x74, 0x68, 0x4b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2f, 0x0a, 0x14, - 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, - 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x3a, 0x0a, - 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0xce, 0x01, 0x0a, 0x11, 0x57, 0x69, - 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x5c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6b, 0x61, - 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x10, 0x6b, 0x65, 0x79, - 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x3d, 0x0a, - 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, + 0x65, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x12, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x22, 0x95, 0x04, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, + 0x0a, 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x48, 0x0a, 0x08, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x6b, + 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x73, 0x1a, 0x30, 0x0a, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x82, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x74, 0x68, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2f, + 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, + 0x3a, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, 0x73, + 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0xce, 0x01, 0x0a, 0x11, + 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x5c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, - 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, - 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, - 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0xb1, 0x01, 0x0a, 0x10, 0x50, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x51, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x42, 0x33, 0x92, 0x41, 0x30, 0x32, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x72, 0x73, 0x61, 0x3a, 0x3c, 0x6b, 0x65, 0x79, - 0x73, 0x69, 0x7a, 0x65, 0x3e, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x3a, 0x3c, 0x63, 0x75, 0x72, - 0x76, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3e, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, - 0x68, 0x6d, 0x12, 0x26, 0x0a, 0x03, 0x66, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x66, - 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x03, 0x66, 0x6d, 0x74, 0x12, 0x22, 0x0a, 0x01, 0x76, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x01, 0x76, 0x22, 0x44, - 0x0a, 0x11, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, - 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x0d, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x5f, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, 0x06, 0x62, - 0x65, 0x61, 0x72, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, - 0x44, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x28, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x4d, 0x65, - 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x28, - 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x61, 0x73, 0x57, 0x72, - 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, - 0x67, 0x0a, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, - 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, - 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xea, 0x02, 0x0a, 0x0e, 0x52, 0x65, 0x77, - 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, - 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x30, - 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, - 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, 0x52, 0x10, - 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, - 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x73, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x29, - 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x73, 0x63, 0x68, 0x65, - 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6b, - 0x61, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, - 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xce, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x09, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x6b, 0x61, - 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, - 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, 0x32, - 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, - 0x02, 0x01, 0x12, 0x78, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, 0x65, 0x67, 0x61, - 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, - 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, - 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, - 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, 0x58, 0x0a, 0x06, - 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, - 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6b, 0x61, 0x73, - 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, - 0x25, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, - 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, 0x32, 0x2f, - 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, 0x71, 0x0a, 0x1a, - 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, 0x12, 0x42, 0x53, - 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x65, 0x61, 0x72, - 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x62, 0x61, 0x63, - 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, - 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, 0x2e, 0x30, 0x0a, - 0x07, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, 0x6b, 0x61, - 0x73, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xca, 0x02, 0x03, - 0x4b, 0x61, 0x73, 0xe2, 0x02, 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x4b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x10, 0x6b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, + 0x3d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, + 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, + 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1c, + 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0xb1, 0x01, 0x0a, + 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x51, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0x92, 0x41, 0x30, 0x32, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x72, 0x73, 0x61, 0x3a, 0x3c, 0x6b, + 0x65, 0x79, 0x73, 0x69, 0x7a, 0x65, 0x3e, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x3a, 0x3c, 0x63, + 0x75, 0x72, 0x76, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3e, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x12, 0x26, 0x0a, 0x03, 0x66, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x03, 0x66, 0x6d, 0x74, 0x12, 0x22, 0x0a, 0x01, + 0x76, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x01, 0x76, + 0x22, 0x44, 0x0a, 0x11, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x0d, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, + 0x06, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x12, 0x44, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x28, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x61, 0x73, + 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0x67, 0x0a, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, + 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xea, 0x02, 0x0a, 0x0e, 0x52, + 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, + 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x30, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, + 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, + 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, + 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, + 0x12, 0x29, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x73, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, + 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x73, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xce, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x09, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, + 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, + 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x6b, 0x61, 0x73, 0x2f, + 0x76, 0x32, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, + 0x79, 0x90, 0x02, 0x01, 0x12, 0x78, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, 0x65, + 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, 0x73, + 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, 0x58, + 0x0a, 0x06, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, + 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6b, + 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x25, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, + 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, + 0x32, 0x2f, 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, 0x71, + 0x0a, 0x1a, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, 0x12, + 0x42, 0x53, 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x65, + 0x61, 0x72, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x62, + 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, + 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, 0x2e, + 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, + 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, + 0x6b, 0x61, 0x73, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xca, + 0x02, 0x03, 0x4b, 0x61, 0x73, 0xe2, 0x02, 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/sdk/kas_client.go b/sdk/kas_client.go index 1c4779a28..8093d5055 100644 --- a/sdk/kas_client.go +++ b/sdk/kas_client.go @@ -20,12 +20,13 @@ import ( const ( secondsPerMinute = 60 + statusPermit = "permit" ) type KASClient struct { accessTokenSource auth.AccessTokenSource dialOptions []grpc.DialOption - sessionKey *ocrypto.RsaKeyPair + sessionKey ocrypto.KeyPair } type kaoResult struct { @@ -39,7 +40,7 @@ type decryptor interface { Decrypt(ctx context.Context, results []kaoResult) (int, error) } -func newKASClient(dialOptions []grpc.DialOption, accessTokenSource auth.AccessTokenSource, sessionKey *ocrypto.RsaKeyPair) *KASClient { +func newKASClient(dialOptions []grpc.DialOption, accessTokenSource auth.AccessTokenSource, sessionKey ocrypto.KeyPair) *KASClient { return &KASClient{ accessTokenSource: accessTokenSource, dialOptions: dialOptions, @@ -113,7 +114,7 @@ func (k *KASClient) nanoUnwrap(ctx context.Context, requests ...*kas.UnsignedRew for _, results := range response.GetResponses() { var kaoKeys []kaoResult for _, kao := range results.GetResults() { - if kao.GetStatus() == "permit" { + if kao.GetStatus() == statusPermit { wrappedKey := kao.GetKasWrappedKey() key, err := aesGcm.Decrypt(wrappedKey) if err != nil { @@ -144,6 +145,57 @@ func (k *KASClient) unwrap(ctx context.Context, requests ...*kas.UnsignedRewrapR return nil, fmt.Errorf("error making rewrap request to kas: %w", err) } + if ocrypto.IsECKeyType(k.sessionKey.GetKeyType()) { + return k.handleECKeyResponse(response) + } + return k.handleRSAKeyResponse(response) +} + +func (k *KASClient) handleECKeyResponse(response *kas.RewrapResponse) (map[string][]kaoResult, error) { + kasEphemeralPublicKey := response.GetSessionPublicKey() + clientPrivateKey, err := k.sessionKey.PrivateKeyInPemFormat() + if err != nil { + return nil, fmt.Errorf("failed to get private key: %w", err) + } + ecdhKey, err := ocrypto.ComputeECDHKey([]byte(clientPrivateKey), []byte(kasEphemeralPublicKey)) + if err != nil { + return nil, fmt.Errorf("ocrypto.ComputeECDHKey failed: %w", err) + } + sessionKey, err := ocrypto.CalculateHKDF([]byte("salt"), ecdhKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.CalculateHKDF failed: %w", err) + } + + aesGcm, err := ocrypto.NewAESGcm(sessionKey) + if err != nil { + return nil, fmt.Errorf("ocrypto.NewAESGcm failed: %w", err) + } + + return k.processECResponse(response, aesGcm) +} + +func (k *KASClient) processECResponse(response *kas.RewrapResponse, aesGcm ocrypto.AesGcm) (map[string][]kaoResult, error) { + policyResults := make(map[string][]kaoResult) + for _, results := range response.GetResponses() { + var kaoKeys []kaoResult + for _, kao := range results.GetResults() { + if kao.GetStatus() == statusPermit { + key, err := aesGcm.Decrypt(kao.GetKasWrappedKey()) + if err != nil { + kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), Error: err}) + } else { + kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), SymmetricKey: key}) + } + } else { + kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), Error: errors.New(kao.GetError())}) + } + } + policyResults[results.GetPolicyId()] = kaoKeys + } + return policyResults, nil +} + +func (k *KASClient) handleRSAKeyResponse(response *kas.RewrapResponse) (map[string][]kaoResult, error) { clientPrivateKey, err := k.sessionKey.PrivateKeyInPemFormat() if err != nil { return nil, fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err) @@ -154,13 +206,16 @@ func (k *KASClient) unwrap(ctx context.Context, requests ...*kas.UnsignedRewrapR return nil, fmt.Errorf("ocrypto.NewAsymDecryption failed: %w", err) } + return k.processRSAResponse(response, asymDecryption) +} + +func (k *KASClient) processRSAResponse(response *kas.RewrapResponse, asymDecryption ocrypto.AsymDecryption) (map[string][]kaoResult, error) { policyResults := make(map[string][]kaoResult) for _, results := range response.GetResponses() { var kaoKeys []kaoResult for _, kao := range results.GetResults() { - if kao.GetStatus() == "permit" { - wrappedKey := kao.GetKasWrappedKey() - key, err := asymDecryption.Decrypt(wrappedKey) + if kao.GetStatus() == statusPermit { + key, err := asymDecryption.Decrypt(kao.GetKasWrappedKey()) if err != nil { kaoKeys = append(kaoKeys, kaoResult{KeyAccessObjectID: kao.GetKeyAccessObjectId(), Error: err}) } else { @@ -172,7 +227,6 @@ func (k *KASClient) unwrap(ctx context.Context, requests ...*kas.UnsignedRewrapR } policyResults[results.GetPolicyId()] = kaoKeys } - return policyResults, nil } diff --git a/sdk/manifest.go b/sdk/manifest.go index 9316dbf6b..fc3034fdd 100644 --- a/sdk/manifest.go +++ b/sdk/manifest.go @@ -20,15 +20,16 @@ type IntegrityInformation struct { } type KeyAccess struct { - KeyType string `json:"type"` - KasURL string `json:"url"` - Protocol string `json:"protocol"` - WrappedKey string `json:"wrappedKey"` - PolicyBinding interface{} `json:"policyBinding"` - EncryptedMetadata string `json:"encryptedMetadata,omitempty"` - KID string `json:"kid,omitempty"` - SplitID string `json:"sid,omitempty"` - SchemaVersion string `json:"schemaVersion,omitempty"` + KeyType string `json:"type"` + KasURL string `json:"url"` + Protocol string `json:"protocol"` + WrappedKey string `json:"wrappedKey"` + PolicyBinding interface{} `json:"policyBinding"` + EncryptedMetadata string `json:"encryptedMetadata,omitempty"` + KID string `json:"kid,omitempty"` + SplitID string `json:"sid,omitempty"` + SchemaVersion string `json:"schemaVersion,omitempty"` + EphemeralPublicKey string `json:"ephemeralPublicKey,omitempty"` } type PolicyBinding struct { diff --git a/sdk/schema/manifest-lax.schema.json b/sdk/schema/manifest-lax.schema.json index 532c95099..a31abd75f 100644 --- a/sdk/schema/manifest-lax.schema.json +++ b/sdk/schema/manifest-lax.schema.json @@ -99,6 +99,10 @@ "encryptedMetadata": { "description": "Metadata associated with the TDF, and the request. The contents of the metadata are freeform, and are used to pass information from the client, and any plugins that may be in use by the KAS. The metadata stored here should not be used for primary access decisions. Base64.", "type": ["string", "null"] + }, + "ephemeralPublicKey": { + "description": "For ECC wrapped keys, the client public key portion used, with the KAS public key identified with the key id, to derive a shared key that encrypts the wrapped key.", + "type": ["string", "null"] } } }, diff --git a/sdk/schema/manifest.schema.json b/sdk/schema/manifest.schema.json index dfb920d38..6488623fa 100644 --- a/sdk/schema/manifest.schema.json +++ b/sdk/schema/manifest.schema.json @@ -52,7 +52,7 @@ "type": { "description": "The type of key access object.", "type": "string", - "enum": ["wrapped", "remote"] + "enum": ["ec-wrapped", "remote", "wrapped"] }, "url": { "description": "A fully qualified URL pointing to a key access service responsible for managing access to the encryption keys.", @@ -64,7 +64,7 @@ "enum": ["kas"] }, "wrappedKey": { - "description": "The symmetric key used to encrypt the payload. It has been encrypted using the public key of the KAS, then base64 encoded.", + "description": "The symmetric key used to encrypt the payload. It has been encrypted using the public key of the KAS, then base64 encoded. Options", "type": "string" }, "sid": { @@ -99,6 +99,10 @@ "encryptedMetadata": { "description": "Metadata associated with the TDF, and the request. The contents of the metadata are freeform, and are used to pass information from the client, and any plugins that may be in use by the KAS. The metadata stored here should not be used for primary access decisions. Base64.", "type": "string" + }, + "ephemeralPublicKey": { + "description": "For ECC wrapped keys, the client public key portion used, with the KAS public key identified with the key id, to derive a shared key that encrypts the wrapped key.", + "type": "string" } } }, diff --git a/sdk/tdf.go b/sdk/tdf.go index d286a5389..08be44591 100644 --- a/sdk/tdf.go +++ b/sdk/tdf.go @@ -34,6 +34,7 @@ const ( tdfZipReference = "reference" kKeySize = 32 kWrapped = "wrapped" + kECWrapped = "ec-wrapped" kKasProtocol = "kas" kSplitKeyType = "split" kGCMCipherAlgorithm = "AES-256-GCM" @@ -65,7 +66,7 @@ type Reader struct { aesGcm ocrypto.AesGcm payloadSize int64 payloadKey []byte - kasSessionKey ocrypto.RsaKeyPair + kasSessionKey ocrypto.KeyPair config TDFReaderConfig } @@ -81,6 +82,11 @@ type tdf3DecryptHandler struct { reader *Reader } +type ecKeyWrappedKeyInfo struct { + publicKey string + wrappedKey string +} + func (r *tdf3DecryptHandler) Decrypt(ctx context.Context, results []kaoResult) (int, error) { err := r.reader.buildKey(ctx, results) if err != nil { @@ -412,12 +418,14 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon conjunction := make(map[string][]KASInfo) var splitIDs []string + keyAlgorithm := string(tdfConfig.keyType) + for _, splitInfo := range tdfConfig.splitPlan { // Public key was passed in with kasInfoList // TODO first look up in attribute information / add to split plan? ki, ok := latestKASInfo[splitInfo.KAS] if !ok || ki.PublicKey == "" { - k, err := s.getPublicKey(ctx, splitInfo.KAS, "rsa:2048") + k, err := s.getPublicKey(ctx, splitInfo.KAS, keyAlgorithm) if err != nil { return fmt.Errorf("unable to retrieve public key from KAS at [%s]: %w", splitInfo.KAS, err) } @@ -451,27 +459,10 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon // add meta data var encryptedMetadata string if len(tdfConfig.metaData) > 0 { - gcm, err := ocrypto.NewAESGcm(symKey) - if err != nil { - return fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) - } - - emb, err := gcm.Encrypt([]byte(tdfConfig.metaData)) + encryptedMetadata, err = encryptMetadata(symKey, tdfConfig.metaData) if err != nil { - return fmt.Errorf("ocrypto.AesGcm.encrypt failed:%w", err) - } - - iv := emb[:ocrypto.GcmStandardNonceSize] - metadata := EncryptedMetadata{ - Cipher: string(ocrypto.Base64Encode(emb)), - Iv: string(ocrypto.Base64Encode(iv)), + return err } - - metadataJSON, err := json.Marshal(metadata) - if err != nil { - return fmt.Errorf(" json.Marshal failed:%w", err) - } - encryptedMetadata = string(ocrypto.Base64Encode(metadataJSON)) } for _, kasInfo := range conjunction[splitID] { @@ -479,27 +470,9 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon return fmt.Errorf("splitID:[%s], kas:[%s]: %w", splitID, kasInfo.URL, errKasPubKeyMissing) } - // wrap the key with kas public key - asymEncrypt, err := ocrypto.NewAsymEncryption(kasInfo.PublicKey) + keyAccess, err := createKeyAccess(tdfConfig, kasInfo, symKey, policyBinding, encryptedMetadata, splitID) if err != nil { - return fmt.Errorf("ocrypto.NewAsymEncryption failed:%w", err) - } - - wrappedKey, err := asymEncrypt.Encrypt(symKey) - if err != nil { - return fmt.Errorf("ocrypto.AsymEncryption.encrypt failed:%w", err) - } - - keyAccess := KeyAccess{ - KeyType: kWrapped, - KasURL: kasInfo.URL, - KID: kasInfo.KID, - Protocol: kKasProtocol, - PolicyBinding: policyBinding, - EncryptedMetadata: encryptedMetadata, - SplitID: splitID, - WrappedKey: string(ocrypto.Base64Encode(wrappedKey)), - SchemaVersion: keyAccessSchemaVersion, + return err } manifest.EncryptionInformation.KeyAccessObjs = append(manifest.EncryptionInformation.KeyAccessObjs, keyAccess) @@ -526,6 +499,121 @@ func (s SDK) prepareManifest(ctx context.Context, t *TDFObject, tdfConfig TDFCon return nil } +func encryptMetadata(symKey []byte, metaData string) (string, error) { + gcm, err := ocrypto.NewAESGcm(symKey) + if err != nil { + return "", fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) + } + + emb, err := gcm.Encrypt([]byte(metaData)) + if err != nil { + return "", fmt.Errorf("ocrypto.AesGcm.encrypt failed:%w", err) + } + + iv := emb[:ocrypto.GcmStandardNonceSize] + metadata := EncryptedMetadata{ + Cipher: string(ocrypto.Base64Encode(emb)), + Iv: string(ocrypto.Base64Encode(iv)), + } + + metadataJSON, err := json.Marshal(metadata) + if err != nil { + return "", fmt.Errorf(" json.Marshal failed:%w", err) + } + return string(ocrypto.Base64Encode(metadataJSON)), nil +} + +func createKeyAccess(tdfConfig TDFConfig, kasInfo KASInfo, symKey []byte, policyBinding PolicyBinding, encryptedMetadata, splitID string) (KeyAccess, error) { + keyAccess := KeyAccess{ + KeyType: kWrapped, + KasURL: kasInfo.URL, + KID: kasInfo.KID, + Protocol: kKasProtocol, + PolicyBinding: policyBinding, + EncryptedMetadata: encryptedMetadata, + SplitID: splitID, + SchemaVersion: keyAccessSchemaVersion, + } + + if ocrypto.IsECKeyType(tdfConfig.keyType) { + mode, err := ocrypto.ECKeyTypeToMode(tdfConfig.keyType) + if err != nil { + return KeyAccess{}, err + } + wrappedKeyInfo, err := generateWrapKeyWithEC(mode, kasInfo.PublicKey, symKey) + if err != nil { + return KeyAccess{}, err + } + keyAccess.KeyType = kECWrapped + keyAccess.WrappedKey = wrappedKeyInfo.wrappedKey + keyAccess.EphemeralPublicKey = wrappedKeyInfo.publicKey + } else { + wrappedKey, err := generateWrapKeyWithRSA(kasInfo.PublicKey, symKey) + if err != nil { + return KeyAccess{}, err + } + keyAccess.WrappedKey = wrappedKey + } + + return keyAccess, nil +} + +func generateWrapKeyWithEC(mode ocrypto.ECCMode, kasPublicKey string, symKey []byte) (ecKeyWrappedKeyInfo, error) { + ecKeyPair, err := ocrypto.NewECKeyPair(mode) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.NewECKeyPair failed:%w", err) + } + + emphermalPublicKey, err := ecKeyPair.PublicKeyInPemFormat() + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("failed to get EC public key: %w", err) + } + + emphermalPrivateKey, err := ecKeyPair.PrivateKeyInPemFormat() + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("failed to get EC private key: %w", err) + } + + ecdhKey, err := ocrypto.ComputeECDHKey([]byte(emphermalPrivateKey), []byte(kasPublicKey)) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.ComputeECDHKey failed:%w", err) + } + + sessionKey, err := ocrypto.CalculateHKDF([]byte("salt"), ecdhKey) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.CalculateHKDF failed:%w", err) + } + + gcm, err := ocrypto.NewAESGcm(sessionKey) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.NewAESGcm failed:%w", err) + } + + wrappedKey, err := gcm.Encrypt(symKey) + if err != nil { + return ecKeyWrappedKeyInfo{}, fmt.Errorf("ocrypto.AESGcm.Encrypt failed:%w", err) + } + + return ecKeyWrappedKeyInfo{ + publicKey: emphermalPublicKey, + wrappedKey: string(ocrypto.Base64Encode(wrappedKey)), + }, nil +} + +func generateWrapKeyWithRSA(publicKey string, symKey []byte) (string, error) { + asymEncrypt, err := ocrypto.NewAsymEncryption(publicKey) + if err != nil { + return "", fmt.Errorf("ocrypto.NewAsymEncryption failed:%w", err) + } + + wrappedKey, err := asymEncrypt.Encrypt(symKey) + if err != nil { + return "", fmt.Errorf("ocrypto.AsymEncryption.encrypt failed:%w", err) + } + + return string(ocrypto.Base64Encode(wrappedKey)), nil +} + // create policy object func createPolicyObject(attributes []AttributeValueFQN) (PolicyObject, error) { uuidObj, err := uuid.NewUUID() @@ -585,7 +673,7 @@ func (s SDK) LoadTDF(reader io.ReadSeeker, opts ...TDFReaderOption) (*Reader, er dialOptions: s.dialOptions, tdfReader: tdfReader, manifest: *manifestObj, - kasSessionKey: *s.config.kasSessionKey, + kasSessionKey: config.kasSessionKey, config: *config, }, nil } @@ -885,8 +973,9 @@ func createRewrapRequest(_ context.Context, r *Reader) (map[string]*kas.Unsigned Hash: hash, Algorithm: alg, }, - SplitId: kao.SplitID, - WrappedKey: key, + SplitId: kao.SplitID, + WrappedKey: key, + EphemeralPublicKey: []byte(kao.EphemeralPublicKey), }, } if req, ok := kasReqs[kao.KasURL]; ok { @@ -1095,7 +1184,7 @@ func (r *Reader) buildKey(_ context.Context, results []kaoResult) error { // Unwraps the payload key, if possible, using the access service func (r *Reader) doPayloadKeyUnwrap(ctx context.Context) error { //nolint:gocognit // Better readability keeping it as is - kasClient := newKASClient(r.dialOptions, r.tokenSource, &r.kasSessionKey) + kasClient := newKASClient(r.dialOptions, r.tokenSource, r.kasSessionKey) var kaoResults []kaoResult reqFail := func(err error, req *kas.UnsignedRewrapRequest_WithPolicyRequest) { diff --git a/sdk/tdf_config.go b/sdk/tdf_config.go index e0c182bb6..0159b7a4b 100644 --- a/sdk/tdf_config.go +++ b/sdk/tdf_config.go @@ -13,6 +13,10 @@ const ( maxSegmentSize = defaultSegmentSize * 2 minSegmentSize = 16 * 1024 kasPublicKeyPath = "/kas_public_key" + DefaultRSAKeySize = 2048 + ECKeySize256 = 256 + ECKeySize384 = 384 + ECKeySize521 = 521 ) type TDFFormat = int @@ -63,33 +67,18 @@ type TDFConfig struct { attributeValues []*policy.Value kasInfoList []KASInfo splitPlan []keySplitStep + keyType ocrypto.KeyType } func newTDFConfig(opt ...TDFOption) (*TDFConfig, error) { - rsaKeyPair, err := ocrypto.NewRSAKeyPair(tdf3KeySize) - if err != nil { - return nil, fmt.Errorf("ocrypto.NewRSAKeyPair failed: %w", err) - } - - publicKey, err := rsaKeyPair.PublicKeyInPemFormat() - if err != nil { - return nil, fmt.Errorf("ocrypto.PublicKeyInPemFormat failed: %w", err) - } - - privateKey, err := rsaKeyPair.PublicKeyInPemFormat() - if err != nil { - return nil, fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err) - } - c := &TDFConfig{ autoconfigure: true, - tdfPrivateKey: privateKey, - tdfPublicKey: publicKey, defaultSegmentSize: defaultSegmentSize, enableEncryption: true, tdfFormat: JSONFormat, integrityAlgorithm: HS256, segmentIntegrityAlgorithm: GMAC, + keyType: ocrypto.RSA2048Key, // default to RSA } for _, o := range opt { @@ -99,9 +88,33 @@ func newTDFConfig(opt ...TDFOption) (*TDFConfig, error) { } } + publicKey, privateKey, err := generateKeyPair(c.keyType) + if err != nil { + return nil, err + } + + c.tdfPrivateKey = privateKey + c.tdfPublicKey = publicKey + return c, nil } +func generateKeyPair(kt ocrypto.KeyType) (string, string, error) { + keyPair, err := ocrypto.NewKeyPair(kt) + if err != nil { + return "", "", fmt.Errorf("ocrypto.NewRSAKeyPair failed: %w", err) + } + publicKey, err := keyPair.PublicKeyInPemFormat() + if err != nil { + return "", "", fmt.Errorf("ocrypto.PublicKeyInPemFormat failed: %w", err) + } + privateKey, err := keyPair.PrivateKeyInPemFormat() + if err != nil { + return "", "", fmt.Errorf("ocrypto.PrivateKeyInPemFormat failed: %w", err) + } + return publicKey, privateKey, nil +} + // WithDataAttributes appends the given data attributes to the bound policy func WithDataAttributes(attributes ...string) TDFOption { return func(c *TDFConfig) error { @@ -213,6 +226,16 @@ func WithAutoconfigure(enable bool) TDFOption { } } +func WithWrappingKeyAlg(keyType ocrypto.KeyType) TDFOption { + return func(c *TDFConfig) error { + if c.keyType == "" { + return fmt.Errorf("key type missing") + } + c.keyType = keyType + return nil + } +} + // Schema Validation where 0 = none (skip), 1 = lax (allowing novel entries, 'falsy' values for unkowns), 2 = strict (rejecting novel entries, strict match to manifest schema) type SchemaValidationIntensity int @@ -230,12 +253,17 @@ type TDFReaderConfig struct { disableAssertionVerification bool schemaValidationIntensity SchemaValidationIntensity + kasSessionKey ocrypto.KeyPair + keyType ocrypto.KeyType } func newTDFReaderConfig(opt ...TDFReaderOption) (*TDFReaderConfig, error) { + var err error c := &TDFReaderConfig{ disableAssertionVerification: false, + keyType: ocrypto.RSA2048Key, } + for _, o := range opt { err := o(c) if err != nil { @@ -243,6 +271,11 @@ func newTDFReaderConfig(opt ...TDFReaderOption) (*TDFReaderConfig, error) { } } + c.kasSessionKey, err = ocrypto.NewKeyPair(c.keyType) + if err != nil { + return nil, fmt.Errorf("failed to create RSA key pair: %w", err) + } + return c, nil } @@ -266,3 +299,13 @@ func WithDisableAssertionVerification(disable bool) TDFReaderOption { return nil } } + +func WithSessionKeyType(keyType ocrypto.KeyType) TDFReaderOption { + return func(c *TDFReaderConfig) error { + if c.keyType == "" { + return fmt.Errorf("key type missing") + } + c.keyType = keyType + return nil + } +} diff --git a/service/internal/security/crypto_provider.go b/service/internal/security/crypto_provider.go index 9538d3d6a..8c535fa55 100644 --- a/service/internal/security/crypto_provider.go +++ b/service/internal/security/crypto_provider.go @@ -19,6 +19,7 @@ type CryptoProvider interface { RSAPublicKey(keyID string) (string, error) RSAPublicKeyAsJSON(keyID string) (string, error) RSADecrypt(hash crypto.Hash, keyID string, keyLabel string, ciphertext []byte) ([]byte, error) + ECDecrypt(keyID string, ephemeralPublicKey, ciphertext []byte) ([]byte, error) ECPublicKey(keyID string) (string, error) ECCertificate(keyID string) (string, error) diff --git a/service/internal/security/standard_crypto.go b/service/internal/security/standard_crypto.go index 3fb91fc49..702e421b4 100644 --- a/service/internal/security/standard_crypto.go +++ b/service/internal/security/standard_crypto.go @@ -2,6 +2,7 @@ package security import ( "crypto" + "crypto/ecdh" "crypto/elliptic" "crypto/sha256" "crypto/x509" @@ -60,6 +61,9 @@ type StandardECCrypto struct { KeyPairInfo ecPrivateKeyPem string ecCertificatePEM string + + // Lazily filled in + sk *ecdh.PrivateKey } // List of keys by identifier @@ -427,3 +431,30 @@ func versionSalt() []byte { digest.Write([]byte(kNanoTDFMagicStringAndVersion)) return digest.Sum(nil) } + +// ECDecrypt uses hybrid ECIES to decrypt the data. +func (s *StandardCrypto) ECDecrypt(keyID string, ephemeralPublicKey, ciphertext []byte) ([]byte, error) { + ska, ok := s.keysByID[keyID] + if !ok { + return nil, fmt.Errorf("key [%s] not found", keyID) + } + sk, ok := ska.(StandardECCrypto) + if !ok { + return nil, fmt.Errorf("key [%s] is not an EC key", keyID) + } + if sk.sk == nil { + // Parse the private key + loaded, err := ocrypto.ECPrivateKeyFromPem([]byte(sk.ecPrivateKeyPem)) + if err != nil { + return nil, fmt.Errorf("failed to parse EC private key: %w", err) + } + sk.sk = loaded + } + + ed, err := ocrypto.NewECDecryptor(sk.sk) + if err != nil { + return nil, fmt.Errorf("failed to create EC decryptor: %w", err) + } + + return ed.DecryptWithEphemeralKey(ciphertext, ephemeralPublicKey) +} diff --git a/service/kas/access/provider.go b/service/kas/access/provider.go index c417a72a6..c10f71ddd 100644 --- a/service/kas/access/provider.go +++ b/service/kas/access/provider.go @@ -36,6 +36,11 @@ type KASConfig struct { ECCertID string `mapstructure:"eccertid" json:"eccertid"` // Deprecated RSACertID string `mapstructure:"rsacertid" json:"rsacertid"` + + // Enables experimental EC rewrap support in TDFs + // Enabling is required to parse KAOs with the `ec-wrapped` type, + // and (currently) also enables responding with ECIES encrypted responses. + ECTDFEnabled bool `mapstructure:"ec_tdf_enabled" json:"ec_tdf_enabled"` } // Specifies the preferred/default key for a given algorithm type. diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index 5507cdcc0..31eb3da9a 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -66,11 +66,16 @@ type entityInfo struct { } type kaoResult struct { - ID string - Key []byte - Error error + ID string + DEK []byte + Encapped []byte + Error error + + // Optional: Present for EC wrapped responses + EphemeralPublicKey []byte } +// From policy ID to KAO ID to result type policyKAOResults map[string]map[string]kaoResult const ( @@ -335,9 +340,9 @@ func addResultsToResponse(response *kaspb.RewrapResponse, result policyKAOResult case kaoRes.Error != nil: kaoResult.Status = kFailedStatus kaoResult.Result = &kaspb.KeyAccessRewrapResult_Error{Error: kaoRes.Error.Error()} - case kaoRes.Key != nil: + case kaoRes.Encapped != nil: kaoResult.Status = kPermitStatus - kaoResult.Result = &kaspb.KeyAccessRewrapResult_KasWrappedKey{KasWrappedKey: kaoRes.Key} + kaoResult.Result = &kaspb.KeyAccessRewrapResult_KasWrappedKey{KasWrappedKey: kaoRes.Encapped} default: kaoResult.Status = kFailedStatus kaoResult.Result = &kaspb.KeyAccessRewrapResult_Error{Error: "kao not processed by kas"} @@ -388,7 +393,7 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap } var results policyKAOResults if len(tdf3Reqs) > 0 { - results = p.tdf3Rewrap(ctx, tdf3Reqs, body.GetClientPublicKey(), entityInfo) + resp.SessionPublicKey, results = p.tdf3Rewrap(ctx, tdf3Reqs, body.GetClientPublicKey(), entityInfo) addResultsToResponse(resp, results) } else { resp.SessionPublicKey, results = p.nanoTDFRewrap(ctx, nanoReqs, body.GetClientPublicKey(), entityInfo) @@ -408,7 +413,7 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap if kao.Error != nil { return nil, kao.Error } - resp.EntityWrappedKey = kao.Key //nolint:staticcheck // deprecated but keeping behavior for backwards compatibility + resp.EntityWrappedKey = kao.Encapped //nolint:staticcheck // deprecated but keeping behavior for backwards compatibility } return connect.NewResponse(resp), err @@ -429,30 +434,84 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned failedKAORewrap(results, kao, err400("bad request")) continue } - var kidsToCheck []string - if kao.GetKeyAccessObject().GetKid() != "" { - kidsToCheck = []string{kao.GetKeyAccessObject().GetKid()} - } else { - p.Logger.InfoContext(ctx, "kid free kao") - for _, k := range p.KASConfig.Keyring { - if k.Algorithm == security.AlgorithmRSA2048 && k.Legacy { - kidsToCheck = append(kidsToCheck, k.KID) - } - } - if len(kidsToCheck) == 0 { - p.Logger.WarnContext(ctx, "failure to find legacy kids for rsa") + + var symKey []byte + var err error + switch kao.GetKeyAccessObject().GetKeyType() { + case "ec-wrapped": + + if !p.KASConfig.ECTDFEnabled { + p.Logger.WarnContext(ctx, "ec-wrapped not enabled") failedKAORewrap(results, kao, err400("bad request")) continue } - } - symKey, err := p.CryptoProvider.RSADecrypt(crypto.SHA1, kidsToCheck[0], "", kao.GetKeyAccessObject().GetWrappedKey()) - for _, kid := range kidsToCheck[1:] { - p.Logger.WarnContext(ctx, "continue paging through legacy KIDs for kid free kao", "err", err) - if err == nil { - break + // Get the ephemeral public key in PEM format + ephemeralPubKeyPEM := kao.GetKeyAccessObject().GetEphemeralPublicKey() + + // Get EC key size and convert to mode + keySize, err := ocrypto.GetECKeySize(ephemeralPubKeyPEM) + if err != nil { + return nil, results, fmt.Errorf("failed to get EC key size: %w", err) + } + + mode, err := ocrypto.ECSizeToMode(keySize) + if err != nil { + return nil, results, fmt.Errorf("failed to convert key size to mode: %w", err) + } + + // Parse the PEM public key + block, _ := pem.Decode(ephemeralPubKeyPEM) + if block == nil { + return nil, results, fmt.Errorf("failed to decode PEM block") + } + + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, results, fmt.Errorf("failed to parse public key: %w", err) + } + + ecPub, ok := pub.(*ecdsa.PublicKey) + if !ok { + return nil, results, fmt.Errorf("not an EC public key") + } + + // Compress the public key + compressedKey, err := ocrypto.CompressedECPublicKey(mode, *ecPub) + if err != nil { + return nil, results, fmt.Errorf("failed to compress public key: %w", err) + } + + symKey, err = p.CryptoProvider.ECDecrypt(kao.GetKeyAccessObject().GetKid(), compressedKey, kao.GetKeyAccessObject().GetWrappedKey()) + if err != nil { + return nil, results, fmt.Errorf("failed to decrypt EC key: %w", err) + } + case "wrapped": + var kidsToCheck []string + if kao.GetKeyAccessObject().GetKid() != "" { + kidsToCheck = []string{kao.GetKeyAccessObject().GetKid()} + } else { + p.Logger.InfoContext(ctx, "kid free kao") + for _, k := range p.KASConfig.Keyring { + if k.Algorithm == security.AlgorithmRSA2048 && k.Legacy { + kidsToCheck = append(kidsToCheck, k.KID) + } + } + if len(kidsToCheck) == 0 { + p.Logger.WarnContext(ctx, "failure to find legacy kids for rsa") + failedKAORewrap(results, kao, err400("bad request")) + continue + } + } + + symKey, err = p.CryptoProvider.RSADecrypt(crypto.SHA1, kidsToCheck[0], "", kao.GetKeyAccessObject().GetWrappedKey()) + for _, kid := range kidsToCheck[1:] { + p.Logger.WarnContext(ctx, "continue paging through legacy KIDs for kid free kao", "err", err) + if err == nil { + break + } + symKey, err = p.CryptoProvider.RSADecrypt(crypto.SHA1, kid, "", kao.GetKeyAccessObject().GetWrappedKey()) } - symKey, err = p.CryptoProvider.RSADecrypt(crypto.SHA1, kid, "", kao.GetKeyAccessObject().GetWrappedKey()) } if err != nil { p.Logger.WarnContext(ctx, "failure to decrypt dek", "err", err) @@ -460,14 +519,13 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned continue } - err = verifyPolicyBinding(ctx, []byte(req.GetPolicy().GetBody()), kao, symKey, *p.Logger) - if err != nil { + if err := verifyPolicyBinding(ctx, []byte(req.GetPolicy().GetBody()), kao, symKey, *p.Logger); err != nil { failedKAORewrap(results, kao, err) continue } results[kao.GetKeyAccessObjectId()] = kaoResult{ ID: kao.GetKeyAccessObjectId(), - Key: symKey, + DEK: symKey, } anyValidKAOs = true @@ -485,7 +543,7 @@ func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.Unsigned return policy, results, nil } -func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRewrapRequest_WithPolicyRequest, clientPublicKey string, entity *entityInfo) policyKAOResults { +func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRewrapRequest_WithPolicyRequest, clientPublicKey string, entity *entityInfo) (string, policyKAOResults) { if p.Tracer != nil { var span trace.Span ctx, span = p.Tracer.Start(ctx, "rewrap-tdf3") @@ -512,19 +570,42 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew pdpAccessResults, accessErr := p.canAccess(ctx, tok, policies) if accessErr != nil { failAllKaos(requests, results, err403("could not perform access")) - return results + return "", results } - asymEncrypt, err := ocrypto.NewAsymEncryption(clientPublicKey) + asymEncrypt, err := ocrypto.FromPublicPEM(clientPublicKey) if err != nil { p.Logger.WarnContext(ctx, "ocrypto.NewAsymEncryption:", "err", err) + failAllKaos(requests, results, err400("invalid request")) + return "", results + } + + var sessionKey string + if e, ok := asymEncrypt.(ocrypto.ECEncryptor); ok { + sessionKey, err = e.PublicKeyInPemFormat() + if err != nil { + p.Logger.ErrorContext(ctx, "unable to serialize ephemeral key", "err", err) + // This may be a 500, but could also be caused by a bad clientPublicKey + failAllKaos(requests, results, err400("invalid request")) + return "", results + } + if !p.KASConfig.ECTDFEnabled { + p.Logger.ErrorContext(ctx, "ec rewrap not enabled") + failAllKaos(requests, results, err400("invalid request")) + return "", results + } } for _, pdpAccess := range pdpAccessResults { policy := pdpAccess.Policy req, ok := policyReqs[policy] - kaoResults := results[req.GetPolicy().GetId()] + if !ok { + p.Logger.WarnContext(ctx, "policy not found in policyReqs", "policy.uuid", policy.UUID) + continue + } + kaoResults, ok := results[req.GetPolicy().GetId()] if !ok { // this should not happen + p.Logger.WarnContext(ctx, "policy not found in policyReq response", "policy.uuid", policy.UUID) continue } access := pdpAccess.Access @@ -533,7 +614,8 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew kasPolicy := ConvertToAuditKasPolicy(*policy) for _, kao := range req.GetKeyAccessObjects() { - kaoRes := kaoResults[kao.GetKeyAccessObjectId()] + kaoID := kao.GetKeyAccessObjectId() + kaoRes := kaoResults[kaoID] if kaoRes.Error != nil { continue } @@ -553,22 +635,23 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew continue } - rewrappedKey, err := asymEncrypt.Encrypt(kaoRes.Key) + rewrappedKey, err := asymEncrypt.Encrypt(kaoRes.DEK) if err != nil { p.Logger.WarnContext(ctx, "rewrap: ocrypto.AsymEncryption.encrypt failed", "err", err, "clientPublicKey", clientPublicKey) p.Logger.Audit.RewrapFailure(ctx, auditEventParams) failedKAORewrap(kaoResults, kao, err400("bad key for rewrap")) continue } - kaoResults[kao.GetKeyAccessObjectId()] = kaoResult{ - ID: kao.GetKeyAccessObjectId(), - Key: rewrappedKey, + kaoResults[kaoID] = kaoResult{ + ID: kaoID, + Encapped: rewrappedKey, + EphemeralPublicKey: asymEncrypt.EphemeralKey(), } p.Logger.Audit.RewrapSuccess(ctx, auditEventParams) } } - return results + return sessionKey, results } func (p *Provider) nanoTDFRewrap(ctx context.Context, requests []*kaspb.UnsignedRewrapRequest_WithPolicyRequest, clientPublicKey string, entity *entityInfo) (string, policyKAOResults) { @@ -645,7 +728,7 @@ func (p *Provider) nanoTDFRewrap(ctx context.Context, requests []*kaspb.Unsigned failedKAORewrap(kaoResults, kao, err403("forbidden")) continue } - cipherText, err := wrapKeyAES(sessionKey, kaoInfo.Key) + cipherText, err := wrapKeyAES(sessionKey, kaoInfo.DEK) if err != nil { p.Logger.Audit.RewrapFailure(ctx, auditEventParams) failedKAORewrap(kaoResults, kao, err403("forbidden")) @@ -653,8 +736,8 @@ func (p *Provider) nanoTDFRewrap(ctx context.Context, requests []*kaspb.Unsigned } kaoResults[kao.GetKeyAccessObjectId()] = kaoResult{ - ID: kao.GetKeyAccessObjectId(), - Key: cipherText, + ID: kao.GetKeyAccessObjectId(), + Encapped: cipherText, } p.Logger.Audit.RewrapSuccess(ctx, auditEventParams) @@ -725,7 +808,7 @@ func (p *Provider) verifyNanoRewrapRequests(ctx context.Context, req *kaspb.Unsi } results[kao.GetKeyAccessObjectId()] = kaoResult{ ID: kao.GetKeyAccessObjectId(), - Key: symmetricKey, + DEK: symmetricKey, } return policy, results } diff --git a/service/kas/kas.proto b/service/kas/kas.proto index 312540360..227d894d4 100644 --- a/service/kas/kas.proto +++ b/service/kas/kas.proto @@ -47,6 +47,9 @@ message KeyAccess { bytes wrapped_key = 8; // header is only used for NanoTDFs bytes header = 9; + + // For wrapping with an ECDH derived key, when type=ec-wrapped + bytes ephemeral_public_key = 10; } message UnsignedRewrapRequest { diff --git a/test/start-additional-kas/action.yaml b/test/start-additional-kas/action.yaml index 722ac9bbb..120a88a3e 100644 --- a/test/start-additional-kas/action.yaml +++ b/test/start-additional-kas/action.yaml @@ -12,6 +12,11 @@ inputs: kas-name: required: true description: 'The name for the additional KAS' + ec-tdf-enabled: + default: false + description: 'Whether to enable ECC wrapping for TDFs' + required: false + type: boolean runs: using: 'composite' @@ -23,6 +28,7 @@ runs: opentdf-${{ inputs.kas-name }}.yaml yq e ' (.server.port = ${{ inputs.kas-port }}) | (.mode = ["kas"]) + | (.services.kas.ec_tdf_enabled = ${{ inputs.ec-tdf-enabled }}) | (.sdk_config = {"client_id":"opentdf","client_secret":"secret","core":{"endpoint":"http://localhost:8080","plaintext":true}}) ' && .github/scripts/watch.sh opentdf-${{ inputs.kas-name }}.yaml ./opentdf --config-file ./opentdf-${{ inputs.kas-name }}.yaml start diff --git a/test/start-up-with-containers/action.yaml b/test/start-up-with-containers/action.yaml index 6130bb842..eb24dd95e 100644 --- a/test/start-up-with-containers/action.yaml +++ b/test/start-up-with-containers/action.yaml @@ -11,6 +11,11 @@ inputs: required: false description: A JSON array containing extra keys for the KAS to load. Each object should have 'kid', 'alg', 'private', and 'cert' fields. default: '[]' + ec-tdf-enabled: + default: false + description: 'Whether to enable ECC wrapping for TDFs' + required: false + type: boolean outputs: platform-working-dir: @@ -84,6 +89,10 @@ runs: opentdf.yaml yq e "${yq_command}" working-directory: otdf-test-platform + - name: Enable ECC wrapping for TDFs + if: ${{ inputs.ec-tdf-enabled }} + run: | + yq e '.services.kas.ec_tdf_enabled = true' -i opentdf.yaml - name: Trust the generated certs shell: bash run: | diff --git a/test/tdf-roundtrips.bats b/test/tdf-roundtrips.bats index d79007ebd..0e323fdcb 100755 --- a/test/tdf-roundtrips.bats +++ b/test/tdf-roundtrips.bats @@ -25,6 +25,34 @@ run go run ./examples decrypt sensitive.txt.tdf echo "$output" printf '%s\n' "$output" | grep "Hello Zero Trust" + + echo "[INFO] decrypting with EC..." + run go run ./examples decrypt -A 'ec:secp256r1' sensitive.txt.tdf + echo "$output" + printf '%s\n' "$output" | grep "Hello Zero Trust" +} + +@test "examples: roundtrip Z-TDF with EC wrapped KAO" { + # TODO: add subject mapping here to remove reliance on `provision fixtures` + echo "[INFO] create a tdf3 format file" + run go run ./examples encrypt -o sensitive-with-ec.txt.tdf --autoconfigure=false -A "ec:secp256r1" "Hello EC wrappers!" + echo "[INFO] echoing output; if successful, this is just the manifest" + echo "$output" + + echo "[INFO] Validate the manifest lists the expected kid in its KAO" + kaotype=$(jq -r '.encryptionInformation.keyAccess[0].type' <<<"${output}") + echo "$kaotype" + [ "$kaotype" = ec-wrapped ] + + echo "[INFO] decrypting..." + run go run ./examples decrypt sensitive-with-ec.txt.tdf + echo "$output" + printf '%s\n' "$output" | grep "Hello EC wrappers!" + + echo "[INFO] decrypting with EC..." + run go run ./examples decrypt -A 'ec:secp256r1' sensitive-with-ec.txt.tdf + echo "$output" + printf '%s\n' "$output" | grep "Hello EC wrappers!" } @test "examples: roundtrip Z-TDF with extra unnecessary, invalid kas" { @@ -210,6 +238,7 @@ logger: services: kas: enabled: true + ec_tdf_enabled: true keyring: - kid: ${ec_current_key} alg: ec:secp256r1 From 52782b3ac89acd128cee657c8f6167d80a6ce1db Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 14 Feb 2025 14:24:54 -0500 Subject: [PATCH 07/34] chore(ci): Fix missing option to workflow (#1921) --- test/start-up-with-containers/action.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/start-up-with-containers/action.yaml b/test/start-up-with-containers/action.yaml index eb24dd95e..36dbdb468 100644 --- a/test/start-up-with-containers/action.yaml +++ b/test/start-up-with-containers/action.yaml @@ -90,6 +90,7 @@ runs: working-directory: otdf-test-platform - name: Enable ECC wrapping for TDFs + shell: bash if: ${{ inputs.ec-tdf-enabled }} run: | yq e '.services.kas.ec_tdf_enabled = true' -i opentdf.yaml From a3d3f2a2ef913fc34a0489a54c4c92c7c5853491 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Fri, 14 Feb 2025 15:48:53 -0500 Subject: [PATCH 08/34] chore(ci): Fix wrong cwd in start-up-with-containers (#1922) --- test/start-up-with-containers/action.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/test/start-up-with-containers/action.yaml b/test/start-up-with-containers/action.yaml index 36dbdb468..5b17c2f99 100644 --- a/test/start-up-with-containers/action.yaml +++ b/test/start-up-with-containers/action.yaml @@ -94,6 +94,7 @@ runs: if: ${{ inputs.ec-tdf-enabled }} run: | yq e '.services.kas.ec_tdf_enabled = true' -i opentdf.yaml + working-directory: otdf-test-platform - name: Trust the generated certs shell: bash run: | From e6a53a370b13c3ed63752789aa886be660354e1a Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Tue, 18 Feb 2025 08:39:42 -0700 Subject: [PATCH 09/34] fix: Improve http.Client usage for security and performance (#1910) ### Proposed Changes This change switches us from maintaining a tls config which we then on-demand initialize an `http.Client` with to instead maintain and reuse an `http.Client` instance. This enables us to utilize the connection pooling which occurs within the `http.Transport` to reduce ssl handshakes and thus reduce latency. In addition this change provides us a central place to configure out `http.Client` (`httputil`). Allowing us to easily set configuration options to reduce the security risks of using an unconfigured `http.Client`. Notably timeouts to reduce DoS risks, and control around following redirects to prevent blind SSRF's. This PR 3/4 addresses #1891. After it's merged a small change will be made in the `service` to fully utilize the API being introduced in the SDK here. ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions --- sdk/auth/oauth/oauth.go | 21 +++++---- sdk/auth/oauth/oauth_test.go | 8 +++- sdk/auth/token_adding_interceptor.go | 19 +++++---- sdk/httputil/http.go | 64 ++++++++++++++++++++++++++++ sdk/options.go | 10 +++-- sdk/sdk.go | 13 +++--- 6 files changed, 106 insertions(+), 29 deletions(-) create mode 100644 sdk/httputil/http.go diff --git a/sdk/auth/oauth/oauth.go b/sdk/auth/oauth/oauth.go index a678360c4..e29b1670d 100644 --- a/sdk/auth/oauth/oauth.go +++ b/sdk/auth/oauth/oauth.go @@ -2,7 +2,6 @@ package oauth import ( "context" - "crypto/tls" "encoding/json" "fmt" "io" @@ -17,6 +16,7 @@ import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/opentdf/platform/sdk/httputil" ) const ( @@ -24,8 +24,8 @@ const ( ) type CertExchangeInfo struct { - TLSConfig *tls.Config - Audience []string + HTTPClient *http.Client + Audience []string } type ClientCredentials struct { @@ -146,6 +146,9 @@ func GetAccessToken(client *http.Client, tokenEndpoint string, scopes []string, if err != nil { return nil, err } + if client == nil { + client = httputil.SafeHTTPClient() + } resp, err := client.Do(req) if err != nil { @@ -249,6 +252,9 @@ func DoTokenExchange(ctx context.Context, client *http.Client, tokenEndpoint str if err != nil { return nil, err } + if client == nil { + client = httputil.SafeHTTPClient() + } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("error making request to IdP for token exchange: %w", err) @@ -313,12 +319,11 @@ func DoCertExchange(ctx context.Context, tokenEndpoint string, exchangeInfo Cert if err != nil { return nil, err } - client := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: exchangeInfo.TLSConfig, - }, - } + client := exchangeInfo.HTTPClient + if client == nil { + client = httputil.SafeHTTPClient() + } resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("error making request to IdP for certificate exchange: %w", err) diff --git a/sdk/auth/oauth/oauth_test.go b/sdk/auth/oauth/oauth_test.go index 288497285..8c55bccd2 100644 --- a/sdk/auth/oauth/oauth_test.go +++ b/sdk/auth/oauth/oauth_test.go @@ -23,6 +23,7 @@ import ( "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" "github.com/opentdf/platform/lib/fixtures" + "github.com/opentdf/platform/sdk/httputil" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" tc "github.com/testcontainers/testcontainers-go" @@ -78,12 +79,15 @@ func (s *OAuthSuite) TestCertExchangeFromKeycloak() { rootCAs, _ := x509.SystemCertPool() rootCAs.AppendCertsFromPEM(ca) s.Require().NoError(err) - tlsConfig := tls.Config{ + tlsConfig := &tls.Config{ MinVersion: tls.VersionTLS12, Certificates: []tls.Certificate{cert}, RootCAs: rootCAs, } - exhcangeInfo := CertExchangeInfo{TLSConfig: &tlsConfig, Audience: []string{"opentdf-sdk"}} + exhcangeInfo := CertExchangeInfo{ + HTTPClient: httputil.SafeHTTPClientWithTLSConfig(tlsConfig), + Audience: []string{"opentdf-sdk"}, + } tok, err := DoCertExchange( context.Background(), diff --git a/sdk/auth/token_adding_interceptor.go b/sdk/auth/token_adding_interceptor.go index 45f3ea33b..18a438c8f 100644 --- a/sdk/auth/token_adding_interceptor.go +++ b/sdk/auth/token_adding_interceptor.go @@ -14,6 +14,7 @@ import ( "github.com/lestrrat-go/jwx/v2/jwk" "github.com/lestrrat-go/jwx/v2/jws" "github.com/lestrrat-go/jwx/v2/jwt" + "github.com/opentdf/platform/sdk/httputil" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -25,15 +26,22 @@ const ( ) func NewTokenAddingInterceptor(t AccessTokenSource, c *tls.Config) TokenAddingInterceptor { + return NewTokenAddingInterceptorWithClient(t, httputil.SafeHTTPClientWithTLSConfig(c)) +} + +func NewTokenAddingInterceptorWithClient(t AccessTokenSource, c *http.Client) TokenAddingInterceptor { + if c == nil { + c = httputil.SafeHTTPClient() + } return TokenAddingInterceptor{ tokenSource: t, - tlsConfig: c, + httpClient: c, } } type TokenAddingInterceptor struct { tokenSource AccessTokenSource - tlsConfig *tls.Config + httpClient *http.Client } func (i TokenAddingInterceptor) AddCredentials( @@ -45,12 +53,7 @@ func (i TokenAddingInterceptor) AddCredentials( opts ...grpc.CallOption, ) error { newMetadata := make([]string, 0) - client := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: i.tlsConfig, - }, - } - accessToken, err := i.tokenSource.AccessToken(ctx, client) + accessToken, err := i.tokenSource.AccessToken(ctx, i.httpClient) if err == nil { newMetadata = append(newMetadata, "Authorization", fmt.Sprintf("DPoP %s", accessToken)) } else { diff --git a/sdk/httputil/http.go b/sdk/httputil/http.go new file mode 100644 index 000000000..323257c3c --- /dev/null +++ b/sdk/httputil/http.go @@ -0,0 +1,64 @@ +package httputil + +import ( + "crypto/tls" + "net/http" + "time" +) + +const ( + defaultTimeout = 120 * time.Second + // defaults to match DefaultTransport - defined to satisfy lint + maxIdleConns = 100 + idleConnTimeout = 90 * time.Second + tlsHandshakeTimeout = 10 * time.Second + expectContinueTimeout = 1 * time.Second +) + +var preventRedirectCheck = func(_ *http.Request, _ []*http.Request) error { + return http.ErrUseLastResponse // Prevent following redirects +} + +var safeHTTPClient = &http.Client{ + Transport: http.DefaultTransport, + Timeout: defaultTimeout, + CheckRedirect: preventRedirectCheck, +} + +// SafeHTTPClient returns a default http client which has sensible timeouts, won't follow redirects, and enables idle +// connection pooling. +func SafeHTTPClient() *http.Client { + return safeHTTPClient +} + +// SafeHTTPClientWithTLSConfig returns a http client which has sensible timeouts, won't follow redirects, and if +// specified a http.Transport with the tls.Config provided. +func SafeHTTPClientWithTLSConfig(cfg *tls.Config) *http.Client { + if cfg == nil { + return safeHTTPClient + } + return SafeHTTPClientWithTransport(&http.Transport{ + TLSClientConfig: cfg, + // config below matches DefaultTransport + Proxy: http.ProxyFromEnvironment, + ForceAttemptHTTP2: true, + MaxIdleConns: maxIdleConns, + IdleConnTimeout: idleConnTimeout, + TLSHandshakeTimeout: tlsHandshakeTimeout, + ExpectContinueTimeout: expectContinueTimeout, + }) +} + +// SafeHTTPClientWithTransport returns a http client which has sensible timeouts, won't follow redirects, and if +// specified the provided http.Transport. +func SafeHTTPClientWithTransport(transport *http.Transport) *http.Client { + if transport == nil { + return safeHTTPClient + } + return &http.Client{ + Transport: transport, + // config below matches our values for safeHttpClient + Timeout: defaultTimeout, + CheckRedirect: preventRedirectCheck, + } +} diff --git a/sdk/options.go b/sdk/options.go index 3ec1da618..42852c808 100644 --- a/sdk/options.go +++ b/sdk/options.go @@ -3,10 +3,12 @@ package sdk import ( "crypto/rsa" "crypto/tls" + "net/http" "github.com/opentdf/platform/lib/ocrypto" "github.com/opentdf/platform/sdk/auth" "github.com/opentdf/platform/sdk/auth/oauth" + "github.com/opentdf/platform/sdk/httputil" "golang.org/x/oauth2" "google.golang.org/grpc" "google.golang.org/grpc/credentials" @@ -20,7 +22,7 @@ type config struct { // Platform configuration structure is subject to change. Consume via accessor methods. PlatformConfiguration PlatformConfiguration dialOption grpc.DialOption - tlsConfig *tls.Config + httpClient *http.Client clientCredentials *oauth.ClientCredentials tokenExchange *oauth.TokenExchangeInfo tokenEndpoint string @@ -66,7 +68,7 @@ func WithInsecureSkipVerifyConn() Option { } c.dialOption = grpc.WithTransportCredentials(credentials.NewTLS(tlsConfig)) // used by http client - c.tlsConfig = tlsConfig + c.httpClient = httputil.SafeHTTPClientWithTLSConfig(tlsConfig) } } @@ -83,7 +85,7 @@ func WithInsecurePlaintextConn() Option { c.dialOption = grpc.WithTransportCredentials(insecure.NewCredentials()) // used by http client // FIXME anything to do here - c.tlsConfig = &tls.Config{} + c.httpClient = httputil.SafeHTTPClient() } } @@ -97,7 +99,7 @@ func WithClientCredentials(clientID, clientSecret string, scopes []string) Optio func WithTLSCredentials(tls *tls.Config, audience []string) Option { return func(c *config) { - c.certExchange = &oauth.CertExchangeInfo{TLSConfig: tls, Audience: audience} + c.certExchange = &oauth.CertExchangeInfo{HTTPClient: httputil.SafeHTTPClientWithTLSConfig(tls), Audience: audience} } } diff --git a/sdk/sdk.go b/sdk/sdk.go index 0a9280059..944bb21e1 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -27,6 +27,7 @@ import ( "github.com/opentdf/platform/protocol/go/wellknownconfiguration" "github.com/opentdf/platform/sdk/audit" "github.com/opentdf/platform/sdk/auth" + "github.com/opentdf/platform/sdk/httputil" "github.com/opentdf/platform/sdk/internal/archive" "github.com/xeipuuv/gojsonschema" "google.golang.org/grpc" @@ -154,7 +155,7 @@ func New(platformEndpoint string, opts ...Option) (*SDK, error) { return nil, err } if accessTokenSource != nil { - interceptor := auth.NewTokenAddingInterceptor(accessTokenSource, cfg.tlsConfig) + interceptor := auth.NewTokenAddingInterceptorWithClient(accessTokenSource, cfg.httpClient) uci = append(uci, interceptor.AddCredentials) } @@ -452,13 +453,11 @@ func getTokenEndpoint(c config) (string, error) { return "", err } - httpClient := &http.Client{ - Transport: &http.Transport{ - TLSClientConfig: c.tlsConfig, - }, + client := c.httpClient + if client == nil { + client = httputil.SafeHTTPClient() } - - resp, err := httpClient.Do(req) + resp, err := client.Do(req) if err != nil { return "", err } From 3a6648528e3d3582ec3c5222e4dfc37d0fb13e74 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 18 Feb 2025 15:13:12 -0500 Subject: [PATCH 10/34] fix(core): Fixes for ec-wrapped from js client (#1923) ### Proposed Changes * Javascript still uses the old, non-bulk request object format for rewrap * As such, the logic for upgrading the request body needs to support the ec wrapped kao type ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions --- service/kas/access/keyaccess.go | 21 +++++++++-------- service/kas/access/rewrap.go | 41 +++++++++++++++++++++------------ 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/service/kas/access/keyaccess.go b/service/kas/access/keyaccess.go index 69cd7fe21..ab704124c 100644 --- a/service/kas/access/keyaccess.go +++ b/service/kas/access/keyaccess.go @@ -1,14 +1,15 @@ package access type KeyAccess struct { - EncryptedMetadata string `json:"encryptedMetadata,omitempty"` - PolicyBinding interface{} `json:"policyBinding,omitempty"` - Protocol string `json:"protocol"` - Type string `json:"type"` - URL string `json:"url"` - KID string `json:"kid,omitempty"` - SID string `json:"sid,omitempty"` - WrappedKey []byte `json:"wrappedKey,omitempty"` - Header []byte `json:"header,omitempty"` - Algorithm string `json:"algorithm,omitempty"` + EncryptedMetadata string `json:"encryptedMetadata,omitempty"` + PolicyBinding interface{} `json:"policyBinding,omitempty"` + Protocol string `json:"protocol"` + Type string `json:"type"` + URL string `json:"url"` + KID string `json:"kid,omitempty"` + SID string `json:"sid,omitempty"` + WrappedKey []byte `json:"wrappedKey,omitempty"` + Header []byte `json:"header,omitempty"` + Algorithm string `json:"algorithm,omitempty"` + EphemeralPublicKey string `json:"ephemeralPublicKey,omitempty"` } diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index 31eb3da9a..0819e9746 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -158,17 +158,21 @@ func extractAndConvertV1SRTBody(body []byte) (kaspb.UnsignedRewrapRequest, error reqs := []*kaspb.UnsignedRewrapRequest_WithPolicyRequest{ { KeyAccessObjects: []*kaspb.UnsignedRewrapRequest_WithKeyAccessObject{ - {KeyAccessObjectId: "kao-0", KeyAccessObject: &kaspb.KeyAccess{ - EncryptedMetadata: kao.EncryptedMetadata, - PolicyBinding: &kaspb.PolicyBinding{Hash: binding, Algorithm: kao.Algorithm}, - Protocol: kao.Protocol, - KeyType: kao.Type, - KasUrl: kao.URL, - Kid: kao.KID, - SplitId: kao.SID, - WrappedKey: kao.WrappedKey, - Header: kao.Header, - }}, + { + KeyAccessObjectId: "kao-0", + KeyAccessObject: &kaspb.KeyAccess{ + EncryptedMetadata: kao.EncryptedMetadata, + PolicyBinding: &kaspb.PolicyBinding{Hash: binding, Algorithm: kao.Algorithm}, + Protocol: kao.Protocol, + KeyType: kao.Type, + KasUrl: kao.URL, + Kid: kao.KID, + SplitId: kao.SID, + WrappedKey: kao.WrappedKey, + Header: kao.Header, + EphemeralPublicKey: []byte(kao.EphemeralPublicKey), + }, + }, }, Algorithm: requestBody.Algorithm, Policy: &kaspb.UnsignedRewrapRequest_WithPolicy{ @@ -402,21 +406,24 @@ func (p *Provider) Rewrap(ctx context.Context, req *connect.Request[kaspb.Rewrap if isV1 { if len(results) != 1 { - return nil, fmt.Errorf("invalid request") + p.Logger.WarnContext(ctx, "400 due to wrong result set size", "results", results) + return nil, err400("invalid request") } kaoResults := *getMapValue(results) if len(kaoResults) != 1 { - return nil, fmt.Errorf("invalid request") + p.Logger.WarnContext(ctx, "400 due to wrong result set size", "kaoResults", kaoResults, "results", results) + return nil, err400("invalid request") } kao := *getMapValue(kaoResults) if kao.Error != nil { + p.Logger.DebugContext(ctx, "forwarding legacy err", "err", err) return nil, kao.Error } resp.EntityWrappedKey = kao.Encapped //nolint:staticcheck // deprecated but keeping behavior for backwards compatibility } - return connect.NewResponse(resp), err + return connect.NewResponse(resp), nil } func (p *Provider) verifyRewrapRequests(ctx context.Context, req *kaspb.UnsignedRewrapRequest_WithPolicyRequest) (*Policy, map[string]kaoResult, error) { @@ -555,8 +562,11 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew policyReqs := make(map[*Policy]*kaspb.UnsignedRewrapRequest_WithPolicyRequest) for _, req := range requests { policy, kaoResults, err := p.verifyRewrapRequests(ctx, req) - results[req.GetPolicy().GetId()] = kaoResults + policyID := req.GetPolicy().GetId() + results[policyID] = kaoResults if err != nil { + p.Logger.WarnContext(ctx, "rewrap: verifyRewrapRequests failed", "err", err, "policyID", policyID) + // TODO Fail all requests for this policy continue } policies = append(policies, policy) @@ -569,6 +579,7 @@ func (p *Provider) tdf3Rewrap(ctx context.Context, requests []*kaspb.UnsignedRew } pdpAccessResults, accessErr := p.canAccess(ctx, tok, policies) if accessErr != nil { + p.Logger.DebugContext(ctx, "tdf3rewrap: cannot access policy", "err", accessErr, "policies", policies) failAllKaos(requests, results, err403("could not perform access")) return "", results } From 443f1a0100c3d9e2c49c2a3e2b15b8b7dcb5d956 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 19:47:29 +0000 Subject: [PATCH 11/34] chore(ci): bump docker/metadata-action from 5.5.1 to 5.6.1 (#1900) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [docker/metadata-action](https://github.com/docker/metadata-action) from 5.5.1 to 5.6.1.
Release notes

Sourced from docker/metadata-action's releases.

v5.6.1

Full Changelog: https://github.com/docker/metadata-action/compare/v5.6.0...v5.6.1

v5.6.0

Full Changelog: https://github.com/docker/metadata-action/compare/v5.5.1...v5.6.0

Commits
  • 369eb59 Merge pull request #480 from crazy-max/back-to-sha-7
  • 7d870ce chore: update generated content
  • e44a9cd back to commit sha length of 7
  • 8cb0002 Merge pull request #478 from crazy-max/commit-date-request
  • e01ddd3 chore: update generated content
  • 861d98a commiter_date: fix github api request fallback
  • 359e915 Merge pull request #475 from crazy-max/commit-date-changes
  • 0c395eb commit_date: code cleanup and readme updates
  • 1156622 Merge pull request #474 from docker/dependabot/npm_and_yarn/cross-spawn-7.0.5
  • 95ea8d0 chore(deps): Bump cross-spawn from 7.0.3 to 7.0.5
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=docker/metadata-action&package-manager=github_actions&previous-version=5.5.1&new-version=5.6.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dave Mihalcik --- .github/workflows/nightly-build.yaml | 2 +- .github/workflows/release-build.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nightly-build.yaml b/.github/workflows/nightly-build.yaml index 1f25666c1..8203134b9 100644 --- a/.github/workflows/nightly-build.yaml +++ b/.github/workflows/nightly-build.yaml @@ -39,7 +39,7 @@ jobs: password: ${{ steps.gcp-auth.outputs.access_token }} - id: docker_meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 with: images: ${{ secrets.DOCKER_REPO }} tags: | diff --git a/.github/workflows/release-build.yaml b/.github/workflows/release-build.yaml index 4463498a4..3b937198f 100644 --- a/.github/workflows/release-build.yaml +++ b/.github/workflows/release-build.yaml @@ -45,7 +45,7 @@ jobs: password: ${{ steps.gcp-auth.outputs.access_token }} - id: docker_meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 + uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 with: images: ${{ secrets.DOCKER_REPO }} tags: | From 74abbb66cbb39023f56cd502a7cda294580a41c6 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Thu, 20 Feb 2025 15:23:49 -0500 Subject: [PATCH 12/34] fix(sdk): Fix compatibility between bulk and non-bulk rewrap (#1914) ### Proposed Changes * Fixes for version skew in the rewrap introduced by the bulk change * Pre-bulk services' responses are now interpretable from responses from post-bulk sdks * Post-bulk SDKs now fill out necessary fields for pre-bulk services * Post-bulk services have slightly better parsing behavior ### Checklist - [x] I have added or updated unit tests - [x] I have added or updated integration tests (if appropriate) - [x] I have added or updated documentation ### Testing Instructions --- docs/grpc/index.html | 52 ++++++ protocol/go/kas/kas.pb.go | 350 ++++++++++++++++++++--------------- sdk/kas_client.go | 47 ++++- sdk/kas_client_test.go | 53 ++++++ service/kas/access/rewrap.go | 22 ++- service/kas/kas.proto | 15 +- 6 files changed, 373 insertions(+), 166 deletions(-) diff --git a/docs/grpc/index.html b/docs/grpc/index.html index 5a9fee706..99bd9b661 100644 --- a/docs/grpc/index.html +++ b/docs/grpc/index.html @@ -3971,10 +3971,62 @@

UnsignedRewrapRequest

+ + key_access + KeyAccess + +

Deprecated. Used for legacy non-bulk requests

+ + + + policy + string + +

Deprecated. Used for legacy non-bulk requests

+ + + + algorithm + string + +

Deprecated. Used for legacy non-bulk requests

+ + + + +

Fields with deprecated option

+ + + + + + + + + + + + + + + + + + + + + + + + + +
NameOption
key_access

true

policy

true

algorithm

true

+ + diff --git a/protocol/go/kas/kas.pb.go b/protocol/go/kas/kas.pb.go index a78c98a81..c1052bf36 100644 --- a/protocol/go/kas/kas.pb.go +++ b/protocol/go/kas/kas.pb.go @@ -340,6 +340,18 @@ type UnsignedRewrapRequest struct { ClientPublicKey string `protobuf:"bytes,1,opt,name=client_public_key,json=clientPublicKey,proto3" json:"client_public_key,omitempty"` Requests []*UnsignedRewrapRequest_WithPolicyRequest `protobuf:"bytes,2,rep,name=requests,proto3" json:"requests,omitempty"` + // Used for legacy non-bulk requests + // + // Deprecated: Marked as deprecated in kas/kas.proto. + KeyAccess *KeyAccess `protobuf:"bytes,3,opt,name=key_access,json=keyAccess,proto3" json:"key_access,omitempty"` + // Used for legacy non-bulk requests + // + // Deprecated: Marked as deprecated in kas/kas.proto. + Policy string `protobuf:"bytes,4,opt,name=policy,proto3" json:"policy,omitempty"` + // Used for legacy non-bulk requests + // + // Deprecated: Marked as deprecated in kas/kas.proto. + Algorithm string `protobuf:"bytes,5,opt,name=algorithm,proto3" json:"algorithm,omitempty"` } func (x *UnsignedRewrapRequest) Reset() { @@ -388,6 +400,30 @@ func (x *UnsignedRewrapRequest) GetRequests() []*UnsignedRewrapRequest_WithPolic return nil } +// Deprecated: Marked as deprecated in kas/kas.proto. +func (x *UnsignedRewrapRequest) GetKeyAccess() *KeyAccess { + if x != nil { + return x.KeyAccess + } + return nil +} + +// Deprecated: Marked as deprecated in kas/kas.proto. +func (x *UnsignedRewrapRequest) GetPolicy() string { + if x != nil { + return x.Policy + } + return "" +} + +// Deprecated: Marked as deprecated in kas/kas.proto. +func (x *UnsignedRewrapRequest) GetAlgorithm() string { + if x != nil { + return x.Algorithm + } + return "" +} + type PublicKeyRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -1017,7 +1053,7 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x65, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x12, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x22, 0x95, 0x04, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x63, 0x4b, 0x65, 0x79, 0x22, 0x86, 0x05, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x63, 0x6c, 0x69, 0x65, 0x6e, @@ -1026,138 +1062,145 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x72, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x73, 0x1a, 0x30, 0x0a, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x82, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x74, 0x68, 0x4b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2f, - 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, - 0x3a, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, 0x73, - 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0f, 0x6b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0xce, 0x01, 0x0a, 0x11, - 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x5c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, - 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, - 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, - 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x4b, 0x65, - 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x10, 0x6b, - 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, - 0x3d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x25, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, - 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, - 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1c, - 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0xb1, 0x01, 0x0a, - 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x51, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0x92, 0x41, 0x30, 0x32, 0x2e, 0x61, 0x6c, 0x67, 0x6f, 0x72, - 0x69, 0x74, 0x68, 0x6d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x72, 0x73, 0x61, 0x3a, 0x3c, 0x6b, - 0x65, 0x79, 0x73, 0x69, 0x7a, 0x65, 0x3e, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x3a, 0x3c, 0x63, - 0x75, 0x72, 0x76, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3e, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, - 0x69, 0x74, 0x68, 0x6d, 0x12, 0x26, 0x0a, 0x03, 0x66, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x03, 0x66, 0x6d, 0x74, 0x12, 0x22, 0x0a, 0x01, - 0x76, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x01, 0x76, - 0x22, 0x44, 0x0a, 0x11, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x0d, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x69, 0x67, 0x6e, 0x65, - 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x52, - 0x06, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x12, 0x44, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, - 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x28, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x5f, - 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x61, 0x73, - 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x22, 0x67, 0x0a, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, - 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, 0x69, - 0x63, 0x79, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, - 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, - 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xea, 0x02, 0x0a, 0x0e, 0x52, - 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, 0x0a, - 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x21, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x30, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, - 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, 0x01, - 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, - 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, - 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, - 0x12, 0x29, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x73, 0x63, - 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, 0x61, - 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x73, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xce, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, 0x65, - 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x09, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, - 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, - 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, - 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x6b, 0x61, 0x73, 0x2f, - 0x76, 0x32, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, - 0x79, 0x90, 0x02, 0x01, 0x12, 0x78, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, 0x65, - 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, - 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, 0x73, - 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, 0x58, - 0x0a, 0x06, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, - 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x6b, - 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x25, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, 0x82, - 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x76, - 0x32, 0x2f, 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, 0x71, - 0x0a, 0x1a, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, 0x12, - 0x42, 0x53, 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, 0x65, - 0x61, 0x72, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x62, - 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, 0x74, - 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, 0x2e, - 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, 0x50, - 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, 0x66, - 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, 0x2f, - 0x6b, 0x61, 0x73, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xca, - 0x02, 0x03, 0x4b, 0x61, 0x73, 0xe2, 0x02, 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x74, 0x73, 0x12, 0x31, 0x0a, 0x0a, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6b, 0x65, + 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x1a, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x06, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x20, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x1a, 0x30, 0x0a, 0x0a, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x1a, 0x82, 0x01, 0x0a, 0x13, 0x57, 0x69, 0x74, 0x68, + 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, + 0x12, 0x3a, 0x0a, 0x11, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6b, 0x61, + 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x0f, 0x6b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x1a, 0xce, 0x01, 0x0a, + 0x11, 0x57, 0x69, 0x74, 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x5c, 0x0a, 0x12, 0x6b, 0x65, 0x79, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, + 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, + 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, 0x68, 0x4b, + 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x10, + 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, + 0x12, 0x3d, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, + 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x57, 0x69, 0x74, + 0x68, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x22, 0xb1, 0x01, + 0x0a, 0x10, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x51, 0x0a, 0x09, 0x61, 0x6c, 0x67, 0x6f, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x33, 0x92, 0x41, 0x30, 0x32, 0x2e, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x72, 0x73, 0x61, 0x3a, 0x3c, + 0x6b, 0x65, 0x79, 0x73, 0x69, 0x7a, 0x65, 0x3e, 0x20, 0x6f, 0x72, 0x20, 0x65, 0x63, 0x3a, 0x3c, + 0x63, 0x75, 0x72, 0x76, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x3e, 0x52, 0x09, 0x61, 0x6c, 0x67, 0x6f, + 0x72, 0x69, 0x74, 0x68, 0x6d, 0x12, 0x26, 0x0a, 0x03, 0x66, 0x6d, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x52, 0x03, 0x66, 0x6d, 0x74, 0x12, 0x22, 0x0a, + 0x01, 0x76, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x14, 0x92, 0x41, 0x11, 0x32, 0x0f, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x01, + 0x76, 0x22, 0x44, 0x0a, 0x11, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x69, 0x64, 0x22, 0x4f, 0x0a, 0x0d, 0x52, 0x65, 0x77, 0x72, 0x61, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x14, 0x73, 0x69, 0x67, 0x6e, + 0x65, 0x64, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, + 0x52, 0x06, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x22, 0xc7, 0x02, 0x0a, 0x15, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x44, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, 0x41, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x14, 0x6b, 0x65, 0x79, 0x5f, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x6b, 0x65, 0x79, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x12, 0x28, 0x0a, 0x0f, 0x6b, 0x61, 0x73, 0x5f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x48, 0x00, 0x52, 0x0d, 0x6b, 0x61, + 0x73, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x22, 0x67, 0x0a, 0x12, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, + 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6f, 0x6c, 0x69, + 0x63, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6f, 0x6c, + 0x69, 0x63, 0x79, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4b, 0x65, 0x79, + 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x22, 0xea, 0x02, 0x0a, 0x0e, + 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, + 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x21, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x42, 0x02, 0x18, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x30, 0x0a, 0x12, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x77, 0x72, 0x61, 0x70, + 0x70, 0x65, 0x64, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x42, 0x02, 0x18, + 0x01, 0x52, 0x10, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x57, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, + 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x70, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x10, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x12, 0x29, 0x0a, 0x0e, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x02, 0x18, 0x01, 0x52, 0x0d, 0x73, + 0x63, 0x68, 0x65, 0x6d, 0x61, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x09, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x52, 0x65, 0x77, 0x72, + 0x61, 0x70, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x73, 0x1a, 0x53, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x05, 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, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xce, 0x02, 0x0a, 0x0d, 0x41, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x69, 0x0a, 0x09, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x15, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, + 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2d, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, + 0x30, 0x30, 0x12, 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x12, 0x16, 0x2f, 0x6b, 0x61, 0x73, + 0x2f, 0x76, 0x32, 0x2f, 0x6b, 0x61, 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, + 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, 0x78, 0x0a, 0x0f, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, + 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x1b, 0x2e, 0x6b, 0x61, 0x73, 0x2e, 0x4c, + 0x65, 0x67, 0x61, 0x63, 0x79, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x22, 0x2a, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, + 0x00, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x12, 0x13, 0x2f, 0x6b, 0x61, 0x73, 0x2f, 0x6b, 0x61, + 0x73, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x90, 0x02, 0x01, 0x12, + 0x58, 0x0a, 0x06, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x12, 0x12, 0x2e, 0x6b, 0x61, 0x73, 0x2e, + 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, + 0x6b, 0x61, 0x73, 0x2e, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x25, 0x92, 0x41, 0x09, 0x4a, 0x07, 0x0a, 0x03, 0x32, 0x30, 0x30, 0x12, 0x00, + 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x3a, 0x01, 0x2a, 0x22, 0x0e, 0x2f, 0x6b, 0x61, 0x73, 0x2f, + 0x76, 0x32, 0x2f, 0x72, 0x65, 0x77, 0x72, 0x61, 0x70, 0x42, 0xe2, 0x01, 0x92, 0x41, 0x73, 0x12, + 0x71, 0x0a, 0x1a, 0x4f, 0x70, 0x65, 0x6e, 0x54, 0x44, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2a, 0x4c, 0x0a, + 0x12, 0x42, 0x53, 0x44, 0x20, 0x33, 0x2d, 0x43, 0x6c, 0x61, 0x75, 0x73, 0x65, 0x20, 0x43, 0x6c, + 0x65, 0x61, 0x72, 0x12, 0x36, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, + 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x73, + 0x74, 0x65, 0x72, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x35, + 0x2e, 0x30, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x2e, 0x6b, 0x61, 0x73, 0x42, 0x08, 0x4b, 0x61, 0x73, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x74, 0x64, 0x66, 0x2f, 0x70, 0x6c, 0x61, 0x74, + 0x66, 0x6f, 0x72, 0x6d, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2f, 0x67, 0x6f, + 0x2f, 0x6b, 0x61, 0x73, 0xa2, 0x02, 0x03, 0x4b, 0x58, 0x58, 0xaa, 0x02, 0x03, 0x4b, 0x61, 0x73, + 0xca, 0x02, 0x03, 0x4b, 0x61, 0x73, 0xe2, 0x02, 0x0f, 0x4b, 0x61, 0x73, 0x5c, 0x47, 0x50, 0x42, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x03, 0x4b, 0x61, 0x73, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1197,26 +1240,27 @@ var file_kas_kas_proto_goTypes = []interface{}{ var file_kas_kas_proto_depIdxs = []int32{ 3, // 0: kas.KeyAccess.policy_binding:type_name -> kas.PolicyBinding 14, // 1: kas.UnsignedRewrapRequest.requests:type_name -> kas.UnsignedRewrapRequest.WithPolicyRequest - 15, // 2: kas.KeyAccessRewrapResult.metadata:type_name -> kas.KeyAccessRewrapResult.MetadataEntry - 9, // 3: kas.PolicyRewrapResult.results:type_name -> kas.KeyAccessRewrapResult - 16, // 4: kas.RewrapResponse.metadata:type_name -> kas.RewrapResponse.MetadataEntry - 10, // 5: kas.RewrapResponse.responses:type_name -> kas.PolicyRewrapResult - 4, // 6: kas.UnsignedRewrapRequest.WithKeyAccessObject.key_access_object:type_name -> kas.KeyAccess - 13, // 7: kas.UnsignedRewrapRequest.WithPolicyRequest.key_access_objects:type_name -> kas.UnsignedRewrapRequest.WithKeyAccessObject - 12, // 8: kas.UnsignedRewrapRequest.WithPolicyRequest.policy:type_name -> kas.UnsignedRewrapRequest.WithPolicy - 17, // 9: kas.KeyAccessRewrapResult.MetadataEntry.value:type_name -> google.protobuf.Value - 17, // 10: kas.RewrapResponse.MetadataEntry.value:type_name -> google.protobuf.Value - 6, // 11: kas.AccessService.PublicKey:input_type -> kas.PublicKeyRequest - 2, // 12: kas.AccessService.LegacyPublicKey:input_type -> kas.LegacyPublicKeyRequest - 8, // 13: kas.AccessService.Rewrap:input_type -> kas.RewrapRequest - 7, // 14: kas.AccessService.PublicKey:output_type -> kas.PublicKeyResponse - 18, // 15: kas.AccessService.LegacyPublicKey:output_type -> google.protobuf.StringValue - 11, // 16: kas.AccessService.Rewrap:output_type -> kas.RewrapResponse - 14, // [14:17] is the sub-list for method output_type - 11, // [11:14] 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 + 4, // 2: kas.UnsignedRewrapRequest.key_access:type_name -> kas.KeyAccess + 15, // 3: kas.KeyAccessRewrapResult.metadata:type_name -> kas.KeyAccessRewrapResult.MetadataEntry + 9, // 4: kas.PolicyRewrapResult.results:type_name -> kas.KeyAccessRewrapResult + 16, // 5: kas.RewrapResponse.metadata:type_name -> kas.RewrapResponse.MetadataEntry + 10, // 6: kas.RewrapResponse.responses:type_name -> kas.PolicyRewrapResult + 4, // 7: kas.UnsignedRewrapRequest.WithKeyAccessObject.key_access_object:type_name -> kas.KeyAccess + 13, // 8: kas.UnsignedRewrapRequest.WithPolicyRequest.key_access_objects:type_name -> kas.UnsignedRewrapRequest.WithKeyAccessObject + 12, // 9: kas.UnsignedRewrapRequest.WithPolicyRequest.policy:type_name -> kas.UnsignedRewrapRequest.WithPolicy + 17, // 10: kas.KeyAccessRewrapResult.MetadataEntry.value:type_name -> google.protobuf.Value + 17, // 11: kas.RewrapResponse.MetadataEntry.value:type_name -> google.protobuf.Value + 6, // 12: kas.AccessService.PublicKey:input_type -> kas.PublicKeyRequest + 2, // 13: kas.AccessService.LegacyPublicKey:input_type -> kas.LegacyPublicKeyRequest + 8, // 14: kas.AccessService.Rewrap:input_type -> kas.RewrapRequest + 7, // 15: kas.AccessService.PublicKey:output_type -> kas.PublicKeyResponse + 18, // 16: kas.AccessService.LegacyPublicKey:output_type -> google.protobuf.StringValue + 11, // 17: kas.AccessService.Rewrap:output_type -> kas.RewrapResponse + 15, // [15:18] is the sub-list for method output_type + 12, // [12:15] is the sub-list for method input_type + 12, // [12:12] is the sub-list for extension type_name + 12, // [12:12] is the sub-list for extension extendee + 0, // [0:12] is the sub-list for field type_name } func init() { file_kas_kas_proto_init() } diff --git a/sdk/kas_client.go b/sdk/kas_client.go index 8093d5055..8c685f25a 100644 --- a/sdk/kas_client.go +++ b/sdk/kas_client.go @@ -27,6 +27,9 @@ type KASClient struct { accessTokenSource auth.AccessTokenSource dialOptions []grpc.DialOption sessionKey ocrypto.KeyPair + + // Set this to enable legacy, non-batch rewrap requests + supportSingleRewrapEndpoint bool } type kaoResult struct { @@ -42,9 +45,10 @@ type decryptor interface { func newKASClient(dialOptions []grpc.DialOption, accessTokenSource auth.AccessTokenSource, sessionKey ocrypto.KeyPair) *KASClient { return &KASClient{ - accessTokenSource: accessTokenSource, - dialOptions: dialOptions, - sessionKey: sessionKey, + accessTokenSource: accessTokenSource, + dialOptions: dialOptions, + sessionKey: sessionKey, + supportSingleRewrapEndpoint: true, } } @@ -72,9 +76,38 @@ func (k *KASClient) makeRewrapRequest(ctx context.Context, requests []*kas.Unsig return nil, fmt.Errorf("error making rewrap request: %w", err) } + upgradeRewrapResponseV1(response, requests) + return response, nil } +// convert v1 responses to v2 +func upgradeRewrapResponseV1(response *kas.RewrapResponse, requests []*kas.UnsignedRewrapRequest_WithPolicyRequest) { + if len(response.GetResponses()) > 0 { + return + } + if len(response.GetEntityWrappedKey()) == 0 { //nolint:staticcheck // SA1019: use of deprecated method required for compatibility + return + } + if len(requests) == 0 { + return + } + response.Responses = []*kas.PolicyRewrapResult{ + { + PolicyId: requests[0].GetPolicy().GetId(), + Results: []*kas.KeyAccessRewrapResult{ + { + KeyAccessObjectId: requests[0].GetKeyAccessObjects()[0].GetKeyAccessObjectId(), + Status: statusPermit, + Result: &kas.KeyAccessRewrapResult_KasWrappedKey{ + KasWrappedKey: response.GetEntityWrappedKey(), //nolint:staticcheck // SA1019: use of deprecated method + }, + }, + }, + }, + } +} + func (k *KASClient) nanoUnwrap(ctx context.Context, requests ...*kas.UnsignedRewrapRequest_WithPolicyRequest) (map[string][]kaoResult, error) { keypair, err := ocrypto.NewECKeyPair(ocrypto.ECCModeSecp256r1) if err != nil { @@ -251,10 +284,18 @@ func getGRPCAddress(kasURL string) (string, error) { } func (k *KASClient) getRewrapRequest(reqs []*kas.UnsignedRewrapRequest_WithPolicyRequest, pubKey string) (*kas.RewrapRequest, error) { + if len(reqs) == 0 { + return nil, errors.New("no requests provided") + } requestBody := &kas.UnsignedRewrapRequest{ ClientPublicKey: pubKey, Requests: reqs, } + if len(reqs) == 1 && len(reqs[0].GetKeyAccessObjects()) == 1 && k.supportSingleRewrapEndpoint { + requestBody.KeyAccess = reqs[0].GetKeyAccessObjects()[0].GetKeyAccessObject() //nolint:staticcheck // SA1019: use of deprecated method + requestBody.Policy = reqs[0].GetPolicy().GetBody() //nolint:staticcheck // SA1019: use of deprecated method + requestBody.Algorithm = reqs[0].GetAlgorithm() //nolint:staticcheck // SA1019: use of deprecated method + } requestBodyJSON, err := protojson.Marshal(requestBody) if err != nil { diff --git a/sdk/kas_client_test.go b/sdk/kas_client_test.go index a45f32119..0431cc647 100644 --- a/sdk/kas_client_test.go +++ b/sdk/kas_client_test.go @@ -14,6 +14,7 @@ import ( "github.com/opentdf/platform/sdk/auth" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" "google.golang.org/grpc" "google.golang.org/protobuf/encoding/protojson" ) @@ -21,6 +22,7 @@ import ( type FakeAccessTokenSource struct { dpopKey jwk.Key asymDecryption ocrypto.AsymDecryption + asymEncryption ocrypto.AsymEncryption accessToken string } @@ -36,6 +38,8 @@ func getTokenSource(t *testing.T) FakeAccessTokenSource { dpopKey, _ := ocrypto.NewRSAKeyPair(2048) dpopPEM, _ := dpopKey.PrivateKeyInPemFormat() decryption, _ := ocrypto.NewAsymDecryption(dpopPEM) + dpopPEMPublic, _ := dpopKey.PublicKeyInPemFormat() + encryption, _ := ocrypto.NewAsymEncryption(dpopPEMPublic) dpopJWK, err := jwk.ParseKey([]byte(dpopPEM), jwk.WithPEM(true)) if err != nil { t.Fatalf("error creating JWK: %v", err) @@ -48,6 +52,7 @@ func getTokenSource(t *testing.T) FakeAccessTokenSource { return FakeAccessTokenSource{ dpopKey: dpopJWK, asymDecryption: decryption, + asymEncryption: encryption, accessToken: "thisistheaccesstoken", } } @@ -161,3 +166,51 @@ func Test_StoreKASKeys(t *testing.T) { assert.Nil(t, k2) require.ErrorContains(t, err, "error making request") } + +type TestUpgradeRewrapRequestV1Suite struct { + suite.Suite +} + +func (suite *TestUpgradeRewrapRequestV1Suite) TestUpgradeRewrapRequestV1_Happy() { + response := &kaspb.RewrapResponse{ + EntityWrappedKey: []byte("wrappedKey"), + } + requests := []*kaspb.UnsignedRewrapRequest_WithPolicyRequest{ + { + KeyAccessObjects: []*kaspb.UnsignedRewrapRequest_WithKeyAccessObject{ + { + KeyAccessObjectId: "kaoID", + }, + }, + Policy: &kaspb.UnsignedRewrapRequest_WithPolicy{ + Id: "policyID", + }, + }, + } + + upgradeRewrapResponseV1(response, requests) + + suite.Require().Len(response.GetResponses(), 1) + policyResult := response.GetResponses()[0] + suite.Equal("policyID", policyResult.GetPolicyId()) + + suite.Require().Len(policyResult.GetResults(), 1) + kaoResult := policyResult.GetResults()[0] + + suite.Equal("kaoID", kaoResult.GetKeyAccessObjectId()) + suite.NotNil(kaoResult.GetKasWrappedKey()) + suite.Empty(kaoResult.GetError()) +} + +func (suite *TestUpgradeRewrapRequestV1Suite) TestUpgradeRewrapRequestV1_Empty() { + response := &kaspb.RewrapResponse{} + requests := []*kaspb.UnsignedRewrapRequest_WithPolicyRequest{} + + upgradeRewrapResponseV1(response, requests) + + suite.EqualExportedValues(&kaspb.RewrapResponse{}, response) +} + +func TestUpgradeRewrapRequestV1(t *testing.T) { + suite.Run(t, new(TestUpgradeRewrapRequestV1Suite)) +} diff --git a/service/kas/access/rewrap.go b/service/kas/access/rewrap.go index 0819e9746..195872012 100644 --- a/service/kas/access/rewrap.go +++ b/service/kas/access/rewrap.go @@ -222,16 +222,20 @@ func extractSRTBody(ctx context.Context, headers http.Header, in *kaspb.RewrapRe } var requestBody kaspb.UnsignedRewrapRequest - err = protojson.Unmarshal([]byte(rbString), &requestBody) + err = protojson.UnmarshalOptions{DiscardUnknown: true}.Unmarshal([]byte(rbString), &requestBody) // if there are no requests then it could be a v1 request - if err != nil || len(requestBody.GetRequests()) == 0 { + if err != nil { + logger.WarnContext(ctx, "invalid SRT", "err.v2", err, "srt", rbString) + return nil, false, err400("invalid request body") + } + if len(requestBody.GetRequests()) == 0 { + logger.DebugContext(ctx, "legacy v1 SRT") var errv1 error - requestBody, errv1 = extractAndConvertV1SRTBody([]byte(rbString)) - if errv1 != nil { - logger.WarnContext(ctx, "invalid SRT", "err.v1", errv1, "err.v2", err) + + if requestBody, errv1 = extractAndConvertV1SRTBody([]byte(rbString)); errv1 != nil { + logger.WarnContext(ctx, "invalid SRT", "err.v1", errv1, "srt", rbString, "rewrap.body", requestBody.String()) return nil, false, err400("invalid request body") } - logger.DebugContext(ctx, "legacy v1 SRT", "err.v2", err) isV1 = true } logger.DebugContext(ctx, "extracted request body", slog.String("rewrap.body", requestBody.String()), slog.Any("rewrap.srt", rbString)) @@ -289,9 +293,15 @@ func verifyPolicyBinding(ctx context.Context, policy []byte, kao *kaspb.Unsigned func extractPolicyBinding(policyBinding interface{}) (string, error) { switch v := policyBinding.(type) { case string: + if v == "" { + return "", fmt.Errorf("empty policy binding") + } return v, nil case map[string]interface{}: if hash, ok := v["hash"].(string); ok { + if hash == "" { + return "", fmt.Errorf("empty policy binding hash field") + } return hash, nil } return "", fmt.Errorf("invalid policy binding object, missing 'hash' field") diff --git a/service/kas/kas.proto b/service/kas/kas.proto index 227d894d4..79642387d 100644 --- a/service/kas/kas.proto +++ b/service/kas/kas.proto @@ -33,7 +33,7 @@ message LegacyPublicKeyRequest { message PolicyBinding { string algorithm = 1 [json_name = "alg"]; - string hash = 2; + string hash = 2; } message KeyAccess { @@ -45,7 +45,7 @@ message KeyAccess { string kid = 6; string split_id = 7 [json_name = "sid"]; bytes wrapped_key = 8; - // header is only used for NanoTDFs + // header is only used for NanoTDFs bytes header = 9; // For wrapping with an ECDH derived key, when type=ec-wrapped @@ -70,6 +70,13 @@ message UnsignedRewrapRequest { string client_public_key = 1; repeated WithPolicyRequest requests = 2; + + // Used for legacy non-bulk requests + KeyAccess key_access = 3 [deprecated = true]; + // Used for legacy non-bulk requests + string policy = 4 [deprecated = true]; + // Used for legacy non-bulk requests + string algorithm = 5 [deprecated = true]; } message PublicKeyRequest { string algorithm = 1 [(grpc.gateway.protoc_gen_openapiv2.options.openapiv2_field) = {description: "algorithm type rsa: or ec:"}]; @@ -109,8 +116,8 @@ message RewrapResponse { bytes entity_wrapped_key = 2 [deprecated = true]; string session_public_key = 3; string schema_version = 4 [deprecated = true]; - // New Rewrap API changes - repeated PolicyRewrapResult responses = 5; + // New Rewrap API changes + repeated PolicyRewrapResult responses = 5; } // Get app info from the root path From 9ca042d65028214c3c06a1d86ddf3fe64f763e28 Mon Sep 17 00:00:00 2001 From: Cassandra Zimmerman Date: Thu, 20 Feb 2025 14:40:04 -0700 Subject: [PATCH 13/34] chore(main): update labels for repo metrics (#1929) ### Proposed Changes * the labels on the metrics we are pulling for the repos need to be updated, they are still the names of the old repos. this is making reporting confusing. this pr updates the labels to match the repos they are reporting about. ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions * you can trigger this workflow manually and view the json output to have the correct labels. --- .github/workflows/traffic.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/traffic.yaml b/.github/workflows/traffic.yaml index be8d858e2..97141c692 100644 --- a/.github/workflows/traffic.yaml +++ b/.github/workflows/traffic.yaml @@ -13,11 +13,10 @@ jobs: matrix: repo-values: - {repo: platform, event: ""} - - {repo: otdfctl, event: backend-} - - {repo: spec, event: frontend-} + - {repo: otdfctl, event: otdfctl-} + - {repo: spec, event: spec-} - {repo: tests, event: tests-} - - {repo: client-web, event: clientweb-} - - {repo: client-cpp, event: cpp-sdk-} + - {repo: web-sdk, event: web-sdk-} - {repo: java-sdk, event: java-sdk-} - {repo: charts, event: charts-} - {repo: nifi, event: nifi-} From 939c71603b1f12e8994632a5b3871d7ebbbaba37 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Mon, 24 Feb 2025 08:11:28 -0500 Subject: [PATCH 14/34] chore(ci): actionlint fix (#1932) ### Proposed Changes * This shouldn't matter, since go package names cannot contain spaces, but this fixes an issue where spaces in the release paths would cause the for loop to fail. ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions --- .github/workflows/release.yaml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b4d1bd25a..5746f129a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -30,7 +30,7 @@ jobs: - id: todo if: fromJson(steps.release-please.outputs.releases_created) run: | - for x in ${{join(fromJson(steps.release-please.outputs.paths_released), ' ')}}; do + <<<"$RELEASED_PATHS" jq -r '.[]'| while IFS= read -r x; do case "$x" in lib/ocrypto) echo "TO_UPDATE=['examples','sdk','service']">>"$GITHUB_OUTPUT" @@ -60,7 +60,8 @@ jobs: ;; esac done - + env: + RELEASED_PATHS: ${{ toJson(steps.release-please.outputs.paths_released) }} update-go-mods: runs-on: ubuntu-latest needs: @@ -78,15 +79,15 @@ jobs: - run: | git checkout -b update-go-mods-for-${{matrix.path}} git push -f -u origin update-go-mods-for-${{matrix.path}} - cd ${{matrix.path}} - for x in ${{join(fromJson(needs.release-please.outputs.paths_released), ' ')}}; do - export pkg=github.com/opentdf/platform/${x} + cd ${{matrix.path}} || exit 1 + <<<"$RELEASED_PATHS" jq -r '.[]'| while IFS= read -r x; do + export pkg="github.com/opentdf/platform/${x}" if go mod edit --json | jq -e '.Replace[] | select(.Old.Path == env.pkg)'; then - go mod edit --dropreplace=$pkg + go mod edit --dropreplace="$pkg" fi echo "Should we update [${pkg}] in [${{ matrix.path }}]?" if go mod edit --json | jq -e '.Require[] | select(.Path == env.pkg)'; then - ver=$(jq -r .\[\"${x}\"\] < "${GITHUB_WORKSPACE}/.release-please-manifest.json") + ver="$(jq -r --arg x "$x" '.[$x]' <"${GITHUB_WORKSPACE}"/.release-please-manifest.json)" echo "go get ${pkg}@v${ver}" go get "${pkg}@v${ver}" fi @@ -99,6 +100,7 @@ jobs: git diff env: GONOSUMDB: github.com/opentdf/platform/${{join(fromJson(needs.release-please.outputs.paths_released), ',github.com/opentdf/platform/')}} + RELEASED_PATHS: ${{ toJson(needs.release-please.outputs.paths_released) }} - uses: planetscale/ghcommit-action@d4176bfacef926cc2db351eab20398dfc2f593b5 with: commit_message: "fix(core): Autobump ${{ matrix.path }}" From aa3696d848a23ac79029bd64f1b61a15567204d7 Mon Sep 17 00:00:00 2001 From: Jake Van Vorhis <83739412+jakedoublev@users.noreply.github.com> Date: Tue, 25 Feb 2025 03:57:01 -0800 Subject: [PATCH 15/34] feat(sdk): sdk.New should validate platform connectivity and provide precise error (#1937) ### Proposed Changes * Validates healthy platform is available within `sdk.New` when triggered * Provides precise error if error connecting to provided `platformEndpoint` or status is unhealthy * Exposes validation function from SDK module for DX Resolves https://github.com/opentdf/platform/issues/1935 ### Checklist - [x] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions --- sdk/options.go | 46 +++++++++++++++++++++++++++------------------- sdk/sdk.go | 28 +++++++++++++++++++++++++++- sdk/sdk_test.go | 24 ++++++++++++++++-------- 3 files changed, 70 insertions(+), 28 deletions(-) diff --git a/sdk/options.go b/sdk/options.go index 42852c808..78d4f5ad7 100644 --- a/sdk/options.go +++ b/sdk/options.go @@ -20,25 +20,26 @@ type Option func(*config) // Internal config struct for building SDK options. type config struct { // Platform configuration structure is subject to change. Consume via accessor methods. - PlatformConfiguration PlatformConfiguration - dialOption grpc.DialOption - httpClient *http.Client - clientCredentials *oauth.ClientCredentials - tokenExchange *oauth.TokenExchangeInfo - tokenEndpoint string - scopes []string - extraDialOptions []grpc.DialOption - certExchange *oauth.CertExchangeInfo - kasSessionKey *ocrypto.RsaKeyPair - dpopKey *ocrypto.RsaKeyPair - ipc bool - tdfFeatures tdfFeatures - nanoFeatures nanoFeatures - customAccessTokenSource auth.AccessTokenSource - oauthAccessTokenSource oauth2.TokenSource - coreConn *grpc.ClientConn - entityResolutionConn *grpc.ClientConn - collectionStore *collectionStore + PlatformConfiguration PlatformConfiguration + dialOption grpc.DialOption + httpClient *http.Client + clientCredentials *oauth.ClientCredentials + tokenExchange *oauth.TokenExchangeInfo + tokenEndpoint string + scopes []string + extraDialOptions []grpc.DialOption + certExchange *oauth.CertExchangeInfo + kasSessionKey *ocrypto.RsaKeyPair + dpopKey *ocrypto.RsaKeyPair + ipc bool + tdfFeatures tdfFeatures + nanoFeatures nanoFeatures + customAccessTokenSource auth.AccessTokenSource + oauthAccessTokenSource oauth2.TokenSource + coreConn *grpc.ClientConn + entityResolutionConn *grpc.ClientConn + collectionStore *collectionStore + shouldValidatePlatformConnectivity bool } // Options specific to TDF protocol features @@ -195,6 +196,13 @@ func WithPlatformConfiguration(platformConfiguration PlatformConfiguration) Opti } } +// WithConnectionValidation will validate connection to a healthy, running platform +func WithConnectionValidation() Option { + return func(c *config) { + c.shouldValidatePlatformConnectivity = true + } +} + // WithIPC returns an Option that indicates the SDK should use IPC for communication // this will allow the platform endpoint to be an empty string func WithIPC() Option { diff --git a/sdk/sdk.go b/sdk/sdk.go index 944bb21e1..376ee6d37 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -32,6 +32,7 @@ import ( "github.com/xeipuuv/gojsonschema" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + healthpb "google.golang.org/grpc/health/grpc_health_v1" ) const ( @@ -39,6 +40,7 @@ const ( // Check your configuration and/or retry. ErrGrpcDialFailed = Error("failed to dial grpc endpoint") ErrShutdownFailed = Error("failed to shutdown sdk") + ErrPlatformUnreachable = Error("platform unreachable or not responding") ErrPlatformConfigFailed = Error("failed to retrieve platform configuration") ErrPlatformEndpointMalformed = Error("platform endpoint is malformed") ErrPlatformIssuerNotFound = Error("issuer not found in well-known idp configuration") @@ -112,12 +114,19 @@ func New(platformEndpoint string, opts ...Option) (*SDK, error) { dialOptions = append(dialOptions, cfg.extraDialOptions...) } - // IF IPC is disabled we build a connection to the platform + // IF IPC is disabled we build a validated healthy connection to the platform if !cfg.ipc { platformEndpoint, err = SanitizePlatformEndpoint(platformEndpoint) if err != nil { return nil, fmt.Errorf("%w [%v]: %w", ErrPlatformEndpointMalformed, platformEndpoint, err) } + + if cfg.shouldValidatePlatformConnectivity { + err = ValidateHealthyPlatformConnection(platformEndpoint, dialOptions) + if err != nil { + return nil, err + } + } } // If platformConfiguration is not provided, fetch it from the platform @@ -424,6 +433,23 @@ func fetchPlatformConfiguration(platformEndpoint string, dialOptions []grpc.Dial return getPlatformConfiguration(conn) } +// Test connectability to the platform and validate a healthy status +func ValidateHealthyPlatformConnection(platformEndpoint string, dialOptions []grpc.DialOption) error { + conn, err := grpc.NewClient(platformEndpoint, dialOptions...) + if err != nil { + return errors.Join(ErrGrpcDialFailed, err) + } + defer conn.Close() + + req := healthpb.HealthCheckRequest{} + healthService := healthpb.NewHealthClient(conn) + resp, err := healthService.Check(context.Background(), &req) + if err != nil || resp.GetStatus() != healthpb.HealthCheckResponse_SERVING { + return errors.Join(ErrPlatformUnreachable, err) + } + return nil +} + func getPlatformConfiguration(conn *grpc.ClientConn) (PlatformConfiguration, error) { req := wellknownconfiguration.GetWellKnownConfigurationRequest{} wellKnownConfig := wellknownconfiguration.NewWellKnownServiceClient(conn) diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index 177cb3391..f0d1d0fa3 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -254,14 +254,22 @@ func TestNew_ShouldHaveSameMethods(t *testing.T) { } } -func Test_ShouldCreateNewSDKWithBadEndpoint(t *testing.T) { - // Bad endpoints are not detected until the first call to the platform - t.Skip("Skipping test since this is expected but not great behavior") - // When - s, err := sdk.New(badPlatformEndpoint) - // Then - require.NoError(t, err) - assert.NotNil(t, s) +func Test_New_ShouldFailWithDisconnectedPlatform(t *testing.T) { + s, err := sdk.New(badPlatformEndpoint, + sdk.WithConnectionValidation(), + ) + require.ErrorIs(t, err, sdk.ErrPlatformUnreachable) + assert.Nil(t, s) + + // validates even with platform configuration provided + s, err = sdk.New(badPlatformEndpoint, + sdk.WithPlatformConfiguration(sdk.PlatformConfiguration{ + "platform_issuer": "https://example.org", + }), + sdk.WithConnectionValidation(), + ) + require.ErrorIs(t, err, sdk.ErrPlatformUnreachable) + assert.Nil(t, s) } func Test_ShouldSanitizePlatformEndpoint(t *testing.T) { From 4bb07a544ab4a4b0603533aa9efe2d6ea0e9b308 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 25 Feb 2025 09:01:27 -0500 Subject: [PATCH 16/34] chore(ci): Updates to golangci-lint 1.64 (#1934) ### Proposed Changes - Updates config to use latest recommended linters - Fixes new linter errors and warnings, most notably moving to the now standard `slices` package instead of the `exp` one ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions --- .github/workflows/checks.yaml | 2 +- .golangci.yaml | 6 ++---- Makefile | 4 ++-- README.md | 6 +++--- docs/Contributing.md | 1 + lib/ocrypto/asym_decryption.go | 6 +++--- .../entityresolution/keycloak/keycloak_entity_resolution.go | 3 +-- service/go.mod | 2 +- service/pkg/server/start.go | 2 +- 9 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index adac357ef..e380bbc7d 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -65,7 +65,7 @@ jobs: - name: golangci-lint uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 with: - version: v1.61 + version: v1.64 working-directory: ${{ matrix.directory }} skip-cache: true args: --out-format=colored-line-number diff --git a/.golangci.yaml b/.golangci.yaml index dac566eb3..33586547b 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -9,8 +9,6 @@ linters-settings: # Such cases aren't reported by default. # Default: false check-type-assertions: true - # https://github.com/golangci/golangci-lint/issues/4743 - ignore: '' exhaustive: # Program elements to check for exhaustiveness. @@ -138,7 +136,7 @@ linters: - errname # checks that sentinel errors are prefixed with the Err and error types are suffixed with the Error - errorlint # finds code that will cause problems with the error wrapping scheme introduced in Go 1.13 - exhaustive # checks exhaustiveness of enum switch statements - # - exportloopref # checks for pointers to enclosing loop variables Since Go1.22 (loopvar) this linter is no longer relevant. Replaced by copyloopvar." + - exptostd # Added in 1.63. Checks for usages of the deprecated experimental packages # - fatcontext - forbidigo # forbids identifiers - forcetypeassert # finds forced type assertions @@ -173,7 +171,6 @@ linters: # - spancheck # checks for incorrect usage of opentracing.Span # Added in golangci-lint 1.56 - sqlclosecheck # checks that sql.Rows and sql.Stmt are closed - stylecheck # is a replacement for golint - - tenv # detects using os.Setenv instead of t.Setenv since Go1.17 - testableexamples # checks if examples are testable (have an expected output) - testifylint #- testpackage # makes you use a separate _test package @@ -181,6 +178,7 @@ linters: - unconvert # removes unnecessary type conversions - unparam # reports unused function parameters - usestdlibvars # detects the possibility to use variables/constants from the Go standard library + - usetesting # Replaced tenv in golangci-lint 1.63 - wastedassign # finds wasted assignment statements - whitespace # detects leading and trailing whitespace diff --git a/Makefile b/Makefile index 223f9fa06..29f494b82 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,9 @@ all: toolcheck clean build lint license test toolcheck: @echo "Checking for required tools..." @which buf > /dev/null || (echo "buf not found, please install it from https://docs.buf.build/installation" && exit 1) - @which golangci-lint > /dev/null || (echo "golangci-lint not found, run 'go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0'" && exit 1) + @which golangci-lint > /dev/null || (echo "golangci-lint not found, run 'go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5'" && exit 1) @which protoc-gen-doc > /dev/null || (echo "protoc-gen-doc not found, run 'go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc@v1.5.1'" && exit 1) - @golangci-lint --version | grep "version v\?1.6[123]" > /dev/null || (echo "golangci-lint version must be v1.61 or later [$$(golangci-lint --version)]" && exit 1) + @golangci-lint --version | grep "version v\?1.6[456]" > /dev/null || (echo "golangci-lint version must be v1.64 or later [$$(golangci-lint --version)]" && exit 1) @which goimports >/dev/null || (echo "goimports not found, run 'go install golang.org/x/tools/cmd/goimports@latest'") fix: tidy fmt diff --git a/README.md b/README.md index b7fc62bc6..f158243d8 100644 --- a/README.md +++ b/README.md @@ -24,19 +24,19 @@ - [Podman Compose](https://github.com/containers/podman-compose) - [Buf](https://buf.build/docs/ecosystem/cli-overview) is used for managing protobuf files. Required for developing services. +- [golangci-lint](https://golangci-lint.run/) is used for ensuring good coding practices. + Use `make go-lint` to run it before submitting a PR On macOS, these can be installed with [brew](https://docs.brew.sh/Installation) ```sh -brew install buf go +brew install buf go golangci-lint ``` #### Optional tools - _Optional_ [Air](https://github.com/cosmtrek/air) is used for hot-reload development - install with `go install github.com/cosmtrek/air@latest` -- _Optional_ [golangci-lint](https://golangci-lint.run/) is used for ensuring good coding practices - - install with `brew install golangci-lint` - _Optional_ [grpcurl](https://github.com/fullstorydev/grpcurl) is used for testing gRPC services - install with `brew install grpcurl` - _Optional_ [openssl](https://www.openssl.org/) is used for generating certificates diff --git a/docs/Contributing.md b/docs/Contributing.md index 20ff43b37..378146dc7 100644 --- a/docs/Contributing.md +++ b/docs/Contributing.md @@ -27,4 +27,5 @@ Run `go run github.com/opentdf/platform/service provision fixtures -h` for more ## Advice for Code Contributors +* Make sure to run our linters with `make lint` * Follow our [Error Guidelines](./Contributing-errors.md) diff --git a/lib/ocrypto/asym_decryption.go b/lib/ocrypto/asym_decryption.go index 4744eb91a..1982b58dc 100644 --- a/lib/ocrypto/asym_decryption.go +++ b/lib/ocrypto/asym_decryption.go @@ -55,11 +55,11 @@ func FromPrivatePEM(privateKeyInPem string) (PrivateKeyDecryptor, error) { switch privateKey := priv.(type) { case *ecdsa.PrivateKey: - if sk, err := privateKey.ECDH(); err != nil { + sk, err := privateKey.ECDH() + if err != nil { return nil, fmt.Errorf("unable to create ECDH key: %w", err) - } else { - return NewECDecryptor(sk) } + return NewECDecryptor(sk) case *ecdh.PrivateKey: return NewECDecryptor(privateKey) case *rsa.PrivateKey: diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go index 14a5caf4e..f991ef2ed 100644 --- a/service/entityresolution/keycloak/keycloak_entity_resolution.go +++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go @@ -225,9 +225,8 @@ func EntityResolution(ctx context.Context, if exErr != nil { return entityresolution.ResolveEntitiesResponse{}, connect.NewError(connect.CodeNotFound, ErrNotFound) - } else { - keycloakEntities = expandedRepresentations } + keycloakEntities = expandedRepresentations default: logger.Error("no group found for", slog.String("entity", ident.String())) var entityNotFoundErr entityresolution.EntityNotFoundError diff --git a/service/go.mod b/service/go.mod index c8a1c6a2a..c33659dac 100644 --- a/service/go.mod +++ b/service/go.mod @@ -36,7 +36,6 @@ require ( go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 go.opentelemetry.io/otel/sdk v1.31.0 go.opentelemetry.io/otel/trace v1.31.0 - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 gopkg.in/natefinch/lumberjack.v2 v2.2.1 @@ -78,6 +77,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect go.opentelemetry.io/otel/metric v1.31.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect golang.org/x/oauth2 v0.22.0 // indirect ) diff --git a/service/pkg/server/start.go b/service/pkg/server/start.go index 92c7b49ea..9247ea49c 100644 --- a/service/pkg/server/start.go +++ b/service/pkg/server/start.go @@ -10,6 +10,7 @@ import ( "net/url" "os" "os/signal" + "slices" "syscall" "github.com/opentdf/platform/lib/ocrypto" @@ -23,7 +24,6 @@ import ( "github.com/opentdf/platform/service/pkg/serviceregistry" "github.com/opentdf/platform/service/tracing" wellknown "github.com/opentdf/platform/service/wellknownconfiguration" - "golang.org/x/exp/slices" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" From 35e25cc6536eeaf722152164240c60d22d492f48 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 15:54:33 +0000 Subject: [PATCH 17/34] chore(main): release lib/ocrypto 0.1.8 (#1795) :robot: I have created a release *beep* *boop* --- ## [0.1.8](https://github.com/opentdf/platform/compare/lib/ocrypto/v0.1.7...lib/ocrypto/v0.1.8) (2025-02-25) ### Features * **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) * **kas:** collect metrics ([#1702](https://github.com/opentdf/platform/issues/1702)) ([def28d1](https://github.com/opentdf/platform/commit/def28d1984b0b111a07330a3eb59c1285206062d)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com> Co-authored-by: Jake Van Vorhis <83739412+jakedoublev@users.noreply.github.com> --- .release-please-manifest.json | 2 +- lib/ocrypto/CHANGELOG.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 27439d625..72f45def4 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,6 +1,6 @@ { "lib/fixtures": "0.2.10", - "lib/ocrypto": "0.1.7", + "lib/ocrypto": "0.1.8", "lib/flattening": "0.1.3", "protocol/go": "0.2.26", "sdk": "0.3.26", diff --git a/lib/ocrypto/CHANGELOG.md b/lib/ocrypto/CHANGELOG.md index d9dfca584..ae8a91d5e 100644 --- a/lib/ocrypto/CHANGELOG.md +++ b/lib/ocrypto/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.1.8](https://github.com/opentdf/platform/compare/lib/ocrypto/v0.1.7...lib/ocrypto/v0.1.8) (2025-02-25) + + +### Features + +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) +* **kas:** collect metrics ([#1702](https://github.com/opentdf/platform/issues/1702)) ([def28d1](https://github.com/opentdf/platform/commit/def28d1984b0b111a07330a3eb59c1285206062d)) + ## [0.1.7](https://github.com/opentdf/platform/compare/lib/ocrypto/v0.1.6...lib/ocrypto/v0.1.7) (2024-11-15) From 53fa8ab90236d5bd29541552782b60b96f625405 Mon Sep 17 00:00:00 2001 From: Jake Van Vorhis <83739412+jakedoublev@users.noreply.github.com> Date: Tue, 25 Feb 2025 09:06:15 -0800 Subject: [PATCH 18/34] fix(sdk): bump lib/ocrypto to 0.1.8 (#1938) ### Proposed Changes * CI pipeline failed to bump `lib/ocrypto` in `sdk` when recently released: https://github.com/opentdf/platform/actions/runs/13525675363/job/37796239649 ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions --- sdk/go.mod | 2 +- sdk/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/go.mod b/sdk/go.mod index d3115010c..6e6320595 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -8,7 +8,7 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 github.com/lestrrat-go/jwx/v2 v2.0.21 github.com/opentdf/platform/lib/fixtures v0.2.10 - github.com/opentdf/platform/lib/ocrypto v0.1.7 + github.com/opentdf/platform/lib/ocrypto v0.1.8 github.com/opentdf/platform/protocol/go v0.2.26 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.32.0 diff --git a/sdk/go.sum b/sdk/go.sum index daff7dde6..069c49a7a 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -114,8 +114,8 @@ github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQ github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXvCTb+nJCuiU2WsWs= github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= -github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= -github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= +github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= +github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= github.com/opentdf/platform/protocol/go v0.2.26 h1:22ugJFhAjlz7BRAky3eBljIQrsLzmsdkKVM+pjuG09k= github.com/opentdf/platform/protocol/go v0.2.26/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= From 496829cf8f47469847fc08ef9c89c10964b1fb95 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Tue, 25 Feb 2025 12:31:12 -0500 Subject: [PATCH 19/34] chore(ci): Fixes release path double-escaping (#1939) - This is already escaped (as evidenced by the existing calls to fromJSON elsewhere) - from [the doc](https://github.com/googleapis/release-please-action?tab=readme-ov-file#outputs): > `paths_released`: A JSON string of the array of paths that had releases created ([] if ) ### Proposed Changes * ### Checklist - [ ] I have added or updated unit tests - [ ] I have added or updated integration tests (if appropriate) - [ ] I have added or updated documentation ### Testing Instructions --- .github/workflows/release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 5746f129a..966881029 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -61,7 +61,7 @@ jobs: esac done env: - RELEASED_PATHS: ${{ toJson(steps.release-please.outputs.paths_released) }} + RELEASED_PATHS: ${{ steps.release-please.outputs.paths_released }} update-go-mods: runs-on: ubuntu-latest needs: @@ -100,7 +100,7 @@ jobs: git diff env: GONOSUMDB: github.com/opentdf/platform/${{join(fromJson(needs.release-please.outputs.paths_released), ',github.com/opentdf/platform/')}} - RELEASED_PATHS: ${{ toJson(needs.release-please.outputs.paths_released) }} + RELEASED_PATHS: ${{ needs.release-please.outputs.paths_released }} - uses: planetscale/ghcommit-action@d4176bfacef926cc2db351eab20398dfc2f593b5 with: commit_message: "fix(core): Autobump ${{ matrix.path }}" From c693b27d339e77dbc3fdb44ee057c12e1f552987 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 18:02:59 +0000 Subject: [PATCH 20/34] chore(main): release protocol/go 0.2.27 (#1920) :robot: I have created a release *beep* *boop* --- ## [0.2.27](https://github.com/opentdf/platform/compare/protocol/go/v0.2.26...protocol/go/v0.2.27) (2025-02-25) ### Features * **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) ### Bug Fixes * **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com> Co-authored-by: Jake Van Vorhis <83739412+jakedoublev@users.noreply.github.com> --- .release-please-manifest.json | 2 +- protocol/go/CHANGELOG.md | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 72f45def4..61ee16bba 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -2,7 +2,7 @@ "lib/fixtures": "0.2.10", "lib/ocrypto": "0.1.8", "lib/flattening": "0.1.3", - "protocol/go": "0.2.26", + "protocol/go": "0.2.27", "sdk": "0.3.26", "service": "0.4.38" } diff --git a/protocol/go/CHANGELOG.md b/protocol/go/CHANGELOG.md index fd49adf11..40d1f59ca 100644 --- a/protocol/go/CHANGELOG.md +++ b/protocol/go/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [0.2.27](https://github.com/opentdf/platform/compare/protocol/go/v0.2.26...protocol/go/v0.2.27) (2025-02-25) + + +### Features + +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) + + +### Bug Fixes + +* **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) + ## [0.2.26](https://github.com/opentdf/platform/compare/protocol/go/v0.2.25...protocol/go/v0.2.26) (2025-02-14) From 0a5a94893836482990586302bfb9838e54c5b6ba Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 13:48:38 -0500 Subject: [PATCH 21/34] fix(core): Autobump sdk (#1941) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- sdk/go.mod | 2 +- sdk/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/go.mod b/sdk/go.mod index 6e6320595..28d42e6e1 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -9,7 +9,7 @@ require ( github.com/lestrrat-go/jwx/v2 v2.0.21 github.com/opentdf/platform/lib/fixtures v0.2.10 github.com/opentdf/platform/lib/ocrypto v0.1.8 - github.com/opentdf/platform/protocol/go v0.2.26 + github.com/opentdf/platform/protocol/go v0.2.27 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.32.0 github.com/xeipuuv/gojsonschema v1.2.0 diff --git a/sdk/go.sum b/sdk/go.sum index 069c49a7a..cad1766f9 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -116,8 +116,8 @@ github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXv github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= -github.com/opentdf/platform/protocol/go v0.2.26 h1:22ugJFhAjlz7BRAky3eBljIQrsLzmsdkKVM+pjuG09k= -github.com/opentdf/platform/protocol/go v0.2.26/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/protocol/go v0.2.27 h1:ZnfXvVio+j/LzfEY8cHo8/tS45XAPWa2xO7Y1tn/hWs= +github.com/opentdf/platform/protocol/go v0.2.27/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= From a3fdf22cb0112fc9c0c60f5551f802a4010c7e77 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 15:19:37 -0500 Subject: [PATCH 22/34] chore(main): release sdk 0.3.27 (#1868) :robot: I have created a release *beep* *boop* --- ## [0.3.27](https://github.com/opentdf/platform/compare/sdk/v0.3.26...sdk/v0.3.27) (2025-02-25) ### Features * **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) * **policy:** adds new public keys table ([#1836](https://github.com/opentdf/platform/issues/1836)) ([cad5048](https://github.com/opentdf/platform/commit/cad5048d09609d678d5b5ac2972605dd61f33bb5)) * **sdk:** Allow schema validation during TDF decrypt ([#1870](https://github.com/opentdf/platform/issues/1870)) ([b7e6fb2](https://github.com/opentdf/platform/commit/b7e6fb24631b4898561b1a64c24c85b32c452a1c)) * **sdk:** MIC-1436: User can decrypt TDF files created with FileWatcher2.0.8 and older. ([#1833](https://github.com/opentdf/platform/issues/1833)) ([f77d110](https://github.com/opentdf/platform/commit/f77d110fcc7f332ceec5a3294b144973eced37c1)) * **sdk:** remove hex encoding for segment hash ([#1805](https://github.com/opentdf/platform/issues/1805)) ([d7179c2](https://github.com/opentdf/platform/commit/d7179c2a91b508c26fbe6499fe5c1ac8334e5505)) * **sdk:** sdk.New should validate platform connectivity and provide precise error ([#1937](https://github.com/opentdf/platform/issues/1937)) ([aa3696d](https://github.com/opentdf/platform/commit/aa3696d848a23ac79029bd64f1b61a15567204d7)) ### Bug Fixes * **core:** Autobump sdk ([#1873](https://github.com/opentdf/platform/issues/1873)) ([085ac7a](https://github.com/opentdf/platform/commit/085ac7af550d2c9d3fd0b0b2deb389939e7cde8e)) * **core:** Autobump sdk ([#1894](https://github.com/opentdf/platform/issues/1894)) ([201244e](https://github.com/opentdf/platform/commit/201244e4473115f07fc997dc49c695cc05d9a6ba)) * **core:** Autobump sdk ([#1917](https://github.com/opentdf/platform/issues/1917)) ([edeeb74](https://github.com/opentdf/platform/commit/edeeb74e9c38b2e6eef7fefa29768912371ec949)) * **core:** Autobump sdk ([#1941](https://github.com/opentdf/platform/issues/1941)) ([0a5a948](https://github.com/opentdf/platform/commit/0a5a94893836482990586302bfb9838e54c5b6ba)) * Improve http.Client usage for security and performance ([#1910](https://github.com/opentdf/platform/issues/1910)) ([e6a53a3](https://github.com/opentdf/platform/commit/e6a53a370b13c3ed63752789aa886be660354e1a)) * **sdk:** bump lib/ocrypto to 0.1.8 ([#1938](https://github.com/opentdf/platform/issues/1938)) ([53fa8ab](https://github.com/opentdf/platform/commit/53fa8ab90236d5bd29541552782b60b96f625405)) * **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) * **sdk:** Removes unnecessary down-cast of `int` ([#1869](https://github.com/opentdf/platform/issues/1869)) ([66f0c14](https://github.com/opentdf/platform/commit/66f0c14a1ef7490a207c0cef8c98ab4af3f128b1)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- sdk/CHANGELOG.md | 24 ++++++++++++++++++++++++ sdk/version.go | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 61ee16bba..658403917 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -3,6 +3,6 @@ "lib/ocrypto": "0.1.8", "lib/flattening": "0.1.3", "protocol/go": "0.2.27", - "sdk": "0.3.26", + "sdk": "0.3.27", "service": "0.4.38" } diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md index 40e6175c6..17dabc263 100644 --- a/sdk/CHANGELOG.md +++ b/sdk/CHANGELOG.md @@ -1,5 +1,29 @@ # Changelog +## [0.3.27](https://github.com/opentdf/platform/compare/sdk/v0.3.26...sdk/v0.3.27) (2025-02-25) + + +### Features + +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) +* **policy:** adds new public keys table ([#1836](https://github.com/opentdf/platform/issues/1836)) ([cad5048](https://github.com/opentdf/platform/commit/cad5048d09609d678d5b5ac2972605dd61f33bb5)) +* **sdk:** Allow schema validation during TDF decrypt ([#1870](https://github.com/opentdf/platform/issues/1870)) ([b7e6fb2](https://github.com/opentdf/platform/commit/b7e6fb24631b4898561b1a64c24c85b32c452a1c)) +* **sdk:** MIC-1436: User can decrypt TDF files created with FileWatcher2.0.8 and older. ([#1833](https://github.com/opentdf/platform/issues/1833)) ([f77d110](https://github.com/opentdf/platform/commit/f77d110fcc7f332ceec5a3294b144973eced37c1)) +* **sdk:** remove hex encoding for segment hash ([#1805](https://github.com/opentdf/platform/issues/1805)) ([d7179c2](https://github.com/opentdf/platform/commit/d7179c2a91b508c26fbe6499fe5c1ac8334e5505)) +* **sdk:** sdk.New should validate platform connectivity and provide precise error ([#1937](https://github.com/opentdf/platform/issues/1937)) ([aa3696d](https://github.com/opentdf/platform/commit/aa3696d848a23ac79029bd64f1b61a15567204d7)) + + +### Bug Fixes + +* **core:** Autobump sdk ([#1873](https://github.com/opentdf/platform/issues/1873)) ([085ac7a](https://github.com/opentdf/platform/commit/085ac7af550d2c9d3fd0b0b2deb389939e7cde8e)) +* **core:** Autobump sdk ([#1894](https://github.com/opentdf/platform/issues/1894)) ([201244e](https://github.com/opentdf/platform/commit/201244e4473115f07fc997dc49c695cc05d9a6ba)) +* **core:** Autobump sdk ([#1917](https://github.com/opentdf/platform/issues/1917)) ([edeeb74](https://github.com/opentdf/platform/commit/edeeb74e9c38b2e6eef7fefa29768912371ec949)) +* **core:** Autobump sdk ([#1941](https://github.com/opentdf/platform/issues/1941)) ([0a5a948](https://github.com/opentdf/platform/commit/0a5a94893836482990586302bfb9838e54c5b6ba)) +* Improve http.Client usage for security and performance ([#1910](https://github.com/opentdf/platform/issues/1910)) ([e6a53a3](https://github.com/opentdf/platform/commit/e6a53a370b13c3ed63752789aa886be660354e1a)) +* **sdk:** bump lib/ocrypto to 0.1.8 ([#1938](https://github.com/opentdf/platform/issues/1938)) ([53fa8ab](https://github.com/opentdf/platform/commit/53fa8ab90236d5bd29541552782b60b96f625405)) +* **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) +* **sdk:** Removes unnecessary down-cast of `int` ([#1869](https://github.com/opentdf/platform/issues/1869)) ([66f0c14](https://github.com/opentdf/platform/commit/66f0c14a1ef7490a207c0cef8c98ab4af3f128b1)) + ## [0.3.26](https://github.com/opentdf/platform/compare/sdk/v0.3.25...sdk/v0.3.26) (2025-01-21) diff --git a/sdk/version.go b/sdk/version.go index 8a168ba19..fce62d770 100644 --- a/sdk/version.go +++ b/sdk/version.go @@ -7,5 +7,5 @@ const ( TDFSpecVersion = "4.3.0" // The three-part semantic version number of this SDK - Version = "0.3.26" // x-release-please-version + Version = "0.3.27" // x-release-please-version ) From ce7bc64a2a9827b4c14eff6663dccb007acb62c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:10:55 +0000 Subject: [PATCH 23/34] chore(ci): bump golangci/golangci-lint-action from 6.1.1 to 6.5.0 (#1931) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6.1.1 to 6.5.0.
Release notes

Sourced from golangci/golangci-lint-action's releases.

v6.5.0

What's Changed

Changes

Dependencies

Full Changelog: https://github.com/golangci/golangci-lint-action/compare/v6.4.1...v6.5.0

v6.4.1

What's Changed

Changes

Full Changelog: https://github.com/golangci/golangci-lint-action/compare/v6.4.0...v6.4.1

v6.4.0

What's Changed

Changes

Full Changelog: https://github.com/golangci/golangci-lint-action/compare/v6.3.3...v6.4.0

v6.3.3

What's Changed

Changes

Full Changelog: https://github.com/golangci/golangci-lint-action/compare/v6.3.2...v6.3.3

v6.3.2

What's Changed

Changes

... (truncated)

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=golangci/golangci-lint-action&package-manager=github_actions&previous-version=6.1.1&new-version=6.5.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dave Mihalcik --- .github/workflows/checks.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/checks.yaml b/.github/workflows/checks.yaml index e380bbc7d..a1eb120ec 100644 --- a/.github/workflows/checks.yaml +++ b/.github/workflows/checks.yaml @@ -63,7 +63,7 @@ jobs: if: env.IS_RELEASE_BRANCH == 'true' working-directory: ${{ matrix.directory }} - name: golangci-lint - uses: golangci/golangci-lint-action@971e284b6050e8a5849b72094c50ab08da042db8 + uses: golangci/golangci-lint-action@2226d7cb06a077cd73e56eedd38eecad18e5d837 with: version: v1.64 working-directory: ${{ matrix.directory }} From d2e37ca081d04f4588c58b752b0c96ef9b0125cb Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:12:12 +0000 Subject: [PATCH 24/34] fix(core): Autobump service (#1945) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- service/go.mod | 6 +++--- service/go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/service/go.mod b/service/go.mod index c33659dac..07f0c266d 100644 --- a/service/go.mod +++ b/service/go.mod @@ -24,9 +24,9 @@ require ( github.com/open-policy-agent/opa v0.68.0 github.com/opentdf/platform/lib/fixtures v0.2.10 github.com/opentdf/platform/lib/flattening v0.1.3 - github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.26 - github.com/opentdf/platform/sdk v0.3.26 + github.com/opentdf/platform/lib/ocrypto v0.1.8 + github.com/opentdf/platform/protocol/go v0.2.27 + github.com/opentdf/platform/sdk v0.3.27 github.com/pressly/goose/v3 v3.19.1 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.18.2 diff --git a/service/go.sum b/service/go.sum index 6bf197419..0181f6b5b 100644 --- a/service/go.sum +++ b/service/go.sum @@ -277,12 +277,12 @@ github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXv github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= github.com/opentdf/platform/lib/flattening v0.1.3 h1:IuOm/wJVXNrzOV676Ticgr0wyBkL+lVjsoSfh+WSkNo= github.com/opentdf/platform/lib/flattening v0.1.3/go.mod h1:Gs/T+6FGZKk9OAdz2Jf1R8CTGeNRYrq1lZGDeYT3hrY= -github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= -github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.26 h1:22ugJFhAjlz7BRAky3eBljIQrsLzmsdkKVM+pjuG09k= -github.com/opentdf/platform/protocol/go v0.2.26/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= -github.com/opentdf/platform/sdk v0.3.26 h1:cXNQsLd7Ef2Nq6HJ/L+4tvdJ+Op42vplkA6C53rcPW8= -github.com/opentdf/platform/sdk v0.3.26/go.mod h1:rw/4l0qfhkhD9bdwqhXARV2CSpV+18m7Ks1wPRGLzkI= +github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= +github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= +github.com/opentdf/platform/protocol/go v0.2.27 h1:ZnfXvVio+j/LzfEY8cHo8/tS45XAPWa2xO7Y1tn/hWs= +github.com/opentdf/platform/protocol/go v0.2.27/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/sdk v0.3.27 h1:O9jCdpnxz3FEaTXj/hAOixR5mk/APsalcWCexGxfwkM= +github.com/opentdf/platform/sdk v0.3.27/go.mod h1:ZJyz6hy0CMiD3MFfG4PrByTnSJnEtArTGA6ZoR1Xg6E= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= From 752447214fdee6e463b1e27199333f25f2aee514 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 21:14:24 +0000 Subject: [PATCH 25/34] chore(ci): bump actions/stale from 9.0.0 to 9.1.0 (#1896) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/stale](https://github.com/actions/stale) from 9.0.0 to 9.1.0.
Release notes

Sourced from actions/stale's releases.

v9.1.0

What's Changed

New Contributors

Full Changelog: https://github.com/actions/stale/compare/v9...v9.1.0

Commits
  • 5bef64f build(deps): bump @​actions/cache from 3.2.2 to 4.0.0 (#1194)
  • fa77dfd build(deps-dev): bump @​types/jest from 29.5.11 to 29.5.14 (#1193)
  • f04443d build(deps): bump @​actions/core from 1.10.1 to 1.11.1 (#1191)
  • 5c715b0 build(deps-dev): bump ts-jest from 29.1.1 to 29.2.5 (#1175)
  • f691222 build(deps): bump actions/publish-action from 0.2.2 to 0.3.0 (#1147)
  • df990c2 build(deps): bump actions/checkout from 3 to 4 (#1091)
  • 6e472ce Merge pull request #1179 from actions/Jcambass-patch-1
  • d10ba64 Merge pull request #1150 from actions/dependabot/npm_and_yarn/undici-5.28.4
  • bbf3da5 resolve check failures
  • 6a2e61d Add workflow file for publishing releases to immutable action package
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/stale&package-manager=github_actions&previous-version=9.0.0&new-version=9.1.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dave Mihalcik --- .github/workflows/stale.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index 9fe2a94a5..a29690528 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -10,7 +10,7 @@ jobs: pull-requests: write runs-on: ubuntu-latest steps: - - uses: actions/stale@28ca1036281a5e5922ead5184a1bbf96e5fc984e + - uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 with: days-before-stale: 120 # negative number means they will never be closed automatically [https://github.com/actions/stale#days-before-close] From 5b16ed7646253ee2f81abfb13d849bf8e3be436a Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:56:53 -0500 Subject: [PATCH 26/34] fix(core): Autobump examples (#1944) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- examples/go.mod | 6 +++--- examples/go.sum | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/examples/go.mod b/examples/go.mod index 1a4260a0c..bff25077c 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -3,9 +3,9 @@ module github.com/opentdf/platform/examples go 1.21 require ( - github.com/opentdf/platform/lib/ocrypto v0.1.7 - github.com/opentdf/platform/protocol/go v0.2.26 - github.com/opentdf/platform/sdk v0.3.23 + github.com/opentdf/platform/lib/ocrypto v0.1.8 + github.com/opentdf/platform/protocol/go v0.2.27 + github.com/opentdf/platform/sdk v0.3.27 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 google.golang.org/grpc v1.66.0 diff --git a/examples/go.sum b/examples/go.sum index 438ed4cf2..ce825598a 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -105,14 +105,14 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM= -github.com/opentdf/platform/lib/fixtures v0.2.8 h1:lGYrMnbORtU62lxsJi8qPsxjFuNIkc4Dop8rVkH6pD0= -github.com/opentdf/platform/lib/fixtures v0.2.8/go.mod h1:8yCSe+oUzW9jbM573r9qgE68rjwDMNzktObiGVsO/W8= -github.com/opentdf/platform/lib/ocrypto v0.1.7 h1:IcCYRrwmMqntqUE8frmUDg5EZ0WMdldpGeGhbv9+/A8= -github.com/opentdf/platform/lib/ocrypto v0.1.7/go.mod h1:4bhKPbRFzURMerH5Vr/LlszHvcoXQbfJXa0bpY7/7yg= -github.com/opentdf/platform/protocol/go v0.2.26 h1:22ugJFhAjlz7BRAky3eBljIQrsLzmsdkKVM+pjuG09k= -github.com/opentdf/platform/protocol/go v0.2.26/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= -github.com/opentdf/platform/sdk v0.3.23 h1:lTjWiqCGcA1fvMNOMUPIiOl8FNNQTaEK/+xyGvpbMZs= -github.com/opentdf/platform/sdk v0.3.23/go.mod h1:KpT/m5zXQ19WqhGePKfIC39Ly8LOipKdKGbJ1B/59a8= +github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXvCTb+nJCuiU2WsWs= +github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= +github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= +github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= +github.com/opentdf/platform/protocol/go v0.2.27 h1:ZnfXvVio+j/LzfEY8cHo8/tS45XAPWa2xO7Y1tn/hWs= +github.com/opentdf/platform/protocol/go v0.2.27/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/sdk v0.3.27 h1:O9jCdpnxz3FEaTXj/hAOixR5mk/APsalcWCexGxfwkM= +github.com/opentdf/platform/sdk v0.3.27/go.mod h1:ZJyz6hy0CMiD3MFfG4PrByTnSJnEtArTGA6ZoR1Xg6E= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= From 9438268b47fab6a4c0fa93df734283c2c1e3e05d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 25 Feb 2025 16:57:23 -0500 Subject: [PATCH 27/34] chore(ci): bump actions/create-github-app-token from 1.11.0 to 1.11.5 (#1930) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 1.11.0 to 1.11.5.
Release notes

Sourced from actions/create-github-app-token's releases.

v1.11.5

1.11.5 (2025-02-15)

Bug Fixes

v1.11.4

1.11.4 (2025-02-15)

Bug Fixes

v1.11.3

1.11.3 (2025-02-04)

Bug Fixes

v1.11.2

1.11.2 (2025-01-30)

Bug Fixes

v1.11.1

What's Changed

Bug Fixes

Full Changelog: https://github.com/actions/create-github-app-token/compare/v1.11.0...v1.11.1

Commits
  • 0d56448 build(release): 1.11.5 [skip ci]
  • 8cedd97 fix(deps): bump @​octokit/request from 9.2.0 to 9.2.2 (#209)
  • 415f6a5 fix(deps): bump @​octokit/request-error from 6.1.6 to 6.1.7 (#208)
  • c14f92a build(release): 1.11.4 [skip ci]
  • d30def8 fix(deps): bump @​octokit/endpoint from 10.1.1 to 10.1.3 (#207)
  • a5be472 build(deps-dev): bump esbuild from 0.24.2 to 0.25.0 (#206)
  • 67e27a7 build(release): 1.11.3 [skip ci]
  • 8e85a3c fix(deps): bump the production-dependencies group with 3 updates (#203)
  • 136412a build(release): 1.11.2 [skip ci]
  • b4192a5 fix(deps): bump @​octokit/request from 9.1.3 to 9.1.4 in the production-depend...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/create-github-app-token&package-manager=github_actions&previous-version=1.11.0&new-version=1.11.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dave Mihalcik --- .github/workflows/release.yaml | 4 ++-- .github/workflows/traffic.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 966881029..c4b3cf7ee 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -17,7 +17,7 @@ jobs: steps: - name: Generate a token id: generate_token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 with: app-id: "${{ secrets.APP_ID }}" private-key: "${{ secrets.AUTOMATION_KEY }}" @@ -110,7 +110,7 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate a token id: generate_token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 with: app-id: "${{ secrets.APP_ID }}" private-key: "${{ secrets.AUTOMATION_KEY }}" diff --git a/.github/workflows/traffic.yaml b/.github/workflows/traffic.yaml index 97141c692..b666f5c75 100644 --- a/.github/workflows/traffic.yaml +++ b/.github/workflows/traffic.yaml @@ -23,7 +23,7 @@ jobs: steps: - name: Generate a token id: generate_token - uses: actions/create-github-app-token@5d869da34e18e7287c1daad50e0b8ea0f506ce69 # v1.11.0 + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # v1.11.5 with: app-id: "${{ secrets.APP_ID }}" private-key: "${{ secrets.AUTOMATION_KEY }}" From 9bebfd01f615f5a438e0695c03dbb1a9ad7badf3 Mon Sep 17 00:00:00 2001 From: Dave Mihalcik Date: Wed, 26 Feb 2025 13:10:43 -0500 Subject: [PATCH 28/34] fix(core): Fixes protoJSON parse bug on ec rewrap (#1943) - protoJSON encodes/decodes `bytes` types as base64 for us. So good for the wrapped key (ciphertext value), but bad or at least not right for PEM encoded string values. --- docs/grpc/index.html | 5 +++-- protocol/go/kas/kas.pb.go | 11 ++++++----- sample.tdf | Bin 0 -> 1529 bytes sdk/tdf.go | 2 +- service/kas/access/rewrap.go | 6 +++--- service/kas/kas.proto | 5 +++-- 6 files changed, 16 insertions(+), 13 deletions(-) create mode 100644 sample.tdf diff --git a/docs/grpc/index.html b/docs/grpc/index.html index 99bd9b661..bffbf1f5d 100644 --- a/docs/grpc/index.html +++ b/docs/grpc/index.html @@ -3559,9 +3559,10 @@

KeyAccess

ephemeral_public_key - bytes + string -

For wrapping with an ECDH derived key, when type=ec-wrapped

+

For wrapping with an ECDH derived key, when type=ec-wrapped. +Should be a PEM-encoded PKCS#8 (asn.1) value.

diff --git a/protocol/go/kas/kas.pb.go b/protocol/go/kas/kas.pb.go index c1052bf36..cd41a7c29 100644 --- a/protocol/go/kas/kas.pb.go +++ b/protocol/go/kas/kas.pb.go @@ -227,8 +227,9 @@ type KeyAccess struct { WrappedKey []byte `protobuf:"bytes,8,opt,name=wrapped_key,json=wrappedKey,proto3" json:"wrapped_key,omitempty"` // header is only used for NanoTDFs Header []byte `protobuf:"bytes,9,opt,name=header,proto3" json:"header,omitempty"` - // For wrapping with an ECDH derived key, when type=ec-wrapped - EphemeralPublicKey []byte `protobuf:"bytes,10,opt,name=ephemeral_public_key,json=ephemeralPublicKey,proto3" json:"ephemeral_public_key,omitempty"` + // For wrapping with an ECDH derived key, when type=ec-wrapped. + // Should be a PEM-encoded PKCS#8 (asn.1) value. + EphemeralPublicKey string `protobuf:"bytes,10,opt,name=ephemeral_public_key,json=ephemeralPublicKey,proto3" json:"ephemeral_public_key,omitempty"` } func (x *KeyAccess) Reset() { @@ -326,11 +327,11 @@ func (x *KeyAccess) GetHeader() []byte { return nil } -func (x *KeyAccess) GetEphemeralPublicKey() []byte { +func (x *KeyAccess) GetEphemeralPublicKey() string { if x != nil { return x.EphemeralPublicKey } - return nil + return "" } type UnsignedRewrapRequest struct { @@ -1051,7 +1052,7 @@ var file_kas_kas_proto_rawDesc = []byte{ 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x64, 0x4b, 0x65, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x30, 0x0a, 0x14, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x5f, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x65, 0x70, 0x68, 0x65, 0x6d, 0x65, 0x72, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x22, 0x86, 0x05, 0x0a, 0x15, 0x55, 0x6e, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x64, 0x52, 0x65, 0x77, 0x72, 0x61, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, diff --git a/sample.tdf b/sample.tdf new file mode 100644 index 0000000000000000000000000000000000000000..556f6c0adc6ade1e978ee9dbffc5741ce5a260b6 GIT binary patch literal 1529 zcmZ`(y^rHW6c5K89HO8@NHmM-ZZ{j-n`AdZE8$JDUMCwTvEw-Q?G=tai6`+Fo^cZU zv>gr5@lPPylPGCuDCw`^8YEf}2+{GJEV;df8_SyU^PBhad++`Foj30n3l9s0!uMaN zJZ!u54xHG-$V$D?a{hj-eZ&~g{&@Cz@+kgz`9b}g7vKK!>GOLpzWPl-?|!NL_qe$>*BqQ3*QRx6cKtjCt>iEL4h5o5yfF31=BG0 zt^CN;pE5L!5L0JJLdSB zZ?PnU~h4sI4Wu!iHa4AXTb@orN)0+`(93ZQsMrSn=#ss!oCtnKV|| z6ur#mM^u_eiKDN{bj+SY91D~Rwv7m3>W_CpBD=VXttdhcXe6-*VY-w?^-{?TZOd~* zLhC2&37h8;hcvXqTxDSq5Zqkspgg&yp0Y`DOd2#UpBZP3PFnFi&ft_Fk`y6cQQV%C zYQ)T}c@||$Wh&|<8_l}fnmC+zo)UG?9BAUcqVjERNM^ai4RB{TaBwiofwer?myYk&+p-~n;qjo2>otr3dJrpgR=m}7z>kfPY~ z`pE>UyoI8eud|jY$$Ne6>{4p%by~(ocolTd7pvCFxafqYl+D?OFfgQ>b5j`D&B07) zEiOw^N$E|L<*~vhYT#9LPFYu5_=4c8AR{yG$gwA+*FG|vN6S{PZI71~x94(vwIS8C zpc;k!Oq0?JB_o5W?dXGbW#64bPFKMujF#N|Z)D8%lLN*_)D0o$4c1|dsp|s(LQ5?I z=0&m5g`DvcMEOos8Y9cMCLXjqjS~cj;eetU+)MAwL>z`x#k0VoNetR|Ye{fk*%7`p zhP6qwN_!qzjX9-_LX$NS+xN6!d0Cq6R~*l(so_N0l!u_1j{r7+&bS z4f&Kpn<82yo3elwCar&y-4*C=AD0i0pp&n2F8oAKAN_Q{P{`kY=Z$;C!b`%v&67Fd mzPfg?-o19)WKN Date: Wed, 26 Feb 2025 14:23:07 -0500 Subject: [PATCH 29/34] chore(main): release protocol/go 0.2.28 (#1947) :robot: I have created a release *beep* *boop* --- ## [0.2.28](https://github.com/opentdf/platform/compare/protocol/go/v0.2.27...protocol/go/v0.2.28) (2025-02-26) ### Bug Fixes * **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- protocol/go/CHANGELOG.md | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 658403917..b169be52b 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -2,7 +2,7 @@ "lib/fixtures": "0.2.10", "lib/ocrypto": "0.1.8", "lib/flattening": "0.1.3", - "protocol/go": "0.2.27", + "protocol/go": "0.2.28", "sdk": "0.3.27", "service": "0.4.38" } diff --git a/protocol/go/CHANGELOG.md b/protocol/go/CHANGELOG.md index 40d1f59ca..547202595 100644 --- a/protocol/go/CHANGELOG.md +++ b/protocol/go/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [0.2.28](https://github.com/opentdf/platform/compare/protocol/go/v0.2.27...protocol/go/v0.2.28) (2025-02-26) + + +### Bug Fixes + +* **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) + ## [0.2.27](https://github.com/opentdf/platform/compare/protocol/go/v0.2.26...protocol/go/v0.2.27) (2025-02-25) From 7270080639f19ba9725f1e834970d94d00191994 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 12:45:15 -0800 Subject: [PATCH 30/34] fix(core): Autobump service (#1950) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- service/go.mod | 2 +- service/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/service/go.mod b/service/go.mod index 07f0c266d..0db4dcb88 100644 --- a/service/go.mod +++ b/service/go.mod @@ -25,7 +25,7 @@ require ( github.com/opentdf/platform/lib/fixtures v0.2.10 github.com/opentdf/platform/lib/flattening v0.1.3 github.com/opentdf/platform/lib/ocrypto v0.1.8 - github.com/opentdf/platform/protocol/go v0.2.27 + github.com/opentdf/platform/protocol/go v0.2.28 github.com/opentdf/platform/sdk v0.3.27 github.com/pressly/goose/v3 v3.19.1 github.com/spf13/cobra v1.8.1 diff --git a/service/go.sum b/service/go.sum index 0181f6b5b..2957e2b69 100644 --- a/service/go.sum +++ b/service/go.sum @@ -279,8 +279,8 @@ github.com/opentdf/platform/lib/flattening v0.1.3 h1:IuOm/wJVXNrzOV676Ticgr0wyBk github.com/opentdf/platform/lib/flattening v0.1.3/go.mod h1:Gs/T+6FGZKk9OAdz2Jf1R8CTGeNRYrq1lZGDeYT3hrY= github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= -github.com/opentdf/platform/protocol/go v0.2.27 h1:ZnfXvVio+j/LzfEY8cHo8/tS45XAPWa2xO7Y1tn/hWs= -github.com/opentdf/platform/protocol/go v0.2.27/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/protocol/go v0.2.28 h1:UfX+yFWFGCtxsvCyIO62p4v7CBtcVR+2dCqHq3O0vy4= +github.com/opentdf/platform/protocol/go v0.2.28/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentdf/platform/sdk v0.3.27 h1:O9jCdpnxz3FEaTXj/hAOixR5mk/APsalcWCexGxfwkM= github.com/opentdf/platform/sdk v0.3.27/go.mod h1:ZJyz6hy0CMiD3MFfG4PrByTnSJnEtArTGA6ZoR1Xg6E= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= From 4dfb45780ef5a42d95405a8ad09421a21c9cd149 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 16:18:29 -0500 Subject: [PATCH 31/34] fix(core): Autobump sdk (#1948) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- sdk/go.mod | 2 +- sdk/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sdk/go.mod b/sdk/go.mod index 28d42e6e1..a1b2064e4 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -9,7 +9,7 @@ require ( github.com/lestrrat-go/jwx/v2 v2.0.21 github.com/opentdf/platform/lib/fixtures v0.2.10 github.com/opentdf/platform/lib/ocrypto v0.1.8 - github.com/opentdf/platform/protocol/go v0.2.27 + github.com/opentdf/platform/protocol/go v0.2.28 github.com/stretchr/testify v1.9.0 github.com/testcontainers/testcontainers-go v0.32.0 github.com/xeipuuv/gojsonschema v1.2.0 diff --git a/sdk/go.sum b/sdk/go.sum index cad1766f9..d5657a2ec 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -116,8 +116,8 @@ github.com/opentdf/platform/lib/fixtures v0.2.10 h1:R688b98ctsEiDRlQSvLxmAWT7bXv github.com/opentdf/platform/lib/fixtures v0.2.10/go.mod h1:wGhclxDeDXf8bp5VAWztT1nY2gWVNGQLd8rWs5wtXV0= github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/7USTIubAuUBlA= github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= -github.com/opentdf/platform/protocol/go v0.2.27 h1:ZnfXvVio+j/LzfEY8cHo8/tS45XAPWa2xO7Y1tn/hWs= -github.com/opentdf/platform/protocol/go v0.2.27/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= +github.com/opentdf/platform/protocol/go v0.2.28 h1:UfX+yFWFGCtxsvCyIO62p4v7CBtcVR+2dCqHq3O0vy4= +github.com/opentdf/platform/protocol/go v0.2.28/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= From a1b07c60043a8eeaf6d0463cff0c6686cf1e640a Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 08:12:24 -0500 Subject: [PATCH 32/34] chore(main): release sdk 0.3.28 (#1946) :robot: I have created a release *beep* *boop* --- ## [0.3.28](https://github.com/opentdf/platform/compare/sdk/v0.3.27...sdk/v0.3.28) (2025-02-26) ### Bug Fixes * **core:** Autobump sdk ([#1948](https://github.com/opentdf/platform/issues/1948)) ([4dfb457](https://github.com/opentdf/platform/commit/4dfb45780ef5a42d95405a8ad09421a21c9cd149)) * **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- sdk/CHANGELOG.md | 8 ++++++++ sdk/version.go | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index b169be52b..22a74f269 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -3,6 +3,6 @@ "lib/ocrypto": "0.1.8", "lib/flattening": "0.1.3", "protocol/go": "0.2.28", - "sdk": "0.3.27", + "sdk": "0.3.28", "service": "0.4.38" } diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md index 17dabc263..0d5f56421 100644 --- a/sdk/CHANGELOG.md +++ b/sdk/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.3.28](https://github.com/opentdf/platform/compare/sdk/v0.3.27...sdk/v0.3.28) (2025-02-26) + + +### Bug Fixes + +* **core:** Autobump sdk ([#1948](https://github.com/opentdf/platform/issues/1948)) ([4dfb457](https://github.com/opentdf/platform/commit/4dfb45780ef5a42d95405a8ad09421a21c9cd149)) +* **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) + ## [0.3.27](https://github.com/opentdf/platform/compare/sdk/v0.3.26...sdk/v0.3.27) (2025-02-25) diff --git a/sdk/version.go b/sdk/version.go index fce62d770..b8eff71e0 100644 --- a/sdk/version.go +++ b/sdk/version.go @@ -7,5 +7,5 @@ const ( TDFSpecVersion = "4.3.0" // The three-part semantic version number of this SDK - Version = "0.3.27" // x-release-please-version + Version = "0.3.28" // x-release-please-version ) From b20123ef768063eb883d9414d86ec1a0e3009884 Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 09:06:36 -0500 Subject: [PATCH 33/34] fix(core): Autobump service (#1952) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- service/go.mod | 2 +- service/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/service/go.mod b/service/go.mod index 0db4dcb88..b1e0a819a 100644 --- a/service/go.mod +++ b/service/go.mod @@ -26,7 +26,7 @@ require ( github.com/opentdf/platform/lib/flattening v0.1.3 github.com/opentdf/platform/lib/ocrypto v0.1.8 github.com/opentdf/platform/protocol/go v0.2.28 - github.com/opentdf/platform/sdk v0.3.27 + github.com/opentdf/platform/sdk v0.3.28 github.com/pressly/goose/v3 v3.19.1 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.18.2 diff --git a/service/go.sum b/service/go.sum index 2957e2b69..2f6fa55ce 100644 --- a/service/go.sum +++ b/service/go.sum @@ -281,8 +281,8 @@ github.com/opentdf/platform/lib/ocrypto v0.1.8 h1:FUKMHsVCjU4NmgaXgS1RFstl19tkX/ github.com/opentdf/platform/lib/ocrypto v0.1.8/go.mod h1:UTtqh8mvhAYA+sEnaMxpr/406e84L5Q1sAxtKGIXfu4= github.com/opentdf/platform/protocol/go v0.2.28 h1:UfX+yFWFGCtxsvCyIO62p4v7CBtcVR+2dCqHq3O0vy4= github.com/opentdf/platform/protocol/go v0.2.28/go.mod h1:eldxqX2oF2ADtG8ivhfwn1lALVMX4aaUM+Lp9ynOJXs= -github.com/opentdf/platform/sdk v0.3.27 h1:O9jCdpnxz3FEaTXj/hAOixR5mk/APsalcWCexGxfwkM= -github.com/opentdf/platform/sdk v0.3.27/go.mod h1:ZJyz6hy0CMiD3MFfG4PrByTnSJnEtArTGA6ZoR1Xg6E= +github.com/opentdf/platform/sdk v0.3.28 h1:rdfZCc5nLXDoljZEDin312T0K/RbNO5mpu1GlMTi8to= +github.com/opentdf/platform/sdk v0.3.28/go.mod h1:25xOGtsBPqbj8VDbn5yN5i6D/9fXNy/WDAM1NSPIXcY= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4= From d7b430bbe7b472301dd13985e56a069d5b056b2b Mon Sep 17 00:00:00 2001 From: "opentdf-automation[bot]" <149537512+opentdf-automation[bot]@users.noreply.github.com> Date: Thu, 27 Feb 2025 14:35:40 +0000 Subject: [PATCH 34/34] chore(main): release service 0.4.39 (#1871) :robot: I have created a release *beep* *boop* --- ## [0.4.39](https://github.com/opentdf/platform/compare/service/v0.4.38...service/v0.4.39) (2025-02-27) ### Features * add ability to retrieve policy resources by id or name ([#1901](https://github.com/opentdf/platform/issues/1901)) ([deb4455](https://github.com/opentdf/platform/commit/deb4455773cd71d3436510bbeb599f309106ce1d)) * **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) * **policy:** adds new public keys table ([#1836](https://github.com/opentdf/platform/issues/1836)) ([cad5048](https://github.com/opentdf/platform/commit/cad5048d09609d678d5b5ac2972605dd61f33bb5)) ### Bug Fixes * add pagination to list public key mappings response ([#1889](https://github.com/opentdf/platform/issues/1889)) ([9898fbd](https://github.com/opentdf/platform/commit/9898fbda305f4eface291a2aaa98d2df80f0ad05)) * cleanup kas public key create error messages ([#1887](https://github.com/opentdf/platform/issues/1887)) ([59f7d0e](https://github.com/opentdf/platform/commit/59f7d0e0ab45ef47b2df9326c0904b54fba4b3eb)) * **core:** Autobump service ([#1875](https://github.com/opentdf/platform/issues/1875)) ([4b6c335](https://github.com/opentdf/platform/commit/4b6c3353913ad90aeef499beb5f8c52144679a61)) * **core:** Autobump service ([#1895](https://github.com/opentdf/platform/issues/1895)) ([08a2048](https://github.com/opentdf/platform/commit/08a20481a085b4af67fc78e6cfae371f0bccd166)) * **core:** Autobump service ([#1919](https://github.com/opentdf/platform/issues/1919)) ([f902295](https://github.com/opentdf/platform/commit/f90229560e8f09b64b4bf650b271c5fbb428bc7f)) * **core:** Autobump service ([#1945](https://github.com/opentdf/platform/issues/1945)) ([d2e37ca](https://github.com/opentdf/platform/commit/d2e37ca081d04f4588c58b752b0c96ef9b0125cb)) * **core:** Autobump service ([#1950](https://github.com/opentdf/platform/issues/1950)) ([7270080](https://github.com/opentdf/platform/commit/7270080639f19ba9725f1e834970d94d00191994)) * **core:** Autobump service ([#1952](https://github.com/opentdf/platform/issues/1952)) ([b20123e](https://github.com/opentdf/platform/commit/b20123ef768063eb883d9414d86ec1a0e3009884)) * **core:** Fixes for ec-wrapped from js client ([#1923](https://github.com/opentdf/platform/issues/1923)) ([3a66485](https://github.com/opentdf/platform/commit/3a6648528e3d3582ec3c5222e4dfc37d0fb13e74)) * **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) * **core:** improve logging and errors on rewrap ([#1906](https://github.com/opentdf/platform/issues/1906)) ([84339d6](https://github.com/opentdf/platform/commit/84339d620717c7bc5de0d6bb6ece656cce5c07be)) * **core:** Requires unique kids ([#1905](https://github.com/opentdf/platform/issues/1905)) ([c1b380c](https://github.com/opentdf/platform/commit/c1b380cb586a10196a8febc700a57c2c41a51a18)) * filter total count on list public key operations ([#1884](https://github.com/opentdf/platform/issues/1884)) ([8df0adc](https://github.com/opentdf/platform/commit/8df0adc60dd49aa3dcdaf4d60f094338ca5ad2e9)) * **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: opentdf-automation[bot] <149537512+opentdf-automation[bot]@users.noreply.github.com> --- .release-please-manifest.json | 2 +- service/CHANGELOG.md | 27 +++++++++++++++++++++++++++ service/cmd/version.go | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 22a74f269..67170cd6d 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -4,5 +4,5 @@ "lib/flattening": "0.1.3", "protocol/go": "0.2.28", "sdk": "0.3.28", - "service": "0.4.38" + "service": "0.4.39" } diff --git a/service/CHANGELOG.md b/service/CHANGELOG.md index 6ba22c2c7..a3933ec11 100644 --- a/service/CHANGELOG.md +++ b/service/CHANGELOG.md @@ -1,5 +1,32 @@ # Changelog +## [0.4.39](https://github.com/opentdf/platform/compare/service/v0.4.38...service/v0.4.39) (2025-02-27) + + +### Features + +* add ability to retrieve policy resources by id or name ([#1901](https://github.com/opentdf/platform/issues/1901)) ([deb4455](https://github.com/opentdf/platform/commit/deb4455773cd71d3436510bbeb599f309106ce1d)) +* **core:** EXPERIMENTAL: EC-wrapped key support ([#1902](https://github.com/opentdf/platform/issues/1902)) ([652266f](https://github.com/opentdf/platform/commit/652266f212ba10b2492a84741f68391a1d39e007)) +* **policy:** adds new public keys table ([#1836](https://github.com/opentdf/platform/issues/1836)) ([cad5048](https://github.com/opentdf/platform/commit/cad5048d09609d678d5b5ac2972605dd61f33bb5)) + + +### Bug Fixes + +* add pagination to list public key mappings response ([#1889](https://github.com/opentdf/platform/issues/1889)) ([9898fbd](https://github.com/opentdf/platform/commit/9898fbda305f4eface291a2aaa98d2df80f0ad05)) +* cleanup kas public key create error messages ([#1887](https://github.com/opentdf/platform/issues/1887)) ([59f7d0e](https://github.com/opentdf/platform/commit/59f7d0e0ab45ef47b2df9326c0904b54fba4b3eb)) +* **core:** Autobump service ([#1875](https://github.com/opentdf/platform/issues/1875)) ([4b6c335](https://github.com/opentdf/platform/commit/4b6c3353913ad90aeef499beb5f8c52144679a61)) +* **core:** Autobump service ([#1895](https://github.com/opentdf/platform/issues/1895)) ([08a2048](https://github.com/opentdf/platform/commit/08a20481a085b4af67fc78e6cfae371f0bccd166)) +* **core:** Autobump service ([#1919](https://github.com/opentdf/platform/issues/1919)) ([f902295](https://github.com/opentdf/platform/commit/f90229560e8f09b64b4bf650b271c5fbb428bc7f)) +* **core:** Autobump service ([#1945](https://github.com/opentdf/platform/issues/1945)) ([d2e37ca](https://github.com/opentdf/platform/commit/d2e37ca081d04f4588c58b752b0c96ef9b0125cb)) +* **core:** Autobump service ([#1950](https://github.com/opentdf/platform/issues/1950)) ([7270080](https://github.com/opentdf/platform/commit/7270080639f19ba9725f1e834970d94d00191994)) +* **core:** Autobump service ([#1952](https://github.com/opentdf/platform/issues/1952)) ([b20123e](https://github.com/opentdf/platform/commit/b20123ef768063eb883d9414d86ec1a0e3009884)) +* **core:** Fixes for ec-wrapped from js client ([#1923](https://github.com/opentdf/platform/issues/1923)) ([3a66485](https://github.com/opentdf/platform/commit/3a6648528e3d3582ec3c5222e4dfc37d0fb13e74)) +* **core:** Fixes protoJSON parse bug on ec rewrap ([#1943](https://github.com/opentdf/platform/issues/1943)) ([9bebfd0](https://github.com/opentdf/platform/commit/9bebfd01f615f5a438e0695c03dbb1a9ad7badf3)) +* **core:** improve logging and errors on rewrap ([#1906](https://github.com/opentdf/platform/issues/1906)) ([84339d6](https://github.com/opentdf/platform/commit/84339d620717c7bc5de0d6bb6ece656cce5c07be)) +* **core:** Requires unique kids ([#1905](https://github.com/opentdf/platform/issues/1905)) ([c1b380c](https://github.com/opentdf/platform/commit/c1b380cb586a10196a8febc700a57c2c41a51a18)) +* filter total count on list public key operations ([#1884](https://github.com/opentdf/platform/issues/1884)) ([8df0adc](https://github.com/opentdf/platform/commit/8df0adc60dd49aa3dcdaf4d60f094338ca5ad2e9)) +* **sdk:** Fix compatibility between bulk and non-bulk rewrap ([#1914](https://github.com/opentdf/platform/issues/1914)) ([74abbb6](https://github.com/opentdf/platform/commit/74abbb66cbb39023f56cd502a7cda294580a41c6)) + ## [0.4.38](https://github.com/opentdf/platform/compare/service/v0.4.37...service/v0.4.38) (2025-01-21) diff --git a/service/cmd/version.go b/service/cmd/version.go index 23892fbea..7e2a11a83 100644 --- a/service/cmd/version.go +++ b/service/cmd/version.go @@ -2,7 +2,7 @@ package cmd import "github.com/spf13/cobra" -const Version = "0.4.38" // Service Version // x-release-please-version +const Version = "0.4.39" // Service Version // x-release-please-version func init() { rootCmd.AddCommand(&cobra.Command{