diff --git a/docs/grpc/index.html b/docs/grpc/index.html
index e8243fc07d..340535914d 100644
--- a/docs/grpc/index.html
+++ b/docs/grpc/index.html
@@ -357,6 +357,10 @@
Table of Contents
EDecisionResponse.Decision
+
+ EEntity.Category
+
+
@@ -2106,7 +2110,7 @@ Entity
email_address |
string |
|
- |
+ one of the entity options must be set |
@@ -2151,6 +2155,13 @@ Entity
|
+
+ | category |
+ Entity.Category |
+ |
+ |
+
+
@@ -2533,6 +2544,35 @@ DecisionResponse.Decision
+ Entity.Category
+
+
+
+ | Name | Number | Description |
+
+
+
+
+ | CATEGORY_UNSPECIFIED |
+ 0 |
+ |
+
+
+
+ | CATEGORY_SUBJECT |
+ 1 |
+ |
+
+
+
+ | CATEGORY_ENVIRONMENT |
+ 2 |
+ |
+
+
+
+
+
diff --git a/docs/openapi/authorization/authorization.swagger.json b/docs/openapi/authorization/authorization.swagger.json
index 84d16fe172..43493bf79a 100644
--- a/docs/openapi/authorization/authorization.swagger.json
+++ b/docs/openapi/authorization/authorization.swagger.json
@@ -128,6 +128,15 @@
],
"default": "DECISION_UNSPECIFIED"
},
+ "EntityCategory": {
+ "type": "string",
+ "enum": [
+ "CATEGORY_UNSPECIFIED",
+ "CATEGORY_SUBJECT",
+ "CATEGORY_ENVIRONMENT"
+ ],
+ "default": "CATEGORY_UNSPECIFIED"
+ },
"authorizationDecisionRequest": {
"type": "object",
"properties": {
@@ -194,7 +203,8 @@
"title": "ephemeral id for tracking between request and response"
},
"emailAddress": {
- "type": "string"
+ "type": "string",
+ "title": "one of the entity options must be set"
},
"userName": {
"type": "string"
@@ -213,6 +223,9 @@
},
"clientId": {
"type": "string"
+ },
+ "category": {
+ "$ref": "#/definitions/EntityCategory"
}
},
"title": "PE (Person Entity) or NPE (Non-Person Entity)"
diff --git a/docs/openapi/entityresolution/entity_resolution.swagger.json b/docs/openapi/entityresolution/entity_resolution.swagger.json
index 288eda816d..45cb881517 100644
--- a/docs/openapi/entityresolution/entity_resolution.swagger.json
+++ b/docs/openapi/entityresolution/entity_resolution.swagger.json
@@ -82,6 +82,15 @@
}
},
"definitions": {
+ "EntityCategory": {
+ "type": "string",
+ "enum": [
+ "CATEGORY_UNSPECIFIED",
+ "CATEGORY_SUBJECT",
+ "CATEGORY_ENVIRONMENT"
+ ],
+ "default": "CATEGORY_UNSPECIFIED"
+ },
"authorizationEntity": {
"type": "object",
"properties": {
@@ -90,7 +99,8 @@
"title": "ephemeral id for tracking between request and response"
},
"emailAddress": {
- "type": "string"
+ "type": "string",
+ "title": "one of the entity options must be set"
},
"userName": {
"type": "string"
@@ -109,6 +119,9 @@
},
"clientId": {
"type": "string"
+ },
+ "category": {
+ "$ref": "#/definitions/EntityCategory"
}
},
"title": "PE (Person Entity) or NPE (Non-Person Entity)"
diff --git a/examples/cmd/authorization.go b/examples/cmd/authorization.go
index f7ac1d705c..9d3364e21b 100644
--- a/examples/cmd/authorization.go
+++ b/examples/cmd/authorization.go
@@ -35,11 +35,13 @@ func authorizationExamples() error {
// model two groups of entities; user bob and user alice
entityChains := []*authorization.EntityChain{{
- Id: "ec1", // ec1 is an arbitrary tracking id to match results to request
- Entities: []*authorization.Entity{{EntityType: &authorization.Entity_EmailAddress{EmailAddress: "bob@example.org"}}},
+ Id: "ec1", // ec1 is an arbitrary tracking id to match results to request
+ Entities: []*authorization.Entity{{EntityType: &authorization.Entity_EmailAddress{EmailAddress: "bob@example.org"},
+ Category: authorization.Entity_CATEGORY_SUBJECT}},
}, {
- Id: "ec2", // ec2 is an arbitrary tracking id to match results to request
- Entities: []*authorization.Entity{{EntityType: &authorization.Entity_UserName{UserName: "alice@example.org"}}},
+ Id: "ec2", // ec2 is an arbitrary tracking id to match results to request
+ Entities: []*authorization.Entity{{EntityType: &authorization.Entity_UserName{UserName: "alice@example.org"},
+ Category: authorization.Entity_CATEGORY_SUBJECT}},
}}
// TODO Get attribute value ids
diff --git a/protocol/go/authorization/authorization.pb.go b/protocol/go/authorization/authorization.pb.go
index 3c15afd138..8ab0e31352 100644
--- a/protocol/go/authorization/authorization.pb.go
+++ b/protocol/go/authorization/authorization.pb.go
@@ -23,6 +23,55 @@ const (
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
+type Entity_Category int32
+
+const (
+ Entity_CATEGORY_UNSPECIFIED Entity_Category = 0
+ Entity_CATEGORY_SUBJECT Entity_Category = 1
+ Entity_CATEGORY_ENVIRONMENT Entity_Category = 2
+)
+
+// Enum value maps for Entity_Category.
+var (
+ Entity_Category_name = map[int32]string{
+ 0: "CATEGORY_UNSPECIFIED",
+ 1: "CATEGORY_SUBJECT",
+ 2: "CATEGORY_ENVIRONMENT",
+ }
+ Entity_Category_value = map[string]int32{
+ "CATEGORY_UNSPECIFIED": 0,
+ "CATEGORY_SUBJECT": 1,
+ "CATEGORY_ENVIRONMENT": 2,
+ }
+)
+
+func (x Entity_Category) Enum() *Entity_Category {
+ p := new(Entity_Category)
+ *p = x
+ return p
+}
+
+func (x Entity_Category) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Entity_Category) Descriptor() protoreflect.EnumDescriptor {
+ return file_authorization_authorization_proto_enumTypes[0].Descriptor()
+}
+
+func (Entity_Category) Type() protoreflect.EnumType {
+ return &file_authorization_authorization_proto_enumTypes[0]
+}
+
+func (x Entity_Category) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Entity_Category.Descriptor instead.
+func (Entity_Category) EnumDescriptor() ([]byte, []int) {
+ return file_authorization_authorization_proto_rawDescGZIP(), []int{1, 0}
+}
+
type DecisionResponse_Decision int32
const (
@@ -56,11 +105,11 @@ func (x DecisionResponse_Decision) String() string {
}
func (DecisionResponse_Decision) Descriptor() protoreflect.EnumDescriptor {
- return file_authorization_authorization_proto_enumTypes[0].Descriptor()
+ return file_authorization_authorization_proto_enumTypes[1].Descriptor()
}
func (DecisionResponse_Decision) Type() protoreflect.EnumType {
- return &file_authorization_authorization_proto_enumTypes[0]
+ return &file_authorization_authorization_proto_enumTypes[1]
}
func (x DecisionResponse_Decision) Number() protoreflect.EnumNumber {
@@ -146,6 +195,7 @@ type Entity struct {
// *Entity_Custom
// *Entity_ClientId
EntityType isEntity_EntityType `protobuf_oneof:"entity_type"`
+ Category Entity_Category `protobuf:"varint,9,opt,name=category,proto3,enum=authorization.Entity_Category" json:"category,omitempty"`
}
func (x *Entity) Reset() {
@@ -243,11 +293,19 @@ func (x *Entity) GetClientId() string {
return ""
}
+func (x *Entity) GetCategory() Entity_Category {
+ if x != nil {
+ return x.Category
+ }
+ return Entity_CATEGORY_UNSPECIFIED
+}
+
type isEntity_EntityType interface {
isEntity_EntityType()
}
type Entity_EmailAddress struct {
+ // one of the entity options must be set
EmailAddress string `protobuf:"bytes,2,opt,name=email_address,json=emailAddress,proto3,oneof"`
}
@@ -1178,7 +1236,7 @@ var file_authorization_authorization_proto_rawDesc = []byte{
0x69, 0x63, 0x79, 0x2f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x22, 0x29, 0x0a, 0x05, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x6a, 0x77,
- 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0xb7, 0x02, 0x0a,
+ 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6a, 0x77, 0x74, 0x22, 0xc9, 0x03, 0x0a,
0x06, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0d, 0x65, 0x6d, 0x61, 0x69, 0x6c,
0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
@@ -1197,164 +1255,173 @@ var file_authorization_authorization_proto_rawDesc = []byte{
0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x48, 0x00,
0x52, 0x06, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x12, 0x1d, 0x0a, 0x09, 0x63, 0x6c, 0x69, 0x65,
0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x63,
- 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x42, 0x0d, 0x0a, 0x0b, 0x65, 0x6e, 0x74, 0x69, 0x74,
- 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x42, 0x0a, 0x0c, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79,
- 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x12, 0x32, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73,
- 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
- 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52,
- 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x0b, 0x45, 0x6e,
- 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
- 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x08, 0x65, 0x6e, 0x74,
- 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69,
- 0x74, 0x79, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xcf, 0x01, 0x0a,
- 0x0f, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
- 0x12, 0x28, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3f, 0x0a, 0x0d, 0x65, 0x6e,
- 0x74, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x0c, 0x65,
- 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x51, 0x0a, 0x13, 0x72,
- 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
- 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
- 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x12, 0x72, 0x65, 0x73, 0x6f,
- 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0xce,
- 0x02, 0x0a, 0x10, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
- 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68,
- 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e,
- 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x34, 0x0a, 0x16, 0x72,
- 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
- 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x72, 0x65, 0x73,
- 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x49,
- 0x64, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28,
- 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f,
- 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x64, 0x65, 0x63,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x63, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44, 0x65, 0x63,
- 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12,
- 0x20, 0x0a, 0x0b, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05,
- 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x73, 0x22, 0x4c, 0x0a, 0x08, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a,
- 0x14, 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
- 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, 0x43, 0x49, 0x53,
- 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45,
- 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x54, 0x10, 0x02, 0x22,
- 0x62, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
- 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x2e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x52, 0x10, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x73, 0x22, 0x66, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x12, 0x64,
- 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
- 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
- 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x11, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69,
- 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0xfa, 0x01, 0x0a, 0x16,
- 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69,
- 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52,
- 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x05, 0x73, 0x63, 0x6f,
- 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
- 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05, 0x73, 0x63,
- 0x6f, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x45, 0x0a, 0x1c, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x63,
- 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x68, 0x69, 0x65,
- 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x1a,
- 0x77, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76,
- 0x65, 0x48, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a,
- 0x06, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x42, 0x1f, 0x0a, 0x1d, 0x5f, 0x77, 0x69, 0x74, 0x68,
- 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x68,
- 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x22, 0x63, 0x0a, 0x12, 0x45, 0x6e, 0x74, 0x69,
- 0x74, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1b,
- 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x09, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x61,
- 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66,
- 0x71, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x74, 0x74, 0x72, 0x69,
- 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x71, 0x6e, 0x73, 0x22, 0x7b, 0x0a,
- 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
- 0x74, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61,
- 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
- 0x28, 0x09, 0x52, 0x14, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72,
- 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x74, 0x74, 0x72,
- 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x71, 0x6e, 0x73,
- 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
- 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x71, 0x6e, 0x73, 0x22, 0x60, 0x0a, 0x17, 0x47, 0x65,
- 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73,
- 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0c, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65,
- 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69,
- 0x74, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x0c,
- 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xc1, 0x01, 0x0a,
- 0x14, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73,
- 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e,
- 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12,
- 0x2c, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32,
- 0x14, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
- 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x51, 0x0a,
+ 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x3a, 0x0a, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67,
+ 0x6f, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68,
+ 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79,
+ 0x2e, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x52, 0x08, 0x63, 0x61, 0x74, 0x65, 0x67,
+ 0x6f, 0x72, 0x79, 0x22, 0x54, 0x0a, 0x08, 0x43, 0x61, 0x74, 0x65, 0x67, 0x6f, 0x72, 0x79, 0x12,
+ 0x18, 0x0a, 0x14, 0x43, 0x41, 0x54, 0x45, 0x47, 0x4f, 0x52, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50,
+ 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x41, 0x54,
+ 0x45, 0x47, 0x4f, 0x52, 0x59, 0x5f, 0x53, 0x55, 0x42, 0x4a, 0x45, 0x43, 0x54, 0x10, 0x01, 0x12,
+ 0x18, 0x0a, 0x14, 0x43, 0x41, 0x54, 0x45, 0x47, 0x4f, 0x52, 0x59, 0x5f, 0x45, 0x4e, 0x56, 0x49,
+ 0x52, 0x4f, 0x4e, 0x4d, 0x45, 0x4e, 0x54, 0x10, 0x02, 0x42, 0x0d, 0x0a, 0x0b, 0x65, 0x6e, 0x74,
+ 0x69, 0x74, 0x79, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x22, 0x42, 0x0a, 0x0c, 0x45, 0x6e, 0x74, 0x69,
+ 0x74, 0x79, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x12, 0x32, 0x0a, 0x09, 0x65, 0x78, 0x74, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e,
+ 0x79, 0x52, 0x09, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x50, 0x0a, 0x0b,
+ 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69,
+ 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x08, 0x65,
+ 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e,
+ 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e,
+ 0x74, 0x69, 0x74, 0x79, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x22, 0xcf,
+ 0x01, 0x0a, 0x0f, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x12, 0x28, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x3f, 0x0a, 0x0d,
+ 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x02, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52,
+ 0x0c, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x51, 0x0a,
0x13, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x12, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73,
- 0x22, 0x6e, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73,
- 0x42, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x50,
- 0x0a, 0x11, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x75, 0x74, 0x68,
- 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x44,
- 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x10,
- 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73,
- 0x22, 0x6d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73,
- 0x42, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
- 0x4e, 0x0a, 0x12, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70,
- 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x63, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x11, 0x64, 0x65,
- 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x32,
- 0x96, 0x03, 0x0a, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x0c, 0x47, 0x65, 0x74, 0x44,
- 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f,
- 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69,
- 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x61,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74,
- 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
- 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x11, 0x2f, 0x76, 0x31, 0x2f, 0x61,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x8d, 0x01, 0x0a,
- 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x54,
- 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x29, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61,
- 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e,
- 0x73, 0x42, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x2a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
- 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x54, 0x6f,
- 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82, 0xd3, 0xe4,
- 0x93, 0x02, 0x19, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2f, 0x61,
- 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x7a, 0x0a, 0x0f,
- 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12,
- 0x25, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
+ 0x22, 0xce, 0x02, 0x0a, 0x10, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x0f, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f,
+ 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
+ 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x34, 0x0a,
+ 0x16, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
+ 0x75, 0x74, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x72,
+ 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65,
+ 0x73, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x2e, 0x41, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x44, 0x0a, 0x08, 0x64,
+ 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x28, 0x2e,
+ 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65,
+ 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x44,
+ 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f,
+ 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x22, 0x4c, 0x0a, 0x08, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12,
+ 0x18, 0x0a, 0x14, 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50,
+ 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x11, 0x0a, 0x0d, 0x44, 0x45, 0x43,
+ 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x13, 0x0a, 0x0f,
+ 0x44, 0x45, 0x43, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x54, 0x10,
+ 0x02, 0x22, 0x62, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4b, 0x0a, 0x11, 0x64, 0x65, 0x63, 0x69,
+ 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20,
+ 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x52, 0x10, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0x66, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69,
+ 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a,
+ 0x12, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, 0x75, 0x74, 0x68,
+ 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69,
+ 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x11, 0x64, 0x65, 0x63, 0x69,
+ 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x22, 0xfa, 0x01,
+ 0x0a, 0x16, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x65, 0x6e, 0x74, 0x69,
+ 0x74, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x61, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e, 0x74, 0x69, 0x74,
+ 0x79, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x05, 0x73,
+ 0x63, 0x6f, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x05,
+ 0x73, 0x63, 0x6f, 0x70, 0x65, 0x88, 0x01, 0x01, 0x12, 0x45, 0x0a, 0x1c, 0x77, 0x69, 0x74, 0x68,
+ 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65, 0x5f, 0x68,
+ 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01,
+ 0x52, 0x1a, 0x77, 0x69, 0x74, 0x68, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73,
+ 0x69, 0x76, 0x65, 0x48, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x88, 0x01, 0x01, 0x42,
+ 0x08, 0x0a, 0x06, 0x5f, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x42, 0x1f, 0x0a, 0x1d, 0x5f, 0x77, 0x69,
+ 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x68, 0x65, 0x6e, 0x73, 0x69, 0x76, 0x65,
+ 0x5f, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x22, 0x63, 0x0a, 0x12, 0x45, 0x6e,
+ 0x74, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73,
+ 0x12, 0x1b, 0x0a, 0x09, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x08, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x49, 0x64, 0x12, 0x30, 0x0a,
+ 0x14, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x5f, 0x66, 0x71, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x74, 0x74,
+ 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x71, 0x6e, 0x73, 0x22,
+ 0x7b, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69,
+ 0x62, 0x75, 0x74, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+ 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74,
+ 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x49, 0x64, 0x12, 0x30, 0x0a, 0x14, 0x61, 0x74,
+ 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x66, 0x71,
+ 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62,
+ 0x75, 0x74, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x46, 0x71, 0x6e, 0x73, 0x22, 0x60, 0x0a, 0x17,
0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
- 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c,
- 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x18,
- 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x6e, 0x74, 0x69,
- 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0xb2, 0x01, 0x0a, 0x11, 0x63, 0x6f, 0x6d,
- 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x12,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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, 0x61, 0x75,
- 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03, 0x41, 0x58,
- 0x58, 0xaa, 0x02, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0xca, 0x02, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0xe2, 0x02, 0x19, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x0d,
- 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70,
- 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x45, 0x0a, 0x0c, 0x65, 0x6e, 0x74, 0x69, 0x74,
+ 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e,
+ 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x45, 0x6e,
+ 0x74, 0x69, 0x74, 0x79, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73,
+ 0x52, 0x0c, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0xc1,
+ 0x01, 0x0a, 0x14, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x70, 0x6f, 0x6c, 0x69, 0x63,
+ 0x79, 0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x73, 0x12, 0x2c, 0x0a, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
+ 0x0b, 0x32, 0x14, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12,
+ 0x51, 0x0a, 0x13, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72,
+ 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x61,
+ 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73,
+ 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x52, 0x12,
+ 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
+ 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x42, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x50, 0x0a, 0x11, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x75,
+ 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x6f, 0x6b, 0x65,
+ 0x6e, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x52, 0x10, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x73, 0x22, 0x6d, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f,
+ 0x6e, 0x73, 0x42, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x12, 0x4e, 0x0a, 0x12, 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
+ 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x44, 0x65,
+ 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x52, 0x11,
+ 0x64, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x73, 0x32, 0x96, 0x03, 0x0a, 0x14, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x72, 0x0a, 0x0c, 0x47, 0x65,
+ 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x2e, 0x61, 0x75, 0x74,
+ 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65,
+ 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23,
+ 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47,
+ 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x22, 0x11, 0x2f, 0x76, 0x31,
+ 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x8d,
+ 0x01, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42,
+ 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x29, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
+ 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69,
+ 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x1a, 0x2a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79,
+ 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x1f, 0x82,
+ 0xd3, 0xe4, 0x93, 0x02, 0x19, 0x22, 0x17, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x2f, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x7a,
+ 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x73, 0x12, 0x25, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f,
+ 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x69,
+ 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x22, 0x18, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x12, 0x22, 0x10, 0x2f, 0x76, 0x31, 0x2f, 0x65, 0x6e,
+ 0x74, 0x69, 0x74, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x42, 0xb2, 0x01, 0x0a, 0x11, 0x63,
+ 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x42, 0x12, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 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,
+ 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0xa2, 0x02, 0x03,
+ 0x41, 0x58, 0x58, 0xaa, 0x02, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0xca, 0x02, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0xe2, 0x02, 0x19, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea,
+ 0x02, 0x0d, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x62,
+ 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -1369,59 +1436,61 @@ func file_authorization_authorization_proto_rawDescGZIP() []byte {
return file_authorization_authorization_proto_rawDescData
}
-var file_authorization_authorization_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_authorization_authorization_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_authorization_authorization_proto_msgTypes = make([]protoimpl.MessageInfo, 15)
var file_authorization_authorization_proto_goTypes = []interface{}{
- (DecisionResponse_Decision)(0), // 0: authorization.DecisionResponse.Decision
- (*Token)(nil), // 1: authorization.Token
- (*Entity)(nil), // 2: authorization.Entity
- (*EntityCustom)(nil), // 3: authorization.EntityCustom
- (*EntityChain)(nil), // 4: authorization.EntityChain
- (*DecisionRequest)(nil), // 5: authorization.DecisionRequest
- (*DecisionResponse)(nil), // 6: authorization.DecisionResponse
- (*GetDecisionsRequest)(nil), // 7: authorization.GetDecisionsRequest
- (*GetDecisionsResponse)(nil), // 8: authorization.GetDecisionsResponse
- (*GetEntitlementsRequest)(nil), // 9: authorization.GetEntitlementsRequest
- (*EntityEntitlements)(nil), // 10: authorization.EntityEntitlements
- (*ResourceAttribute)(nil), // 11: authorization.ResourceAttribute
- (*GetEntitlementsResponse)(nil), // 12: authorization.GetEntitlementsResponse
- (*TokenDecisionRequest)(nil), // 13: authorization.TokenDecisionRequest
- (*GetDecisionsByTokenRequest)(nil), // 14: authorization.GetDecisionsByTokenRequest
- (*GetDecisionsByTokenResponse)(nil), // 15: authorization.GetDecisionsByTokenResponse
- (*anypb.Any)(nil), // 16: google.protobuf.Any
- (*policy.Action)(nil), // 17: policy.Action
+ (Entity_Category)(0), // 0: authorization.Entity.Category
+ (DecisionResponse_Decision)(0), // 1: authorization.DecisionResponse.Decision
+ (*Token)(nil), // 2: authorization.Token
+ (*Entity)(nil), // 3: authorization.Entity
+ (*EntityCustom)(nil), // 4: authorization.EntityCustom
+ (*EntityChain)(nil), // 5: authorization.EntityChain
+ (*DecisionRequest)(nil), // 6: authorization.DecisionRequest
+ (*DecisionResponse)(nil), // 7: authorization.DecisionResponse
+ (*GetDecisionsRequest)(nil), // 8: authorization.GetDecisionsRequest
+ (*GetDecisionsResponse)(nil), // 9: authorization.GetDecisionsResponse
+ (*GetEntitlementsRequest)(nil), // 10: authorization.GetEntitlementsRequest
+ (*EntityEntitlements)(nil), // 11: authorization.EntityEntitlements
+ (*ResourceAttribute)(nil), // 12: authorization.ResourceAttribute
+ (*GetEntitlementsResponse)(nil), // 13: authorization.GetEntitlementsResponse
+ (*TokenDecisionRequest)(nil), // 14: authorization.TokenDecisionRequest
+ (*GetDecisionsByTokenRequest)(nil), // 15: authorization.GetDecisionsByTokenRequest
+ (*GetDecisionsByTokenResponse)(nil), // 16: authorization.GetDecisionsByTokenResponse
+ (*anypb.Any)(nil), // 17: google.protobuf.Any
+ (*policy.Action)(nil), // 18: policy.Action
}
var file_authorization_authorization_proto_depIdxs = []int32{
- 16, // 0: authorization.Entity.claims:type_name -> google.protobuf.Any
- 3, // 1: authorization.Entity.custom:type_name -> authorization.EntityCustom
- 16, // 2: authorization.EntityCustom.extension:type_name -> google.protobuf.Any
- 2, // 3: authorization.EntityChain.entities:type_name -> authorization.Entity
- 17, // 4: authorization.DecisionRequest.actions:type_name -> policy.Action
- 4, // 5: authorization.DecisionRequest.entity_chains:type_name -> authorization.EntityChain
- 11, // 6: authorization.DecisionRequest.resource_attributes:type_name -> authorization.ResourceAttribute
- 17, // 7: authorization.DecisionResponse.action:type_name -> policy.Action
- 0, // 8: authorization.DecisionResponse.decision:type_name -> authorization.DecisionResponse.Decision
- 5, // 9: authorization.GetDecisionsRequest.decision_requests:type_name -> authorization.DecisionRequest
- 6, // 10: authorization.GetDecisionsResponse.decision_responses:type_name -> authorization.DecisionResponse
- 2, // 11: authorization.GetEntitlementsRequest.entities:type_name -> authorization.Entity
- 11, // 12: authorization.GetEntitlementsRequest.scope:type_name -> authorization.ResourceAttribute
- 10, // 13: authorization.GetEntitlementsResponse.entitlements:type_name -> authorization.EntityEntitlements
- 17, // 14: authorization.TokenDecisionRequest.actions:type_name -> policy.Action
- 1, // 15: authorization.TokenDecisionRequest.tokens:type_name -> authorization.Token
- 11, // 16: authorization.TokenDecisionRequest.resource_attributes:type_name -> authorization.ResourceAttribute
- 13, // 17: authorization.GetDecisionsByTokenRequest.decision_requests:type_name -> authorization.TokenDecisionRequest
- 6, // 18: authorization.GetDecisionsByTokenResponse.decision_responses:type_name -> authorization.DecisionResponse
- 7, // 19: authorization.AuthorizationService.GetDecisions:input_type -> authorization.GetDecisionsRequest
- 14, // 20: authorization.AuthorizationService.GetDecisionsByToken:input_type -> authorization.GetDecisionsByTokenRequest
- 9, // 21: authorization.AuthorizationService.GetEntitlements:input_type -> authorization.GetEntitlementsRequest
- 8, // 22: authorization.AuthorizationService.GetDecisions:output_type -> authorization.GetDecisionsResponse
- 15, // 23: authorization.AuthorizationService.GetDecisionsByToken:output_type -> authorization.GetDecisionsByTokenResponse
- 12, // 24: authorization.AuthorizationService.GetEntitlements:output_type -> authorization.GetEntitlementsResponse
- 22, // [22:25] is the sub-list for method output_type
- 19, // [19:22] is the sub-list for method input_type
- 19, // [19:19] is the sub-list for extension type_name
- 19, // [19:19] is the sub-list for extension extendee
- 0, // [0:19] is the sub-list for field type_name
+ 17, // 0: authorization.Entity.claims:type_name -> google.protobuf.Any
+ 4, // 1: authorization.Entity.custom:type_name -> authorization.EntityCustom
+ 0, // 2: authorization.Entity.category:type_name -> authorization.Entity.Category
+ 17, // 3: authorization.EntityCustom.extension:type_name -> google.protobuf.Any
+ 3, // 4: authorization.EntityChain.entities:type_name -> authorization.Entity
+ 18, // 5: authorization.DecisionRequest.actions:type_name -> policy.Action
+ 5, // 6: authorization.DecisionRequest.entity_chains:type_name -> authorization.EntityChain
+ 12, // 7: authorization.DecisionRequest.resource_attributes:type_name -> authorization.ResourceAttribute
+ 18, // 8: authorization.DecisionResponse.action:type_name -> policy.Action
+ 1, // 9: authorization.DecisionResponse.decision:type_name -> authorization.DecisionResponse.Decision
+ 6, // 10: authorization.GetDecisionsRequest.decision_requests:type_name -> authorization.DecisionRequest
+ 7, // 11: authorization.GetDecisionsResponse.decision_responses:type_name -> authorization.DecisionResponse
+ 3, // 12: authorization.GetEntitlementsRequest.entities:type_name -> authorization.Entity
+ 12, // 13: authorization.GetEntitlementsRequest.scope:type_name -> authorization.ResourceAttribute
+ 11, // 14: authorization.GetEntitlementsResponse.entitlements:type_name -> authorization.EntityEntitlements
+ 18, // 15: authorization.TokenDecisionRequest.actions:type_name -> policy.Action
+ 2, // 16: authorization.TokenDecisionRequest.tokens:type_name -> authorization.Token
+ 12, // 17: authorization.TokenDecisionRequest.resource_attributes:type_name -> authorization.ResourceAttribute
+ 14, // 18: authorization.GetDecisionsByTokenRequest.decision_requests:type_name -> authorization.TokenDecisionRequest
+ 7, // 19: authorization.GetDecisionsByTokenResponse.decision_responses:type_name -> authorization.DecisionResponse
+ 8, // 20: authorization.AuthorizationService.GetDecisions:input_type -> authorization.GetDecisionsRequest
+ 15, // 21: authorization.AuthorizationService.GetDecisionsByToken:input_type -> authorization.GetDecisionsByTokenRequest
+ 10, // 22: authorization.AuthorizationService.GetEntitlements:input_type -> authorization.GetEntitlementsRequest
+ 9, // 23: authorization.AuthorizationService.GetDecisions:output_type -> authorization.GetDecisionsResponse
+ 16, // 24: authorization.AuthorizationService.GetDecisionsByToken:output_type -> authorization.GetDecisionsByTokenResponse
+ 13, // 25: authorization.AuthorizationService.GetEntitlements:output_type -> authorization.GetEntitlementsResponse
+ 23, // [23:26] is the sub-list for method output_type
+ 20, // [20:23] is the sub-list for method input_type
+ 20, // [20:20] is the sub-list for extension type_name
+ 20, // [20:20] is the sub-list for extension extendee
+ 0, // [0:20] is the sub-list for field type_name
}
func init() { file_authorization_authorization_proto_init() }
@@ -1626,7 +1695,7 @@ func file_authorization_authorization_proto_init() {
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_authorization_authorization_proto_rawDesc,
- NumEnums: 1,
+ NumEnums: 2,
NumMessages: 15,
NumExtensions: 0,
NumServices: 1,
diff --git a/service/authorization/authorization.go b/service/authorization/authorization.go
index f9a3fc4b07..5a4e99df4b 100644
--- a/service/authorization/authorization.go
+++ b/service/authorization/authorization.go
@@ -269,8 +269,13 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authoriza
auditECEntitlements := make([]audit.EntityChainEntitlement, 0)
auditEntityDecisions := make([]audit.EntityDecision, 0)
- entityAttrValues := make(map[string][]string)
+ // Entitlements for environment entites in chain
+ envEntityAttrValues := make(map[string][]string)
+ // Entitlements for sbuject entities in chain
+ subjectEntityAttrValues := make(map[string][]string)
+
+ //nolint:nestif // handle empty entity / attr list
if len(entities) == 0 || len(allPertinentFqnsRA.GetAttributeValueFqns()) == 0 {
as.logger.WarnContext(ctx, "Empty entity list and/or entity data attribute list")
} else {
@@ -282,12 +287,23 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authoriza
// TODO this might cause errors if multiple entities dont have ids
// currently just adding each entity returned to same list
- for _, e := range ecEntitlements.GetEntitlements() {
+ for idx, e := range ecEntitlements.GetEntitlements() {
+ entityID := e.GetEntityId()
+ if entityID == "" {
+ entityID = EntityIDPrefix + fmt.Sprint(idx)
+ }
auditECEntitlements = append(auditECEntitlements, audit.EntityChainEntitlement{
- EntityID: e.GetEntityId(),
+ EntityID: entityID,
AttributeValueReferences: e.GetAttributeValueFqns(),
})
- entityAttrValues[e.GetEntityId()] = e.GetAttributeValueFqns()
+ entityCategory := entities[idx].GetCategory()
+
+ // If entity type unspecified, include in access decision to err on the side of caution
+ if entityCategory == authorization.Entity_CATEGORY_SUBJECT || entityCategory == authorization.Entity_CATEGORY_UNSPECIFIED {
+ subjectEntityAttrValues[entityID] = e.GetAttributeValueFqns()
+ } else {
+ envEntityAttrValues[entityID] = e.GetAttributeValueFqns()
+ }
}
}
@@ -296,7 +312,7 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authoriza
decisions, err := accessPDP.DetermineAccess(
ctx,
attrVals,
- entityAttrValues,
+ subjectEntityAttrValues,
attrDefs,
)
if err != nil {
@@ -314,7 +330,7 @@ func (as *AuthorizationService) GetDecisions(ctx context.Context, req *authoriza
}
// Add entity decision to audit list
- entityEntitlementFqns := entityAttrValues[entityID]
+ entityEntitlementFqns := subjectEntityAttrValues[entityID]
if entityEntitlementFqns == nil {
entityEntitlementFqns = []string{}
}
diff --git a/service/authorization/authorization.proto b/service/authorization/authorization.proto
index 596fbaf0a7..2bb0d24fbe 100644
--- a/service/authorization/authorization.proto
+++ b/service/authorization/authorization.proto
@@ -18,6 +18,7 @@ message Entity {
string id = 1; // ephemeral id for tracking between request and response
// Standard entity types supported by the platform
oneof entity_type {
+ // one of the entity options must be set
string email_address = 2;
string user_name = 3;
string remote_claims_url = 4;
@@ -26,6 +27,12 @@ message Entity {
EntityCustom custom = 7;
string client_id = 8;
}
+ enum Category {
+ CATEGORY_UNSPECIFIED = 0;
+ CATEGORY_SUBJECT = 1;
+ CATEGORY_ENVIRONMENT = 2;
+ }
+ Category category = 9;
}
// Entity type for custom entities beyond the standard types
diff --git a/service/authorization/authorization_test.go b/service/authorization/authorization_test.go
index 31c2b168a4..f6b82d385f 100644
--- a/service/authorization/authorization_test.go
+++ b/service/authorization/authorization_test.go
@@ -203,7 +203,7 @@ func Test_GetDecisionsAllOf_Pass(t *testing.T) {
{
Id: "ec1",
Entities: []*authorization.Entity{
- {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}},
+ {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT},
},
},
},
@@ -236,7 +236,7 @@ func Test_GetDecisionsAllOf_Pass(t *testing.T) {
{
Id: "ec1",
Entities: []*authorization.Entity{
- {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}},
+ {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT},
},
},
},
@@ -250,7 +250,7 @@ func Test_GetDecisionsAllOf_Pass(t *testing.T) {
{
Id: "ec1",
Entities: []*authorization.Entity{
- {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}},
+ {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT},
},
},
},
@@ -343,7 +343,7 @@ func Test_GetDecisions_AllOf_Fail(t *testing.T) {
{
Id: "ec1",
Entities: []*authorization.Entity{
- {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}},
+ {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT},
},
},
},
@@ -388,6 +388,192 @@ func Test_GetDecisions_AllOf_Fail(t *testing.T) {
assert.Equal(t, authorization.DecisionResponse_DECISION_DENY, resp.GetDecisionResponses()[0].GetDecision())
}
+// Subject entitled and environment entity not entitled -- still pass
+func Test_GetDecisionsAllOfWithEnvironmental_Pass(t *testing.T) {
+ logger := logger.CreateTestLogger()
+
+ listAttributeResp = attr.ListAttributesResponse{}
+
+ attrDef := policy.Attribute{
+ Name: mockAttrName,
+ Namespace: &policy.Namespace{
+ Name: mockNamespace,
+ },
+ Rule: policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ALL_OF,
+ Values: []*policy.Value{
+ {
+ Value: mockAttrValue1,
+ },
+ },
+ }
+ getAttributesByValueFqnsResponse = attr.GetAttributeValuesByFqnsResponse{FqnAttributeValues: map[string]*attr.GetAttributeValuesByFqnsResponse_AttributeAndValue{
+ "https://www.example.org/attr/foo/value/value1": {
+ Attribute: &attrDef,
+ Value: &policy.Value{
+ Fqn: mockFqn1,
+ },
+ },
+ }}
+ userRepresentation := map[string]interface{}{
+ "A": "B",
+ "C": "D",
+ }
+ userStruct, _ := structpb.NewStruct(userRepresentation)
+ resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{
+ EntityRepresentations: []*entityresolution.EntityRepresentation{{
+ OriginalId: "e1",
+ AdditionalProps: []*structpb.Struct{
+ userStruct,
+ },
+ },
+ },
+ }
+
+ testTokenSource := oauth2.StaticTokenSource(&oauth2.Token{
+ AccessToken: "AccessToken",
+ Expiry: time.Now().Add(1 * time.Hour),
+ })
+
+ ctxb := context.Background()
+
+ testrego := rego.New(
+ rego.Query("data.example.p"),
+ rego.Module("example.rego",
+ `package example
+ p = {"e2":["https://www.example.org/attr/foo/value/value1"], "e1":[]} { true }`,
+ ))
+
+ // Run evaluation.
+ prepared, err := testrego.PrepareForEval(ctxb)
+ require.NoError(t, err)
+
+ // set the request
+ req := authorization.GetDecisionsRequest{DecisionRequests: []*authorization.DecisionRequest{
+ {
+ Actions: []*policy.Action{},
+ EntityChains: []*authorization.EntityChain{
+ {
+ Id: "ec1",
+ Entities: []*authorization.Entity{
+ {Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "opentdf"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT},
+ {Id: "e2", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT},
+ },
+ },
+ },
+ ResourceAttributes: []*authorization.ResourceAttribute{
+ {AttributeValueFqns: []string{mockFqn1}},
+ },
+ },
+ }}
+
+ as := AuthorizationService{logger: logger, sdk: &otdf.SDK{
+ Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}},
+ tokenSource: &testTokenSource, eval: prepared}
+
+ resp, err := as.GetDecisions(ctxb, &req)
+
+ require.NoError(t, err)
+ assert.NotNil(t, resp)
+
+ // one entitlement, one attribute value throughout
+ slog.Debug(resp.String())
+ assert.Len(t, resp.GetDecisionResponses(), 1)
+ assert.Equal(t, authorization.DecisionResponse_DECISION_PERMIT, resp.GetDecisionResponses()[0].GetDecision())
+}
+
+// Subject not entitled and environment entity entitled -- still fail
+func Test_GetDecisionsAllOfWithEnvironmental_Fail(t *testing.T) {
+ logger := logger.CreateTestLogger()
+
+ listAttributeResp = attr.ListAttributesResponse{}
+
+ attrDef := policy.Attribute{
+ Name: mockAttrName,
+ Namespace: &policy.Namespace{
+ Name: mockNamespace,
+ },
+ Rule: policy.AttributeRuleTypeEnum_ATTRIBUTE_RULE_TYPE_ENUM_ALL_OF,
+ Values: []*policy.Value{
+ {
+ Value: mockAttrValue1,
+ },
+ },
+ }
+ getAttributesByValueFqnsResponse = attr.GetAttributeValuesByFqnsResponse{FqnAttributeValues: map[string]*attr.GetAttributeValuesByFqnsResponse_AttributeAndValue{
+ "https://www.example.org/attr/foo/value/value1": {
+ Attribute: &attrDef,
+ Value: &policy.Value{
+ Fqn: mockFqn1,
+ },
+ },
+ }}
+ userRepresentation := map[string]interface{}{
+ "A": "B",
+ "C": "D",
+ }
+ userStruct, _ := structpb.NewStruct(userRepresentation)
+ resolveEntitiesResp = entityresolution.ResolveEntitiesResponse{
+ EntityRepresentations: []*entityresolution.EntityRepresentation{{
+ OriginalId: "e1",
+ AdditionalProps: []*structpb.Struct{
+ userStruct,
+ },
+ },
+ },
+ }
+
+ testTokenSource := oauth2.StaticTokenSource(&oauth2.Token{
+ AccessToken: "AccessToken",
+ Expiry: time.Now().Add(1 * time.Hour),
+ })
+
+ ctxb := context.Background()
+
+ testrego := rego.New(
+ rego.Query("data.example.p"),
+ rego.Module("example.rego",
+ `package example
+ p = {"e2":["https://www.example.org/attr/foo/value/value1"], "e1":[]} { true }`,
+ ))
+
+ // Run evaluation.
+ prepared, err := testrego.PrepareForEval(ctxb)
+ require.NoError(t, err)
+
+ // set the request
+ req := authorization.GetDecisionsRequest{DecisionRequests: []*authorization.DecisionRequest{
+ {
+ Actions: []*policy.Action{},
+ EntityChains: []*authorization.EntityChain{
+ {
+ Id: "ec1",
+ Entities: []*authorization.Entity{
+ {Id: "e2", EntityType: &authorization.Entity_ClientId{ClientId: "opentdf"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT},
+ {Id: "e1", EntityType: &authorization.Entity_UserName{UserName: "bob.smith"}, Category: authorization.Entity_CATEGORY_SUBJECT},
+ },
+ },
+ },
+ ResourceAttributes: []*authorization.ResourceAttribute{
+ {AttributeValueFqns: []string{mockFqn1}},
+ },
+ },
+ }}
+
+ as := AuthorizationService{logger: logger, sdk: &otdf.SDK{
+ Attributes: &myAttributesClient{}, EntityResoution: &myERSClient{}},
+ tokenSource: &testTokenSource, eval: prepared}
+
+ resp, err := as.GetDecisions(ctxb, &req)
+
+ require.NoError(t, err)
+ assert.NotNil(t, resp)
+
+ // one entitlement, one attribute value throughout
+ slog.Debug(resp.String())
+ assert.Len(t, resp.GetDecisionResponses(), 1)
+ assert.Equal(t, authorization.DecisionResponse_DECISION_DENY, resp.GetDecisionResponses()[0].GetDecision())
+}
+
func Test_GetEntitlementsSimple(t *testing.T) {
logger := logger.CreateTestLogger()
@@ -452,7 +638,7 @@ func Test_GetEntitlementsSimple(t *testing.T) {
tokenSource: &testTokenSource, eval: prepared}
req := authorization.GetEntitlementsRequest{
- Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}}},
+ Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}},
Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/value1"}},
}
@@ -531,7 +717,7 @@ func Test_GetEntitlementsWithComprehensiveHierarchy(t *testing.T) {
withHierarchy := true
req := authorization.GetEntitlementsRequest{
- Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}}},
+ Entities: []*authorization.Entity{{Id: "e1", EntityType: &authorization.Entity_ClientId{ClientId: "testclient"}, Category: authorization.Entity_CATEGORY_ENVIRONMENT}},
Scope: &authorization.ResourceAttribute{AttributeValueFqns: []string{"https://www.example.org/attr/foo/value/value1"}},
WithComprehensiveHierarchy: &withHierarchy,
}
diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution.go b/service/entityresolution/keycloak/keycloak_entity_resolution.go
index d91636d051..60935fb3ec 100644
--- a/service/entityresolution/keycloak/keycloak_entity_resolution.go
+++ b/service/entityresolution/keycloak/keycloak_entity_resolution.go
@@ -25,7 +25,6 @@ const ErrTextNotFound = "resource not found"
const ClientJwtSelector = "azp"
const UsernameJwtSelector = "preferred_username"
-const UsernameConditionalSelector = "client_id"
const serviceAccountUsernamePrefix = "service-account-"
@@ -357,38 +356,44 @@ func getEntitiesFromToken(ctx context.Context, kcConfig KeycloakConfig, jwtStrin
if !okCast {
return nil, errors.New("error casting extracted value to string")
}
- entities = append(entities, &authorization.Entity{EntityType: &authorization.Entity_ClientId{ClientId: extractedValueCasted}, Id: fmt.Sprintf("jwtentity-%d", entityID)})
+ entities = append(entities, &authorization.Entity{
+ EntityType: &authorization.Entity_ClientId{ClientId: extractedValueCasted},
+ Id: fmt.Sprintf("jwtentity-%d", entityID),
+ Category: authorization.Entity_CATEGORY_ENVIRONMENT})
entityID++
- // extract preferred_username if client isnt present
- _, okExtractConditional := claims[UsernameConditionalSelector]
- if !okExtractConditional { //nolint:nestif // this case has many possible outcomes to handle
- extractedValueUsername, okExp := claims[UsernameJwtSelector]
- if !okExp {
- return nil, errors.New("error extracting selector " + UsernameJwtSelector + " from jwt")
- }
- extractedValueUsernameCasted, okUsernameCast := extractedValueUsername.(string)
- if !okUsernameCast {
- return nil, errors.New("error casting extracted value to string")
- }
+ extractedValueUsername, okExp := claims[UsernameJwtSelector]
+ if !okExp {
+ return nil, errors.New("error extracting selector " + UsernameJwtSelector + " from jwt")
+ }
+ extractedValueUsernameCasted, okUsernameCast := extractedValueUsername.(string)
+ if !okUsernameCast {
+ return nil, errors.New("error casting extracted value to string")
+ }
- // double check for service account
- if strings.HasPrefix(extractedValueUsernameCasted, serviceAccountUsernamePrefix) {
- clientid, err := getServiceAccountClient(ctx, extractedValueUsernameCasted, kcConfig, logger)
- if err != nil {
- return nil, err
- }
- if clientid != "" {
- entities = append(entities, &authorization.Entity{EntityType: &authorization.Entity_ClientId{ClientId: clientid}, Id: fmt.Sprintf("jwtentity-%d", entityID)})
- } else {
- // if the returned clientId is empty, no client found, its not a serive account proceed with username
- entities = append(entities, &authorization.Entity{EntityType: &authorization.Entity_UserName{UserName: extractedValueUsernameCasted}, Id: fmt.Sprintf("jwtentity-%d", entityID)})
- }
+ // double check for service account
+ if strings.HasPrefix(extractedValueUsernameCasted, serviceAccountUsernamePrefix) {
+ clientid, err := getServiceAccountClient(ctx, extractedValueUsernameCasted, kcConfig, logger)
+ if err != nil {
+ return nil, err
+ }
+ if clientid != "" {
+ entities = append(entities, &authorization.Entity{
+ EntityType: &authorization.Entity_ClientId{ClientId: clientid},
+ Id: fmt.Sprintf("jwtentity-%d", entityID),
+ Category: authorization.Entity_CATEGORY_SUBJECT})
} else {
- entities = append(entities, &authorization.Entity{EntityType: &authorization.Entity_UserName{UserName: extractedValueUsernameCasted}, Id: fmt.Sprintf("jwtentity-%d", entityID)})
+ // if the returned clientId is empty, no client found, its not a serive account proceed with username
+ entities = append(entities, &authorization.Entity{
+ EntityType: &authorization.Entity_UserName{UserName: extractedValueUsernameCasted},
+ Id: fmt.Sprintf("jwtentity-%d", entityID),
+ Category: authorization.Entity_CATEGORY_SUBJECT})
}
} else {
- logger.Debug("Did not find conditional value " + UsernameConditionalSelector + " in jwt, proceed")
+ entities = append(entities, &authorization.Entity{
+ EntityType: &authorization.Entity_UserName{UserName: extractedValueUsernameCasted},
+ Id: fmt.Sprintf("jwtentity-%d", entityID),
+ Category: authorization.Entity_CATEGORY_SUBJECT})
}
return entities, nil
diff --git a/service/entityresolution/keycloak/keycloak_entity_resolution_test.go b/service/entityresolution/keycloak/keycloak_entity_resolution_test.go
index e0cf1e40cc..4024e8cb44 100644
--- a/service/entityresolution/keycloak/keycloak_entity_resolution_test.go
+++ b/service/entityresolution/keycloak/keycloak_entity_resolution_test.go
@@ -56,6 +56,10 @@ const byClientIDOpentdfSdkResp = `[
{"id": "opentdfsdkclient", "clientId":"opentdf-sdk"}
]
`
+const byClientIDTDFEntityResResp = `[
+{"id": "tdf-entity-resolution", "clientId":"tdf-entity-resolution"}
+]
+`
const clientCredentialsJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE2MDQsImlhdCI6MTcxNTA5MTMwNCwianRpIjoiMTE3MTYzMjYtNWQyNS00MjlmLWFjMDItNmU0MjE2OWFjMGJhIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiOTljOWVlZDItOTM1Ni00ZjE2LWIwODQtZTgyZDczZjViN2QyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwiYWNyIjoiMSIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJkZWZhdWx0LXJvbGVzLW9wZW50ZGYiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsicmVhbG0tbWFuYWdlbWVudCI6eyJyb2xlcyI6WyJ2aWV3LXVzZXJzIiwidmlldy1jbGllbnRzIiwicXVlcnktY2xpZW50cyIsInF1ZXJ5LWdyb3VwcyIsInF1ZXJ5LXVzZXJzIl19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6InByb2ZpbGUgZW1haWwiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImNsaWVudEhvc3QiOiIxOTIuMTY4LjI0MC4xIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2VydmljZS1hY2NvdW50LXRkZi1lbnRpdHktcmVzb2x1dGlvbiIsImNsaWVudEFkZHJlc3MiOiIxOTIuMTY4LjI0MC4xIiwiY2xpZW50X2lkIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uIn0.h29QLo-QvIc67KKqU_e1-x6G_o5YQccOyW9AthMdB7xhn9C1dBrcScytaWq1RfETPmnM8MXGezqN4OpXrYr-zbkHhq9ha0Ib-M1VJXNgA5sbgKW9JxGQyudmYPgn4fimDCJtAsXo7C-e3mYNm6DJS0zhGQ3msmjLTcHmIPzWlj7VjtPgKhYV75b7yr_yZNBdHjf3EZqfynU2sL8bKa1w7DYDNQve7ThtD4MeKLiuOQHa3_23dECs_ptvPVks7pLGgRKfgGHBC-KQuopjtxIhwkz2vOWRzugDl0aBJMHfwBajYhgZ2YRlV9dqSxmy8BOj4OEXuHbiyfIpY0rCRpSrGg"
const passwordPubClientJwt = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI0OXRmSjByRUo4c0YzUjJ3Yi05eENHVXhYUEQ4RTZldmNsRG1hZ05EM3lBIn0.eyJleHAiOjE3MTUwOTE0ODAsImlhdCI6MTcxNTA5MTE4MCwianRpIjoiZmI5MmM2MTAtYmI0OC00ZDgyLTljZGQtOWFhZjllNzEyNzc3IiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4ODg4L2F1dGgvcmVhbG1zL29wZW50ZGYiLCJhdWQiOlsiaHR0cDovL2xvY2FsaG9zdDo4ODg4IiwidGRmLWVudGl0eS1yZXNvbHV0aW9uIiwicmVhbG0tbWFuYWdlbWVudCIsImFjY291bnQiXSwic3ViIjoiMmU2YzE1ODAtY2ZkMy00M2FiLWIxNzMtZjZjM2JmOGZmNGUyIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoidGRmLWVudGl0eS1yZXNvbHV0aW9uLXB1YmxpYyIsInNlc3Npb25fc3RhdGUiOiIzN2E3YjdiOS0xZmNlLTQxMmYtOTI1OS1lYzUxMTY3MGVhMGYiLCJhY3IiOiIxIiwiYWxsb3dlZC1vcmlnaW5zIjpbIi8qIl0sInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJvcGVudGRmLW9yZy1hZG1pbiIsImRlZmF1bHQtcm9sZXMtb3BlbnRkZiIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJ0ZGYtZW50aXR5LXJlc29sdXRpb24iOnsicm9sZXMiOlsiZW50aXR5LXJlc29sdXRpb24tdGVzdC1yb2xlIl19LCJyZWFsbS1tYW5hZ2VtZW50Ijp7InJvbGVzIjpbInZpZXctdXNlcnMiLCJ2aWV3LWNsaWVudHMiLCJxdWVyeS1jbGllbnRzIiwicXVlcnktZ3JvdXBzIiwicXVlcnktdXNlcnMiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoicHJvZmlsZSBlbWFpbCIsInNpZCI6IjM3YTdiN2I5LTFmY2UtNDEyZi05MjU5LWVjNTExNjcwZWEwZiIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwibmFtZSI6InNhbXBsZSB1c2VyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoic2FtcGxlLXVzZXIiLCJnaXZlbl9uYW1lIjoic2FtcGxlIiwiZmFtaWx5X25hbWUiOiJ1c2VyIiwiZW1haWwiOiJzYW1wbGV1c2VyQHNhbXBsZS5jb20ifQ.Gd_OvPNY7UfY7sBKh55TcvWQHmAkYZ2Jb2VyK1lYgse9EBEa_y3uoepZYrGMGkmYdwApg4eauQjxzT_BZYVBc7u9ch3HY_IUuSh3A6FkDDXZIziByP63FYiI4vKTp0w7e2-oYAdaUTDJ1Y50-l_VvRWjdc4fqi-OKH4t8D1rlq0GJ-P7uOl44Ta43YdBMuXI146-eLqx_zLIC49Pg5Y7MD_Lv23QfGTHTP47ckUQueXoGegNLQNE9nPTuD6lNzHD5_MOqse4IKzoWVs_hs4S8SqVxVlN_ZWXkcGhPllfQtf1qxLyFm51eYH3LGxqyNbGr4nQc8djPV0yWqOTrg8IYQ"
@@ -303,7 +307,10 @@ func Test_KCEntityResolutionNotFoundError(t *testing.T) {
}
func Test_JwtClientAndUsernameClientCredentials(t *testing.T) {
- server := testServer(t, nil, nil, nil, nil, nil)
+ csqr := map[string]string{
+ "clientId=tdf-entity-resolution": byClientIDTDFEntityResResp,
+ }
+ server := testServer(t, nil, nil, nil, nil, csqr)
defer server.Close()
var kcconfig = testKeycloakConfig(server)
@@ -317,8 +324,11 @@ func Test_JwtClientAndUsernameClientCredentials(t *testing.T) {
require.NoError(t, reserr)
assert.Len(t, resp.GetEntityChains(), 1)
- assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 1)
+ assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
+ assert.Equal(t, "tdf-entity-resolution", resp.GetEntityChains()[0].GetEntities()[1].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtClientAndUsernamePasswordPub(t *testing.T) {
@@ -338,7 +348,9 @@ func Test_JwtClientAndUsernamePasswordPub(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 1)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution-public", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "sample-user", resp.GetEntityChains()[0].GetEntities()[1].GetUserName())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtClientAndUsernamePasswordPriv(t *testing.T) {
@@ -358,7 +370,9 @@ func Test_JwtClientAndUsernamePasswordPriv(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 1)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "sample-user", resp.GetEntityChains()[0].GetEntities()[1].GetUserName())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtClientAndUsernameAuthPub(t *testing.T) {
@@ -378,7 +392,9 @@ func Test_JwtClientAndUsernameAuthPub(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 1)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution-public", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "sample-user", resp.GetEntityChains()[0].GetEntities()[1].GetUserName())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtClientAndUsernameAuthPriv(t *testing.T) {
@@ -398,7 +414,9 @@ func Test_JwtClientAndUsernameAuthPriv(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 1)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "sample-user", resp.GetEntityChains()[0].GetEntities()[1].GetUserName())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtClientAndUsernameImplicitPub(t *testing.T) {
@@ -418,7 +436,9 @@ func Test_JwtClientAndUsernameImplicitPub(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 1)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution-public", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "sample-user", resp.GetEntityChains()[0].GetEntities()[1].GetUserName())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtClientAndUsernameImplicitPriv(t *testing.T) {
@@ -438,7 +458,9 @@ func Test_JwtClientAndUsernameImplicitPriv(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 1)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "sample-user", resp.GetEntityChains()[0].GetEntities()[1].GetUserName())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtClientAndClientTokenExchange(t *testing.T) {
@@ -461,7 +483,9 @@ func Test_JwtClientAndClientTokenExchange(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 1)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "opentdf", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "opentdf-sdk", resp.GetEntityChains()[0].GetEntities()[1].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
}
func Test_JwtMultiple(t *testing.T) {
@@ -484,11 +508,15 @@ func Test_JwtMultiple(t *testing.T) {
assert.Len(t, resp.GetEntityChains(), 2)
assert.Len(t, resp.GetEntityChains()[0].GetEntities(), 2)
assert.Equal(t, "opentdf", resp.GetEntityChains()[0].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[0].GetEntities()[0].GetCategory())
assert.Equal(t, "opentdf-sdk", resp.GetEntityChains()[0].GetEntities()[1].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[0].GetEntities()[1].GetCategory())
assert.Len(t, resp.GetEntityChains()[1].GetEntities(), 2)
assert.Equal(t, "tdf-entity-resolution", resp.GetEntityChains()[1].GetEntities()[0].GetClientId())
+ assert.Equal(t, authorization.Entity_CATEGORY_ENVIRONMENT, resp.GetEntityChains()[1].GetEntities()[0].GetCategory())
assert.Equal(t, "sample-user", resp.GetEntityChains()[1].GetEntities()[1].GetUserName())
+ assert.Equal(t, authorization.Entity_CATEGORY_SUBJECT, resp.GetEntityChains()[1].GetEntities()[1].GetCategory())
}
func Test_KCEntityResolutionNotFoundInferEmail(t *testing.T) {