diff --git a/README.md b/README.md index 96e4525..afbb77a 100644 --- a/README.md +++ b/README.md @@ -185,9 +185,11 @@ In the future related code and configurations for both additional languages (Jav Python) will be extracted into separate repositories. ### Open Issues -- Finalizing messaging schema -- Extraction of python / java configurations and code +- Check TODOs in the code +- Finalizing messaging schema + - Check if fields and constraints are correct and compatible with expected use cases + - Check that routing api specific parameters are independent of AuditEventLog +- Clarify if a mutex is needed? Should we provide a MutexMessagingApi? - Clarify if `client.go` file can be used for licence / legal reasons -- Clean up repo (delete main.go, etc. files) -- Finalizing API Design - - Decision whether serialized payload should be replaced with []byte or base64 encoded string \ No newline at end of file +- Extraction of python / java configurations and code +- Clean up repo (delete main.go, etc. files) diff --git a/audit/api/api.go b/audit/api/api.go index a60f1fd..49336aa 100644 --- a/audit/api/api.go +++ b/audit/api/api.go @@ -119,6 +119,24 @@ type CloudEvent struct { // The serialized payload data []byte + + // Optional W3C conform trace parent: + // https://www.w3.org/TR/trace-context/#traceparent-header + // + // Format: --- + // + // Examples: + // "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" + traceParent *string + + // Optional W3C conform trace state header: + // https://www.w3.org/TR/trace-context/#tracestate-header + // + // Format: =[,=] + // + // Examples: + // "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE" + traceState *string } // RoutingIdentifierType is an enumeration of allowed identifier types. diff --git a/audit/api/api_common.go b/audit/api/api_common.go index 49b7606..a6f1b0f 100644 --- a/audit/api/api_common.go +++ b/audit/api/api_common.go @@ -11,7 +11,8 @@ import ( "google.golang.org/protobuf/proto" ) -const ContentTypeProtobuf = "application/x-protobuf" +// ContentTypeCloudEventsProtobuf the cloudevents protobuf content-type sent in metadata of messages +const ContentTypeCloudEventsProtobuf = "application/cloudevents+protobuf" // ErrEventNil indicates that the event was nil var ErrEventNil = errors.New("event is nil") @@ -109,7 +110,7 @@ func validateAndSerializePartially( } routableEvent := auditV1.RoutableAuditEvent{ - EventName: event.LogName, + EventName: event.ProtoPayload.MethodName, Visibility: visibility, Data: &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &payload}, } @@ -155,6 +156,8 @@ func send( return err } + // Naming according to AMQP protocol binding spec + // https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/amqp-protocol-binding.md applicationAttributes := make(map[string]any) applicationAttributes["cloudEvents:specversion"] = cloudEvent.specVersion applicationAttributes["cloudEvents:source"] = cloudEvent.source @@ -163,6 +166,12 @@ func send( applicationAttributes["cloudEvents:datacontenttype"] = cloudEvent.dataContentType applicationAttributes["cloudEvents:type"] = cloudEvent.dataType applicationAttributes["cloudEvents:subject"] = cloudEvent.subject + if cloudEvent.traceParent != nil { + applicationAttributes["cloudEvents:traceparent"] = cloudEvent.traceParent + } + if cloudEvent.traceState != nil { + applicationAttributes["cloudEvents:tracestate"] = cloudEvent.traceState + } return (*messagingApi).Send( ctx, diff --git a/audit/api/api_common_test.go b/audit/api/api_common_test.go index 3fc0391..9e607a3 100644 --- a/audit/api/api_common_test.go +++ b/audit/api/api_common_test.go @@ -2,14 +2,10 @@ package api import ( "context" - "errors" - "google.golang.org/protobuf/types/known/timestamppb" - "google.golang.org/protobuf/types/known/wrapperspb" - "testing" - "time" - "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/audit/messaging" auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1" + "errors" + "testing" "github.com/bufbuild/protovalidate-go" "github.com/google/uuid" @@ -69,104 +65,16 @@ func Test_ValidateAndSerializePartially_EventNil(t *testing.T) { assert.ErrorIs(t, err, ErrEventNil) } -func Test_ValidateAndSerializePartially_AuditEventSequenceNumber(t *testing.T) { - validator := NewValidator(t) - - t.Run("Sequence number too low", func(t *testing.T) { - event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil) - event.SequenceNumber = wrapperspb.Int64(-2) - - _, err := validateAndSerializePartially( - &validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier) - - assert.EqualError(t, err, "validation error:\n - sequence_number: value must be greater than or equal to -1 [int64.gte]") - }) - - t.Run("Sequence number is minimum", func(t *testing.T) { - event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil) - event.SequenceNumber = wrapperspb.Int64(-1) - - e, err := validateAndSerializePartially( - &validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier) - - assert.NoError(t, err) - validateSequenceNumber(t, e, -1) - }) - - t.Run("Sequence number is default", func(t *testing.T) { - event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil) - event.SequenceNumber = wrapperspb.Int64(0) - - e, err := validateAndSerializePartially( - &validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier) - - assert.NoError(t, err) - validateSequenceNumber(t, e, 0) - }) - - t.Run("Sequence number is greater than default", func(t *testing.T) { - event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil) - event.SequenceNumber = wrapperspb.Int64(1) - - e, err := validateAndSerializePartially( - &validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier) - - assert.NoError(t, err) - validateSequenceNumber(t, e, 1) - }) - - t.Run("Sequence number not set", func(t *testing.T) { - event := &auditV1.AuditEvent{ - EventSource: "resource-manager", - Region: auditV1.Region_REGION_EU01, - EventName: "ORGANIZATION_CREATED", - EventTimeStamp: timestamppb.New(time.Now()), - EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT, - Initiator: &auditV1.Principal{ - Id: uuid.NewString(), - }, - } - - identifier := uuid.New() - routingIdentifier := &RoutingIdentifier{ - Identifier: identifier, - Type: RoutingIdentifierTypeOrganization, - } - - objectIdentifier := &auditV1.ObjectIdentifier{ - Identifier: identifier.String(), - Type: auditV1.ObjectType_OBJECT_TYPE_ORGANIZATION, - } - event.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier} - - _, err := validateAndSerializePartially( - &validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier) - - assert.EqualError(t, err, "validation error:\n - sequence_number: value is required [required]") - }) - -} -func validateSequenceNumber(t *testing.T, event *auditV1.RoutableAuditEvent, expectedNumber int64) { - switch data := event.GetData().(type) { - case *auditV1.RoutableAuditEvent_UnencryptedData: - var auditEvent auditV1.AuditEvent - assert.NoError(t, proto.Unmarshal(data.UnencryptedData.Data, &auditEvent)) - assert.Equal(t, expectedNumber, auditEvent.SequenceNumber.Value) - default: - assert.Fail(t, "expected unencrypted data") - } -} - func Test_ValidateAndSerializePartially_AuditEventValidationFailed(t *testing.T) { validator := NewValidator(t) event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil) - event.EventName = "" + event.LogName = "" _, err := validateAndSerializePartially( &validator, event, auditV1.Visibility_VISIBILITY_PUBLIC, routingIdentifier, objectIdentifier) - assert.EqualError(t, err, "validation error:\n - event_name: value is required [required]") + assert.EqualError(t, err, "validation error:\n - log_name: value is required [required]") } func Test_ValidateAndSerializePartially_RoutableEventValidationFailed(t *testing.T) { diff --git a/audit/api/api_legacy.go b/audit/api/api_legacy.go index 502399f..3dad2bd 100644 --- a/audit/api/api_legacy.go +++ b/audit/api/api_legacy.go @@ -15,6 +15,8 @@ import ( "google.golang.org/protobuf/proto" ) +var ErrUnsupportedSeverity = errors.New("unsupported severity level") + // LegacyTopicNameResolver implements TopicNameResolver. // A hard-coded topic name is used, routing identifiers are ignored. type LegacyTopicNameResolver struct { @@ -50,7 +52,7 @@ func NewLegacyAuditApi( ) (*AuditApi, error) { if messagingApi == nil { - return nil, errors.New("messaging api nil") + return nil, ErrMessagingApiNil } // Topic resolver @@ -115,11 +117,14 @@ func (a *LegacyAuditApi) ValidateAndSerialize( // TODO what is the correct id? id: uuid.NewString(), time: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), - dataContentType: "application/cloudevents+protobuf", + dataContentType: ContentTypeCloudEventsProtobuf, dataType: fmt.Sprintf("%v", routableEvent.ProtoReflect().Descriptor().FullName()), // TODO check if this is correct subject: event.ProtoPayload.ResourceName, data: legacyBytes, + // TODO set trace fields + traceParent: nil, + traceState: nil, } return &message, nil } @@ -160,13 +165,14 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat( case *auditV1.ServiceAccountDelegationInfo_IdpPrincipal_: principals = append(principals, LegacyAuditEventPrincipal{ Id: principalValue.IdpPrincipal.PrincipalId, - Email: principalValue.IdpPrincipal.PrincipalEmail, + Email: &principalValue.IdpPrincipal.PrincipalEmail, }) case *auditV1.ServiceAccountDelegationInfo_SystemPrincipal_: principals = append(principals, LegacyAuditEventPrincipal{ Id: "system", }) - + default: + return nil, errors.New("unsupported principal type") } } serviceAccountDelegationInfo = &LegacyAuditEventServiceAccountDelegationInfo{Principals: principals} @@ -179,11 +185,18 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat( } } else { var parameters map[string]interface{} = nil - if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" && event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" { - parsedUrl, err := url.Parse(fmt.Sprintf("%s?%s", event.ProtoPayload.RequestMetadata.RequestAttributes.Path, event.ProtoPayload.RequestMetadata.RequestAttributes.Query)) + if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" && + event.ProtoPayload.RequestMetadata.RequestAttributes.Query != nil && + *event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" { + parameters = map[string]interface{}{} + + parsedUrl, err := url.Parse(fmt.Sprintf("%s?%s", + event.ProtoPayload.RequestMetadata.RequestAttributes.Path, + *event.ProtoPayload.RequestMetadata.RequestAttributes.Query)) if err != nil { return nil, err } + for k, v := range parsedUrl.Query() { parameters[k] = v } @@ -258,13 +271,38 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat( // Result var result = event.ProtoPayload.Response.AsMap() + // Severity + var severity string + switch event.Severity { + case auditV1.LogSeverity_DEFAULT: + fallthrough + case auditV1.LogSeverity_DEBUG: + fallthrough + case auditV1.LogSeverity_INFO: + fallthrough + case auditV1.LogSeverity_NOTICE: + fallthrough + case auditV1.LogSeverity_WARNING: + severity = "INFO" + case auditV1.LogSeverity_ERROR: + fallthrough + case auditV1.LogSeverity_CRITICAL: + fallthrough + case auditV1.LogSeverity_ALERT: + fallthrough + case auditV1.LogSeverity_EMERGENCY: + severity = "ERROR" + default: + return nil, ErrUnsupportedSeverity + } + // Instantiate the legacy event - missing values are filled with defaults legacyAuditEvent := LegacyAuditEvent{ - Severity: "INFO", + Severity: severity, Visibility: visibility, EventType: eventType, EventTimeStamp: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), - EventName: event.LogName, + EventName: event.ProtoPayload.MethodName, SourceIpAddress: sourceIpAddress, UserAgent: userAgent, Initiator: LegacyAuditEventPrincipal{ @@ -274,11 +312,12 @@ func (a *LegacyAuditApi) convertAndSerializeIntoLegacyFormat( ServiceAccountDelegationInfo: serviceAccountDelegationInfo, Request: request, Context: messageContext, - ResourceId: &event.LogName, - ResourceName: &event.ProtoPayload.ResourceName, - CorrelationId: &event.CorrelationId, - Result: &result, - Details: &details, + // TODO clarify + ResourceId: &event.LogName, + ResourceName: &event.ProtoPayload.ResourceName, + CorrelationId: event.CorrelationId, + Result: &result, + Details: &details, } bytes, err := json.Marshal(legacyAuditEvent) diff --git a/audit/api/api_legacy_test.go b/audit/api/api_legacy_test.go index 0f1fc17..6faa348 100644 --- a/audit/api/api_legacy_test.go +++ b/audit/api/api_legacy_test.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "errors" + "fmt" "log/slog" + "net/url" "os" "testing" "time" @@ -320,14 +322,14 @@ func TestLegacyAuditApi(t *testing.T) { var auditEvent LegacyAuditEvent assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) - assert.Equal(t, event.EventName, auditEvent.EventName) - assert.Equal(t, event.EventTimeStamp.AsTime(), auditEvent.EventTimeStamp) - assert.Equal(t, event.Initiator.Id, auditEvent.Initiator.Id) + assert.Equal(t, event.ProtoPayload.MethodName, auditEvent.EventName) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp) + assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id) assert.Equal(t, "SYSTEM_EVENT", auditEvent.EventType) assert.Equal(t, "INFO", auditEvent.Severity) - assert.Equal(t, "none", auditEvent.Request.Endpoint) - assert.Equal(t, "0.0.0.0", auditEvent.SourceIpAddress) - assert.Equal(t, "none", auditEvent.UserAgent) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint) + assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress) + assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent) }) t.Run("Log event with details", func(t *testing.T) { @@ -350,7 +352,7 @@ func TestLegacyAuditApi(t *testing.T) { assert.NoError(t, err) // Instantiate test data - event, routingIdentifier, objectIdentifier := NewOrganizationAuditEventWithDetails() + event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PUBLIC @@ -369,7 +371,7 @@ func TestLegacyAuditApi(t *testing.T) { }) } -func validateSentMessage(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditEvent) { +func validateSentMessage(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditLogEntry) { // Check topic name assert.Equal(t, topicName, *message.Properties.To) @@ -377,43 +379,88 @@ func validateSentMessage(t *testing.T, topicName string, message *amqp.Message, var auditEvent LegacyAuditEvent assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) - assert.Equal(t, event.EventName, auditEvent.EventName) - assert.Equal(t, event.EventTimeStamp.AsTime(), auditEvent.EventTimeStamp) - assert.Equal(t, event.Initiator.Id, auditEvent.Initiator.Id) - assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType) - assert.Equal(t, "INFO", auditEvent.Severity) - assert.Equal(t, "none", auditEvent.Request.Endpoint) - assert.Equal(t, "0.0.0.0", auditEvent.SourceIpAddress) - assert.Equal(t, "none", auditEvent.UserAgent) -} - -func validateSentMessageWithDetails(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditEvent) { - // Check topic name - assert.Equal(t, topicName, *message.Properties.To) - - // Check deserialized message - var auditEvent LegacyAuditEvent - assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) - - assert.Equal(t, event.EventName, auditEvent.EventName) - assert.Equal(t, event.EventTimeStamp.AsTime(), auditEvent.EventTimeStamp) - assert.Equal(t, event.Initiator.Id, auditEvent.Initiator.Id) - assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType) - assert.Equal(t, "INFO", auditEvent.Severity) - assert.Equal(t, event.Request.Endpoint, auditEvent.Request.Endpoint) - assert.Equal(t, event.Request.SourceIpAddress, auditEvent.SourceIpAddress) - assert.Equal(t, *event.Request.UserAgent, auditEvent.UserAgent) - assert.Equal(t, event.Request.Body.AsMap(), *auditEvent.Request.Body) - assert.Equal(t, event.Request.Parameters.AsMap(), *auditEvent.Request.Parameters) - assert.Equal(t, event.Details.AsMap(), *auditEvent.Details) - assert.Equal(t, event.Result.AsMap(), *auditEvent.Result) - for _, header := range event.Request.Headers { - assert.Equal(t, header.Value, (*auditEvent.Request.Headers)[header.Key]) + var severity string + switch event.Severity { + case auditV1.LogSeverity_DEFAULT: + fallthrough + case auditV1.LogSeverity_DEBUG: + fallthrough + case auditV1.LogSeverity_INFO: + fallthrough + case auditV1.LogSeverity_NOTICE: + fallthrough + case auditV1.LogSeverity_WARNING: + severity = "INFO" + case auditV1.LogSeverity_ERROR: + fallthrough + case auditV1.LogSeverity_CRITICAL: + fallthrough + case auditV1.LogSeverity_ALERT: + fallthrough + case auditV1.LogSeverity_EMERGENCY: + severity = "ERROR" + default: + assert.Fail(t, "unknown log severity") } - for idx := range event.Principals { - assert.Equal(t, event.Principals[idx].Id, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id) - assert.Equal(t, event.Principals[idx].Email, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Email) + assert.Equal(t, event.ProtoPayload.MethodName, auditEvent.EventName) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp) + assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id) + assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType) + assert.Equal(t, severity, auditEvent.Severity) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint) + assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress) + assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent) +} + +func validateSentMessageWithDetails(t *testing.T, topicName string, message *amqp.Message, event *auditV1.AuditLogEntry) { + // Check topic name + assert.Equal(t, topicName, *message.Properties.To) + + // Check deserialized message + var auditEvent LegacyAuditEvent + assert.NoError(t, json.Unmarshal(message.Data[0], &auditEvent)) + + assert.Equal(t, event.ProtoPayload.MethodName, auditEvent.EventName) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), auditEvent.EventTimeStamp) + assert.Equal(t, event.ProtoPayload.AuthenticationInfo.PrincipalId, auditEvent.Initiator.Id) + assert.Equal(t, "ADMIN_ACTIVITY", auditEvent.EventType) + assert.Equal(t, "INFO", auditEvent.Severity) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Path, auditEvent.Request.Endpoint) + var parameters map[string]interface{} = nil + if event.ProtoPayload.RequestMetadata.RequestAttributes.Path != "" && + event.ProtoPayload.RequestMetadata.RequestAttributes.Query != nil && + *event.ProtoPayload.RequestMetadata.RequestAttributes.Query != "" { + parameters = map[string]interface{}{} + + parsedUrl, err := url.Parse(fmt.Sprintf("%s?%s", + event.ProtoPayload.RequestMetadata.RequestAttributes.Path, + *event.ProtoPayload.RequestMetadata.RequestAttributes.Query)) + + assert.NoError(t, err) + for k, v := range parsedUrl.Query() { + parameters[k] = v + } + } + assert.Equal(t, event.ProtoPayload.Request.AsMap(), *auditEvent.Request.Body) + assert.Equal(t, parameters, *auditEvent.Request.Parameters) + for key, value := range event.ProtoPayload.RequestMetadata.RequestAttributes.Headers { + assert.Equal(t, value, (*auditEvent.Request.Headers)[key]) + } + assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerIp, auditEvent.SourceIpAddress) + assert.Equal(t, event.ProtoPayload.RequestMetadata.CallerSuppliedUserAgent, auditEvent.UserAgent) + assert.Equal(t, event.ProtoPayload.Request.AsMap(), *auditEvent.Details) + assert.Equal(t, event.ProtoPayload.Response.AsMap(), *auditEvent.Result) + assert.True(t, auditEvent.Context.OrganizationId != nil || auditEvent.Context.FolderId != nil || auditEvent.Context.ProjectId != nil) + + for idx, principal := range event.ProtoPayload.AuthenticationInfo.ServiceAccountDelegationInfo { + switch principalValue := principal.Authority.(type) { + case *auditV1.ServiceAccountDelegationInfo_IdpPrincipal_: + assert.Equal(t, principalValue.IdpPrincipal.PrincipalId, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id) + assert.Equal(t, principalValue.IdpPrincipal.PrincipalEmail, auditEvent.ServiceAccountDelegationInfo.Principals[idx].Email) + case *auditV1.ServiceAccountDelegationInfo_SystemPrincipal_: + assert.Equal(t, "system", auditEvent.ServiceAccountDelegationInfo.Principals[idx].Id) + } } } @@ -458,7 +505,7 @@ func TestLegacyAuditApi_Log_NilEvent(t *testing.T) { } func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormatInvalidObjectIdentifierType(t *testing.T) { - customization := func(event *auditV1.AuditEvent, + customization := func(event *auditV1.AuditLogEntry, routingIdentifier *RoutingIdentifier, objectIdentifier *auditV1.ObjectIdentifier) { objectIdentifier.Type = 4 @@ -477,7 +524,7 @@ func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormatInvalidObjectIdentifi func TestLegacyAuditApi_ConvertAndSerializeIntoLegacyFormat_NoResourceReference(t *testing.T) { event, _, _ := NewProjectAuditEvent(nil) routableEvent := auditV1.RoutableAuditEvent{ - EventName: event.EventName, + EventName: event.ProtoPayload.MethodName, Visibility: auditV1.Visibility_VISIBILITY_PUBLIC, ResourceReference: nil, Data: nil, diff --git a/audit/api/api_mock.go b/audit/api/api_mock.go index 4769f86..ea97698 100644 --- a/audit/api/api_mock.go +++ b/audit/api/api_mock.go @@ -69,6 +69,9 @@ func (a *MockAuditApi) ValidateAndSerialize( // TODO check if this is correct subject: event.ProtoPayload.ResourceName, data: routableEventBytes, + // TODO set trace fields + traceParent: nil, + traceState: nil, } return &message, nil diff --git a/audit/api/api_mock_test.go b/audit/api/api_mock_test.go index ff6f42d..5fc4697 100644 --- a/audit/api/api_mock_test.go +++ b/audit/api/api_mock_test.go @@ -31,7 +31,7 @@ func TestMockAuditApi_Log(t *testing.T) { assert.NoError(t, err) validateRoutableEventPayload( - t, cloudEvent.data, routingIdentifier, objectIdentifier, event, event.EventName, visibility) + t, cloudEvent.data, routingIdentifier, objectIdentifier, event, event.ProtoPayload.MethodName, visibility) }) t.Run("ValidateAndSerialize event nil", func(t *testing.T) { diff --git a/audit/api/api_routable.go b/audit/api/api_routable.go index 5d78535..093f46c 100644 --- a/audit/api/api_routable.go +++ b/audit/api/api_routable.go @@ -128,11 +128,14 @@ func (a *routableAuditApi) ValidateAndSerialize( // TODO what is the correct id? id: uuid.NewString(), time: event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime(), - dataContentType: "application/cloudevents+protobuf", + dataContentType: ContentTypeCloudEventsProtobuf, dataType: fmt.Sprintf("%v", routableEvent.ProtoReflect().Descriptor().FullName()), // TODO check if this is correct subject: event.ProtoPayload.ResourceName, data: routableEventBytes, + // TODO set trace fields + traceParent: nil, + traceState: nil, } return &message, nil diff --git a/audit/api/api_routable_test.go b/audit/api/api_routable_test.go index bd8c586..ff37a40 100644 --- a/audit/api/api_routable_test.go +++ b/audit/api/api_routable_test.go @@ -83,7 +83,7 @@ func TestRoutableAuditApi(t *testing.T) { routingIdentifier, objectIdentifier, event, - "ORGANIZATION_CREATED", + "stackit.resourcemanager.v2.organization.created", visibility) }) @@ -123,7 +123,7 @@ func TestRoutableAuditApi(t *testing.T) { routingIdentifier, objectIdentifier, event, - "ORGANIZATION_CREATED", + "stackit.resourcemanager.v2.organization.created", visibility) }) @@ -159,7 +159,7 @@ func TestRoutableAuditApi(t *testing.T) { routingIdentifier, objectIdentifier, event, - "FOLDER_CREATED", + "stackit.resourcemanager.v2.folder.created", visibility) }) @@ -197,7 +197,7 @@ func TestRoutableAuditApi(t *testing.T) { routingIdentifier, objectIdentifier, event, - "FOLDER_CREATED", + "stackit.resourcemanager.v2.folder.created", visibility) }) @@ -234,7 +234,7 @@ func TestRoutableAuditApi(t *testing.T) { routingIdentifier, objectIdentifier, event, - "PROJECT_CREATED", + "stackit.resourcemanager.v2.project.created", visibility) }) @@ -270,7 +270,7 @@ func TestRoutableAuditApi(t *testing.T) { routingIdentifier, objectIdentifier, event, - "PROJECT_CREATED", + "stackit.resourcemanager.v2.project.created", visibility) }) @@ -309,7 +309,7 @@ func TestRoutableAuditApi(t *testing.T) { assert.Equal(t, "resource-manager", applicationProperties["cloudEvents:source"]) _, isUuid := uuid.Parse(fmt.Sprintf("%s", applicationProperties["cloudEvents:id"])) assert.True(t, true, isUuid) - assert.Equal(t, event.EventTimeStamp.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"]) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"]) assert.Equal(t, "application/cloudevents+protobuf", applicationProperties["cloudEvents:datacontenttype"]) assert.Equal(t, "audit.v1.RoutableAuditEvent", applicationProperties["cloudEvents:type"]) @@ -320,7 +320,7 @@ func TestRoutableAuditApi(t *testing.T) { nil, nil, event, - "SYSTEM_CHANGED", + "stackit.resourcemanager.v2.system.changed", visibility) }) @@ -334,7 +334,7 @@ func TestRoutableAuditApi(t *testing.T) { assert.NoError(t, solaceContainer.TopicSubscriptionCreate(ctx, queueName, "org/*")) // Instantiate test data - event, routingIdentifier, objectIdentifier := NewOrganizationAuditEventWithDetails() + event, routingIdentifier, objectIdentifier := NewOrganizationAuditEvent(nil) // Log the event to solace visibility := auditV1.Visibility_VISIBILITY_PUBLIC @@ -356,7 +356,7 @@ func TestRoutableAuditApi(t *testing.T) { routingIdentifier, objectIdentifier, event, - "ORGANIZATION_CREATED", + "stackit.resourcemanager.v2.organization.created", visibility) }) } @@ -367,7 +367,7 @@ func validateSentEvent( message *amqp.Message, routingIdentifier *RoutingIdentifier, objectIdentifier *auditV1.ObjectIdentifier, - event *auditV1.AuditEvent, + event *auditV1.AuditLogEntry, eventName string, visibility auditV1.Visibility, ) { @@ -383,7 +383,7 @@ func validateSentEvent( assert.Equal(t, "resource-manager", applicationProperties["cloudEvents:source"]) _, isUuid := uuid.Parse(fmt.Sprintf("%s", applicationProperties["cloudEvents:id"])) assert.True(t, true, isUuid) - assert.Equal(t, event.EventTimeStamp.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"]) + assert.Equal(t, event.ProtoPayload.RequestMetadata.RequestAttributes.Time.AsTime().UnixMilli(), applicationProperties["cloudEvents:time"]) assert.Equal(t, "application/cloudevents+protobuf", applicationProperties["cloudEvents:datacontenttype"]) assert.Equal(t, "audit.v1.RoutableAuditEvent", applicationProperties["cloudEvents:type"]) @@ -397,7 +397,7 @@ func validateRoutableEventPayload( payload []byte, routingIdentifier *RoutingIdentifier, objectIdentifier *auditV1.ObjectIdentifier, - event *auditV1.AuditEvent, + event *auditV1.AuditLogEntry, eventName string, visibility auditV1.Visibility, ) { @@ -432,7 +432,7 @@ func validateRoutableEventPayload( assert.Fail(t, "Object name not expected") } - var auditEvent auditV1.AuditEvent + var auditEvent auditV1.AuditLogEntry switch data := routableAuditEvent.Data.(type) { case *auditV1.RoutableAuditEvent_UnencryptedData: assert.NoError(t, proto.Unmarshal(data.UnencryptedData.Data, &auditEvent)) diff --git a/audit/api/test_data.go b/audit/api/test_data.go index e5352ff..a21bde9 100644 --- a/audit/api/test_data.go +++ b/audit/api/test_data.go @@ -1,6 +1,7 @@ package api import ( + "fmt" "google.golang.org/protobuf/types/known/wrapperspb" "time" @@ -22,19 +23,74 @@ func NewOrganizationAuditEvent( *auditV1.ObjectIdentifier, ) { + identifier := uuid.New() + permission := "resourcemanager.organization.edit" + permissionGranted := true + requestId := fmt.Sprintf("%s/1", identifier) + claims, _ := structpb.NewStruct(map[string]interface{}{}) + request, _ := structpb.NewStruct(map[string]interface{}{}) + response, _ := structpb.NewStruct(map[string]interface{}{}) + correlationId := "cad100e2-e139-43b9-8c3b-335731e032bc" + headers := make(map[string]string) + headers["Content-Type"] = "application/json" + labels := make(map[string]string) + labels["label1"] = "value1" auditEvent := &auditV1.AuditLogEntry{ - EventSource: "resource-manager", - Region: auditV1.Region_REGION_EU01, - SequenceNumber: wrapperspb.Int64(0), - EventName: "ORGANIZATION_CREATED", - EventTimeStamp: timestamppb.New(time.Now()), - EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT, - Initiator: &auditV1.Principal{ - Id: uuid.NewString(), + LogName: fmt.Sprintf("organizations/%s/logs/admin-activity", identifier), + ProtoPayload: &auditV1.AuditLog{ + ServiceName: "resource-manager", + MethodName: "stackit.resourcemanager.v2.organization.created", + ResourceName: fmt.Sprintf("organizations/%s", identifier), + AuthenticationInfo: &auditV1.AuthenticationInfo{ + PrincipalId: uuid.NewString(), + PrincipalEmail: "user@example.com", + ServiceAccountName: nil, + ServiceAccountDelegationInfo: nil, + }, + AuthorizationInfo: []*auditV1.AuthorizationInfo{{ + Resource: fmt.Sprintf("organizations/%s", identifier), + Permission: &permission, + Granted: &permissionGranted, + }}, + RequestMetadata: &auditV1.RequestMetadata{ + CallerIp: "127.0.0.1", + CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go", + RequestAttributes: &auditV1.AttributeContext_Request{ + Id: &requestId, + Method: "POST", + Headers: headers, + Path: "/v2/organizations", + Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", + Scheme: "https", + Query: nil, + Time: timestamppb.New(time.Now().UTC()), + Protocol: "http/1.1", + Auth: &auditV1.AttributeContext_Auth{ + Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev", + Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"}, + Claims: claims, + }, + }, + }, + Request: request, + Status: &auditV1.ResponseStatus{ + Code: wrapperspb.Int32(200), + Message: nil, + Details: nil, + }, + NumResponseItems: nil, + Response: response, + Metadata: nil, }, + InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()), + Labels: labels, + CorrelationId: &correlationId, + Timestamp: timestamppb.New(time.Now()), + Severity: auditV1.LogSeverity_DEFAULT, + TraceParent: nil, + TraceState: nil, } - identifier := uuid.New() routingIdentifier := &RoutingIdentifier{ Identifier: identifier, Type: RoutingIdentifierTypeOrganization, @@ -44,7 +100,6 @@ func NewOrganizationAuditEvent( Identifier: identifier.String(), Type: auditV1.ObjectType_OBJECT_TYPE_ORGANIZATION, } - auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier} if customization != nil { (*customization)(auditEvent, routingIdentifier, objectIdentifier) @@ -53,51 +108,6 @@ func NewOrganizationAuditEvent( return auditEvent, routingIdentifier, objectIdentifier } -func NewOrganizationAuditEventWithDetails() (*auditV1.AuditLogEntry, - *RoutingIdentifier, - *auditV1.ObjectIdentifier) { - customization := func(event *auditV1.AuditLogEntry, - routingIdentifier *RoutingIdentifier, - objectIdentifier *auditV1.ObjectIdentifier) { - userAgent := "firefox" - parameters, _ := structpb.NewStruct(map[string]any{"parameter1": "value"}) - body, _ := structpb.NewStruct(map[string]any{"body": "value"}) - - event.Request = &auditV1.RequestDetails{ - Endpoint: "/test", - SourceIpAddress: "127.0.0.1", - UserAgent: &userAgent, - Parameters: parameters, - Body: body, - Headers: []*auditV1.RequestHeader{ - { - Key: "header1", - Value: "value", - }, - }, - } - - email := "test@example.com" - event.Principals = []*auditV1.Principal{ - { - Id: "id", - Email: &email, - }, - } - - details, _ := structpb.NewStruct(map[string]interface{}{ - "detail": "value", - }) - event.Details = details - - result, _ := structpb.NewStruct(map[string]interface{}{ - "result": "value", - }) - event.Result = result - } - return NewOrganizationAuditEvent(&customization) -} - func NewFolderAuditEvent( customization *func( *auditV1.AuditLogEntry, @@ -109,28 +119,83 @@ func NewFolderAuditEvent( *auditV1.ObjectIdentifier, ) { + identifier := uuid.New() + permission := "resourcemanager.folder.edit" + permissionGranted := true + requestId := fmt.Sprintf("%s/1", identifier) + claims, _ := structpb.NewStruct(map[string]interface{}{}) + request, _ := structpb.NewStruct(map[string]interface{}{}) + response, _ := structpb.NewStruct(map[string]interface{}{}) + correlationId := "9c71cedf-ca52-4f9c-a519-ed006e810cdd" + headers := make(map[string]string) + headers["Content-Type"] = "application/json" + labels := make(map[string]string) + labels["label1"] = "value1" auditEvent := &auditV1.AuditLogEntry{ - EventSource: "resource-manager", - Region: auditV1.Region_REGION_EU01, - SequenceNumber: wrapperspb.Int64(0), - EventName: "FOLDER_CREATED", - EventTimeStamp: timestamppb.New(time.Now()), - EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT, - Initiator: &auditV1.Principal{ - Id: uuid.NewString(), + LogName: fmt.Sprintf("folders/%s/logs/admin-activity", identifier), + ProtoPayload: &auditV1.AuditLog{ + ServiceName: "resource-manager", + MethodName: "stackit.resourcemanager.v2.folder.created", + ResourceName: fmt.Sprintf("folders/%s", identifier), + AuthenticationInfo: &auditV1.AuthenticationInfo{ + PrincipalId: uuid.NewString(), + PrincipalEmail: "user@example.com", + ServiceAccountName: nil, + ServiceAccountDelegationInfo: nil, + }, + AuthorizationInfo: []*auditV1.AuthorizationInfo{{ + Resource: fmt.Sprintf("folders/%s", identifier), + Permission: &permission, + Granted: &permissionGranted, + }}, + RequestMetadata: &auditV1.RequestMetadata{ + CallerIp: "127.0.0.1", + CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go", + RequestAttributes: &auditV1.AttributeContext_Request{ + Id: &requestId, + Method: "POST", + Headers: headers, + Path: "/v2/folders", + Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", + Scheme: "https", + Query: nil, + Time: timestamppb.New(time.Now().UTC()), + Protocol: "http/1.1", + Auth: &auditV1.AttributeContext_Auth{ + Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev", + Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"}, + Claims: claims, + }, + }, + }, + Request: request, + Status: &auditV1.ResponseStatus{ + Code: wrapperspb.Int32(200), + Message: nil, + Details: nil, + }, + NumResponseItems: nil, + Response: response, + Metadata: nil, }, + InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()), + Labels: labels, + CorrelationId: &correlationId, + Timestamp: timestamppb.New(time.Now()), + Severity: auditV1.LogSeverity_DEFAULT, + TraceParent: nil, + TraceState: nil, } routingIdentifier := &RoutingIdentifier{ - Identifier: uuid.New(), + Identifier: identifier, Type: RoutingIdentifierTypeOrganization, } objectIdentifier := &auditV1.ObjectIdentifier{ - Identifier: uuid.New().String(), + Identifier: identifier.String(), Type: auditV1.ObjectType_OBJECT_TYPE_FOLDER, } - auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier} if customization != nil { (*customization)(auditEvent, routingIdentifier, objectIdentifier) @@ -150,19 +215,74 @@ func NewProjectAuditEvent( *auditV1.ObjectIdentifier, ) { + identifier := uuid.New() + permission := "resourcemanager.project.edit" + permissionGranted := true + requestId := fmt.Sprintf("%s/1", identifier) + claims, _ := structpb.NewStruct(map[string]interface{}{}) + request, _ := structpb.NewStruct(map[string]interface{}{}) + response, _ := structpb.NewStruct(map[string]interface{}{}) + correlationId := "14d5b611-ccce-4cfa-9085-9ccbfccce3cb" + headers := make(map[string]string) + headers["Content-Type"] = "application/json" + labels := make(map[string]string) + labels["label1"] = "value1" auditEvent := &auditV1.AuditLogEntry{ - EventSource: "resource-manager", - Region: auditV1.Region_REGION_EU01, - SequenceNumber: wrapperspb.Int64(0), - EventName: "PROJECT_CREATED", - EventTimeStamp: timestamppb.New(time.Now()), - EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT, - Initiator: &auditV1.Principal{ - Id: uuid.NewString(), + LogName: fmt.Sprintf("projects/%s/logs/admin-activity", identifier), + ProtoPayload: &auditV1.AuditLog{ + ServiceName: "resource-manager", + MethodName: "stackit.resourcemanager.v2.project.created", + ResourceName: fmt.Sprintf("projects/%s", identifier), + AuthenticationInfo: &auditV1.AuthenticationInfo{ + PrincipalId: uuid.NewString(), + PrincipalEmail: "user@example.com", + ServiceAccountName: nil, + ServiceAccountDelegationInfo: nil, + }, + AuthorizationInfo: []*auditV1.AuthorizationInfo{{ + Resource: fmt.Sprintf("projects/%s", identifier), + Permission: &permission, + Granted: &permissionGranted, + }}, + RequestMetadata: &auditV1.RequestMetadata{ + CallerIp: "127.0.0.1", + CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go", + RequestAttributes: &auditV1.AttributeContext_Request{ + Id: &requestId, + Method: "POST", + Headers: headers, + Path: "/v2/projects", + Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", + Scheme: "https", + Query: nil, + Time: timestamppb.New(time.Now().UTC()), + Protocol: "http/1.1", + Auth: &auditV1.AttributeContext_Auth{ + Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev", + Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"}, + Claims: claims, + }, + }, + }, + Request: request, + Status: &auditV1.ResponseStatus{ + Code: wrapperspb.Int32(200), + Message: nil, + Details: nil, + }, + NumResponseItems: nil, + Response: response, + Metadata: nil, }, + InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()), + Labels: labels, + CorrelationId: &correlationId, + Timestamp: timestamppb.New(time.Now()), + Severity: auditV1.LogSeverity_DEFAULT, + TraceParent: nil, + TraceState: nil, } - identifier := uuid.New() routingIdentifier := &RoutingIdentifier{ Identifier: identifier, Type: RoutingIdentifierTypeProject, @@ -172,7 +292,6 @@ func NewProjectAuditEvent( Identifier: identifier.String(), Type: auditV1.ObjectType_OBJECT_TYPE_PROJECT, } - auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectIdentifier{ObjectIdentifier: objectIdentifier} if customization != nil { (*customization)(auditEvent, routingIdentifier, objectIdentifier) @@ -184,19 +303,74 @@ func NewProjectAuditEvent( func NewSystemAuditEvent( customization *func(*auditV1.AuditLogEntry)) *auditV1.AuditLogEntry { + identifier := uuid.New() + requestId := fmt.Sprintf("%s/1", identifier) + claims, _ := structpb.NewStruct(map[string]interface{}{}) + request, _ := structpb.NewStruct(map[string]interface{}{}) + response, _ := structpb.NewStruct(map[string]interface{}{}) + correlationId := "14d5b611-ccce-4cfa-9085-9ccbfccce3cb" + headers := make(map[string]string) + headers["Content-Type"] = "application/json" + labels := make(map[string]string) + labels["label1"] = "value1" + serviceAccountId := uuid.NewString() + serviceAccountName := fmt.Sprintf("projects/%s/serviceAccounts/%s", identifier, serviceAccountId) + delegationPrincipal := auditV1.ServiceAccountDelegationInfo{Authority: &auditV1.ServiceAccountDelegationInfo_SystemPrincipal_{}} auditEvent := &auditV1.AuditLogEntry{ - EventSource: "resource-manager", - Region: auditV1.Region_REGION_EU01, - SequenceNumber: wrapperspb.Int64(0), - EventName: "SYSTEM_CHANGED", - EventTimeStamp: timestamppb.New(time.Now()), - EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_EVENT, - Initiator: &auditV1.Principal{ - Id: uuid.NewString(), + LogName: fmt.Sprintf("projects/%s/logs/system-event", identifier), + ProtoPayload: &auditV1.AuditLog{ + ServiceName: "resource-manager", + MethodName: "stackit.resourcemanager.v2.system.changed", + ResourceName: fmt.Sprintf("projects/%s", identifier), + AuthenticationInfo: &auditV1.AuthenticationInfo{ + PrincipalId: serviceAccountId, + PrincipalEmail: "service-account@sa.stackit.cloud", + ServiceAccountName: &serviceAccountName, + ServiceAccountDelegationInfo: []*auditV1.ServiceAccountDelegationInfo{&delegationPrincipal}, + }, + AuthorizationInfo: []*auditV1.AuthorizationInfo{{ + Resource: fmt.Sprintf("projects/%s", identifier), + Permission: nil, + Granted: nil, + }}, + RequestMetadata: &auditV1.RequestMetadata{ + CallerIp: "127.0.0.1", + CallerSuppliedUserAgent: "OpenAPI-Generator/ 1.0.0/ go", + RequestAttributes: &auditV1.AttributeContext_Request{ + Id: &requestId, + Method: "POST", + Headers: headers, + Path: "/v2/projects", + Host: "stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", + Scheme: "https", + Query: nil, + Time: timestamppb.New(time.Now().UTC()), + Protocol: "http/1.1", + Auth: &auditV1.AttributeContext_Auth{ + Principal: "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev", + Audiences: []string{"https:// stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"}, + Claims: claims, + }, + }, + }, + Request: request, + Status: &auditV1.ResponseStatus{ + Code: wrapperspb.Int32(200), + Message: nil, + Details: nil, + }, + NumResponseItems: nil, + Response: response, + Metadata: nil, }, + InsertId: fmt.Sprintf("%d/eu01/e72182e8-0bb9-4be2-a19f-87fc0dd6e738/00000000001", time.Now().UnixNano()), + Labels: labels, + CorrelationId: &correlationId, + Timestamp: timestamppb.New(time.Now()), + Severity: auditV1.LogSeverity_DEFAULT, + TraceParent: nil, + TraceState: nil, } - auditEvent.ResourceContainerReference = &auditV1.AuditEvent_ObjectName{ - ObjectName: auditV1.ObjectName_OBJECT_NAME_SYSTEM} if customization != nil { (*customization)(auditEvent) diff --git a/gen/go/audit/v1/audit_event.pb.go b/gen/go/audit/v1/audit_event.pb.go index 3d2e9ef..2b04008 100644 --- a/gen/go/audit/v1/audit_event.pb.go +++ b/gen/go/audit/v1/audit_event.pb.go @@ -13,6 +13,7 @@ import ( _ "google.golang.org/protobuf/types/known/anypb" structpb "google.golang.org/protobuf/types/known/structpb" timestamppb "google.golang.org/protobuf/types/known/timestamppb" + wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" reflect "reflect" sync "sync" ) @@ -25,16 +26,14 @@ const ( ) // The severity of the event described in a log entry, expressed as one of the -// standard severity levels listed below. For your reference, the levels are -// assigned the listed numeric values. The effect of using numeric values other -// than those listed is undefined. -// Copied from -// https://github.com/googleapis/googleapis/blob/master/google/logging/type/log_severity.proto +// standard severity levels listed below. type LogSeverity int32 const ( - // (0) The log entry has no assigned severity level. - LogSeverity_DEFAULT LogSeverity = 0 + LogSeverity_UNSPECIFIED LogSeverity = 0 + // (1) The log entry has no assigned severity level. + // TODO check index + LogSeverity_DEFAULT LogSeverity = 1 // (100) Debug or trace information. LogSeverity_DEBUG LogSeverity = 100 // (200) Routine information, such as ongoing status or performance. @@ -57,7 +56,8 @@ const ( // Enum value maps for LogSeverity. var ( LogSeverity_name = map[int32]string{ - 0: "DEFAULT", + 0: "UNSPECIFIED", + 1: "DEFAULT", 100: "DEBUG", 200: "INFO", 300: "NOTICE", @@ -68,15 +68,16 @@ var ( 800: "EMERGENCY", } LogSeverity_value = map[string]int32{ - "DEFAULT": 0, - "DEBUG": 100, - "INFO": 200, - "NOTICE": 300, - "WARNING": 400, - "ERROR": 500, - "CRITICAL": 600, - "ALERT": 700, - "EMERGENCY": 800, + "UNSPECIFIED": 0, + "DEFAULT": 1, + "DEBUG": 100, + "INFO": 200, + "NOTICE": 300, + "WARNING": 400, + "ERROR": 500, + "CRITICAL": 600, + "ALERT": 700, + "EMERGENCY": 800, } ) @@ -114,39 +115,79 @@ type AuditLogEntry struct { unknownFields protoimpl.UnknownFields // The resource name of the log to which this log entry belongs. - // Example: projects//logs/ - LogName string `protobuf:"bytes,12,opt,name=log_name,json=logName,proto3" json:"log_name,omitempty"` + // + // Format: //logs/ + // Where: + // + // Event-Types: admin-activity, system-event, policy-denied, data-access + // + // Examples: + // + // "projects/00b0f972-59ff-48f2-a4f9-29c57b75c2fa/logs/admin-activity" + // + // Required: true + LogName string `protobuf:"bytes,1,opt,name=log_name,json=logName,proto3" json:"log_name,omitempty"` // The log entry payload, which is always an AuditLog for STACKIT Audit Log events. + // + // Required: true ProtoPayload *AuditLog `protobuf:"bytes,2,opt,name=proto_payload,json=protoPayload,proto3" json:"proto_payload,omitempty"` - // TODO can we specify how the format should look like? - // TODO Encode sequence number into it? - // https://softwaremind.com/blog/the-unique-features-of-snowflake-id-and-its-comparison-to-uuid/ // A unique identifier for the log entry. - // Is generated and set by the SDK. - // Format: - // /// - InsertId string `protobuf:"bytes,4,opt,name=insert_id,json=insertId,proto3" json:"insert_id,omitempty"` + // Is used to check completeness of audit events over time. + // + // Format: /// + // Where: + // + // Unix-Timestamp: A UTC unix timestamp in seconds is expected + // Region-Zone: The region and (optional) zone id. If both, separated with a - (dash) + // Worker-Id: The ID of the K8s Pod, Service-Instance, etc (must be unique for a sending service) + // Sequence-Number: Increasing number, representing the message offset per Worker-Id + // If the Worker-Id changes, the sequence-number has to be reset to 0. + // + // Examples: + // + // "1721899117/eu01/319a7fb9-edd2-46c6-953a-a724bb377c61/8792726390909855142" + // + // Required: true + InsertId string `protobuf:"bytes,3,opt,name=insert_id,json=insertId,proto3" json:"insert_id,omitempty"` // A set of user-defined (key, value) data that provides additional // information about the log entry. - Labels map[string]string `protobuf:"bytes,11,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // + // Required: true + Labels map[string]string `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // Correlate multiple audit logs by setting the same id - CorrelationId string `protobuf:"bytes,15,opt,name=correlation_id,json=correlationId,proto3" json:"correlation_id,omitempty"` + // + // Required: false + CorrelationId *string `protobuf:"bytes,5,opt,name=correlation_id,json=correlationId,proto3,oneof" json:"correlation_id,omitempty"` // The time the event described by the log entry occurred. - Timestamp *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + // + // Required: true + Timestamp *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // The severity of the log entry. - Severity LogSeverity `protobuf:"varint,10,opt,name=severity,proto3,enum=audit.v1.LogSeverity" json:"severity,omitempty"` - // W3C conform trace parent header: + // + // Required: true + Severity LogSeverity `protobuf:"varint,7,opt,name=severity,proto3,enum=audit.v1.LogSeverity" json:"severity,omitempty"` + // Customer set W3C conform trace parent header: // https://www.w3.org/TR/trace-context/#traceparent-header // - // Example: - // `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01` - TraceParent string `protobuf:"bytes,22,opt,name=trace_parent,json=traceParent,proto3" json:"trace_parent,omitempty"` - // W3C conform trace state header: + // Format: --- + // + // Examples: + // + // "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" + // + // Required: false + TraceParent *string `protobuf:"bytes,8,opt,name=trace_parent,json=traceParent,proto3,oneof" json:"trace_parent,omitempty"` + // Customer set W3C conform trace state header: // https://www.w3.org/TR/trace-context/#tracestate-header // - // Example: - // `rojo=00f067aa0ba902b7,congo=t61rcWkgMzE`. - TraceState string `protobuf:"bytes,27,opt,name=trace_state,json=traceState,proto3" json:"trace_state,omitempty"` + // Format: =[,=] + // + // Examples: + // + // "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE" + // + // Required: false + TraceState *string `protobuf:"bytes,9,opt,name=trace_state,json=traceState,proto3,oneof" json:"trace_state,omitempty"` } func (x *AuditLogEntry) Reset() { @@ -210,8 +251,8 @@ func (x *AuditLogEntry) GetLabels() map[string]string { } func (x *AuditLogEntry) GetCorrelationId() string { - if x != nil { - return x.CorrelationId + if x != nil && x.CorrelationId != nil { + return *x.CorrelationId } return "" } @@ -227,19 +268,19 @@ func (x *AuditLogEntry) GetSeverity() LogSeverity { if x != nil { return x.Severity } - return LogSeverity_DEFAULT + return LogSeverity_UNSPECIFIED } func (x *AuditLogEntry) GetTraceParent() string { - if x != nil { - return x.TraceParent + if x != nil && x.TraceParent != nil { + return *x.TraceParent } return "" } func (x *AuditLogEntry) GetTraceState() string { - if x != nil { - return x.TraceState + if x != nil && x.TraceState != nil { + return *x.TraceState } return "" } @@ -250,52 +291,85 @@ type AuditLog struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The name of the API service performing the operation. For example, - // `"resource-manager"`. - ServiceName string `protobuf:"bytes,7,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` - // TODO: Add extra field to open api spec for the method_name - // The name of the service method or operation. - // The format should is: - // stackit.... + // The name of the API service performing the operation. // - // For example, + // Examples: + // + // "resource-manager" + // + // Required: true + ServiceName string `protobuf:"bytes,1,opt,name=service_name,json=serviceName,proto3" json:"service_name,omitempty"` + // TODO renaming into operation? + // The name of the service method or operation. + // + // Format: stackit.... + // + // Examples: // // "stackit.resourcemanager.v1.organization.created" // "stackit.authorization.v2.organization.moved" // "stackit.authorization.v2.folder.moved" - MethodName *string `protobuf:"bytes,8,opt,name=method_name,json=methodName,proto3,oneof" json:"method_name,omitempty"` + // + // Required: true + MethodName string `protobuf:"bytes,2,opt,name=method_name,json=methodName,proto3" json:"method_name,omitempty"` // The resource or collection that is the target of the operation. // The name is a scheme-less URI, not including the API service name. - // For example: // - // "projects//vms/" - // "projects//vms//ports/" - ResourceName string `protobuf:"bytes,11,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"` + // Format: /[/locations/][/
] + // Where: + // + // Region-Zone: Optional region and zone id. If both, separated with a - (dash). Alternatively _ (underscore). + // Details: Optional "/" pairs + // + // Examples: + // + // "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/instances/instance-20240723-174217" + // "projects/dd7d1807-54e9-4426-8994-721758b5b554/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8" + // + // Required: true + ResourceName string `protobuf:"bytes,3,opt,name=resource_name,json=resourceName,proto3" json:"resource_name,omitempty"` // Authentication information. - AuthenticationInfo *AuthenticationInfo `protobuf:"bytes,3,opt,name=authentication_info,json=authenticationInfo,proto3" json:"authentication_info,omitempty"` - // Authorization information. If there are multiple - // resources or permissions involved, then there is + // + // Required: true + AuthenticationInfo *AuthenticationInfo `protobuf:"bytes,4,opt,name=authentication_info,json=authenticationInfo,proto3" json:"authentication_info,omitempty"` + // Authorization information. If there are multiple resources or permissions involved, then there is // one AuthorizationInfo element for each {resource, permission} tuple. - AuthorizationInfo []*AuthorizationInfo `protobuf:"bytes,9,rep,name=authorization_info,json=authorizationInfo,proto3" json:"authorization_info,omitempty"` + // + // Required: false + AuthorizationInfo []*AuthorizationInfo `protobuf:"bytes,5,rep,name=authorization_info,json=authorizationInfo,proto3" json:"authorization_info,omitempty"` // Metadata about the operation. - RequestMetadata *RequestMetadata `protobuf:"bytes,4,opt,name=request_metadata,json=requestMetadata,proto3" json:"request_metadata,omitempty"` + // + // Required: true + RequestMetadata *RequestMetadata `protobuf:"bytes,6,opt,name=request_metadata,json=requestMetadata,proto3" json:"request_metadata,omitempty"` // The operation request. This may not include all request parameters, // such as those that are too large, privacy-sensitive, or duplicated // elsewhere in the log record. // It should never include user-generated data, such as file contents. - Request *structpb.Struct `protobuf:"bytes,16,opt,name=request,proto3" json:"request,omitempty"` + // + // Required: true + Request *structpb.Struct `protobuf:"bytes,7,opt,name=request,proto3" json:"request,omitempty"` // The status of the overall operation. - Status *ResponseStatus `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + // + // Required: true + Status *ResponseStatus `protobuf:"bytes,8,opt,name=status,proto3" json:"status,omitempty"` // The number of items returned from a List or Query API method, // if applicable. - NumResponseItems *int64 `protobuf:"varint,12,opt,name=num_response_items,json=numResponseItems,proto3,oneof" json:"num_response_items,omitempty"` + // + // Required: false + NumResponseItems *wrapperspb.Int64Value `protobuf:"bytes,9,opt,name=num_response_items,json=numResponseItems,proto3,oneof" json:"num_response_items,omitempty"` // The operation response. This may not include all response elements, // such as those that are too large, privacy-sensitive, or duplicated // elsewhere in the log record. - Response *structpb.Struct `protobuf:"bytes,17,opt,name=response,proto3" json:"response,omitempty"` + // + // Required: true + Response *structpb.Struct `protobuf:"bytes,10,opt,name=response,proto3" json:"response,omitempty"` // Other service-specific data about the request, response, and other // information associated with the current audited event. - Metadata *structpb.Struct `protobuf:"bytes,18,opt,name=metadata,proto3" json:"metadata,omitempty"` + // + // Required: false + Metadata *structpb.Struct `protobuf:"bytes,11,opt,name=metadata,proto3,oneof" json:"metadata,omitempty"` } func (x *AuditLog) Reset() { @@ -338,8 +412,8 @@ func (x *AuditLog) GetServiceName() string { } func (x *AuditLog) GetMethodName() string { - if x != nil && x.MethodName != nil { - return *x.MethodName + if x != nil { + return x.MethodName } return "" } @@ -386,11 +460,11 @@ func (x *AuditLog) GetStatus() *ResponseStatus { return nil } -func (x *AuditLog) GetNumResponseItems() int64 { - if x != nil && x.NumResponseItems != nil { - return *x.NumResponseItems +func (x *AuditLog) GetNumResponseItems() *wrapperspb.Int64Value { + if x != nil { + return x.NumResponseItems } - return 0 + return nil } func (x *AuditLog) GetResponse() *structpb.Struct { @@ -413,22 +487,34 @@ type AuthenticationInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // Principal id + // STACKIT principal id + // + // Required: true PrincipalId string `protobuf:"bytes,1,opt,name=principal_id,json=principalId,proto3" json:"principal_id,omitempty"` - // The email address of the authenticated user + // The email address of the authenticated user. + // Service accounts have email addresses that can be used. + // + // Required: true PrincipalEmail string `protobuf:"bytes,2,opt,name=principal_email,json=principalEmail,proto3" json:"principal_email,omitempty"` // The name of the service account used to create or exchange // credentials for authenticating the service account making the request. - // Example: // - // "projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}" - ServiceAccountName *string `protobuf:"bytes,5,opt,name=service_account_name,json=serviceAccountName,proto3,oneof" json:"service_account_name,omitempty"` + // Format: projects//serviceAccounts/ + // + // Examples: + // + // "projects/29b2c56f-f712-4a9c-845b-f0907158e53c/serviceAccounts/a606dc68-8b97-421b-89a9-116bcbd004df" + // + // Required: false + ServiceAccountName *string `protobuf:"bytes,3,opt,name=service_account_name,json=serviceAccountName,proto3,oneof" json:"service_account_name,omitempty"` // Identity delegation history of an authenticated service account that makes // the request. It contains information on the real authorities that try to // access STACKIT resources by delegating on a service account. When multiple // authorities present, they are guaranteed to be sorted based on the original // ordering of the identity delegation events. - ServiceAccountDelegationInfo []*ServiceAccountDelegationInfo `protobuf:"bytes,6,rep,name=service_account_delegation_info,json=serviceAccountDelegationInfo,proto3" json:"service_account_delegation_info,omitempty"` + // + // Required: false + ServiceAccountDelegationInfo []*ServiceAccountDelegationInfo `protobuf:"bytes,4,rep,name=service_account_delegation_info,json=serviceAccountDelegationInfo,proto3" json:"service_account_delegation_info,omitempty"` } func (x *AuthenticationInfo) Reset() { @@ -497,23 +583,36 @@ type AuthorizationInfo struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // TODO check example - // The resource being accessed, as a REST-style string. For example: + // The resource being accessed, as a REST-style string. // - // bigquery.googleapis.com/projects/PROJECTID/datasets/DATASETID + // Format: /[/locations/][/
] + // Where: + // + // Region-Zone: Optional region and zone id. If both, separated with a - (dash). Alternatively _ (underscore). + // Details: Optional "/" pairs + // + // Examples: + // + // "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/instances/instance-20240723-174217" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8" + // + // Required: true Resource string `protobuf:"bytes,1,opt,name=resource,proto3" json:"resource,omitempty"` // The required IAM permission. - Permission string `protobuf:"bytes,2,opt,name=permission,proto3" json:"permission,omitempty"` + // + // Examples: + // + // "resourcemanager.project.edit" + // + // Required: false + Permission *string `protobuf:"bytes,2,opt,name=permission,proto3,oneof" json:"permission,omitempty"` // Whether or not authorization for `resource` and `permission` // was granted. - Granted bool `protobuf:"varint,3,opt,name=granted,proto3" json:"granted,omitempty"` - // Resource attributes used in IAM condition evaluation. This field contains - // resource attributes like resource type and resource name. // - // To get the whole view of the attributes used in IAM - // condition evaluation, the user must also look into - // `AuditLog.request_metadata.request_attributes`. - ResourceAttributes *AttributeContext_Resource `protobuf:"bytes,5,opt,name=resource_attributes,json=resourceAttributes,proto3" json:"resource_attributes,omitempty"` + // Required: false + Granted *bool `protobuf:"varint,3,opt,name=granted,proto3,oneof" json:"granted,omitempty"` } func (x *AuthorizationInfo) Reset() { @@ -556,44 +655,24 @@ func (x *AuthorizationInfo) GetResource() string { } func (x *AuthorizationInfo) GetPermission() string { - if x != nil { - return x.Permission + if x != nil && x.Permission != nil { + return *x.Permission } return "" } func (x *AuthorizationInfo) GetGranted() bool { - if x != nil { - return x.Granted + if x != nil && x.Granted != nil { + return *x.Granted } return false } -func (x *AuthorizationInfo) GetResourceAttributes() *AttributeContext_Resource { - if x != nil { - return x.ResourceAttributes - } - return nil -} - -// TODO check description // This message defines the standard attribute vocabulary for STACKIT APIs. // // An attribute is a piece of metadata that describes an activity on a network // service. For example, the size of an HTTP request, or the status code of // an HTTP response. -// -// Each attribute has a type and a name, which is logically defined as -// a proto message field in `AttributeContext`. The field type becomes the -// attribute type, and the field path becomes the attribute name. For example, -// the attribute `source.ip` maps to field `AttributeContext.source.ip`. -// -// This message definition is guaranteed not to have any wire breaking change. -// So you can use it directly for passing attributes across different systems. -// -// NOTE: Different system may generate different subset of attributes. Please -// verify the system specification before relying on an attribute generated -// a system. type AttributeContext struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -640,33 +719,25 @@ type RequestMetadata struct { // The IP address of the caller. // For caller from internet, this will be public IPv4 or IPv6 address. - // For caller from a VM / K8s Service / etc, this - // will be the SIT proxy's IPv4 address. + // For caller from a VM / K8s Service / etc, this will be the SIT proxy's IPv4 address. + // + // Required: true CallerIp string `protobuf:"bytes,1,opt,name=caller_ip,json=callerIp,proto3" json:"caller_ip,omitempty"` - // TODO check description // The user agent of the caller. - // This information is not authenticated and should be treated accordingly. - // For example: // - // - `google-api-python-client/1.4.0`: - // The request was made by the Google API client for Python. - // - `Cloud SDK Command Line Tool apitools-client/1.0 gcloud/0.9.62`: - // The request was made by the Google Cloud SDK CLI (gcloud). - // - `AppEngine-Google; (+http://code.google.com/appengine; appid: + // Examples: // - // s~my-project`: + // "OpenAPI-Generator/1.0.0/go" + // -> The request was made by the STACKIT SDK GO client or STACKIT CLI + // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" + // -> The request was made by a web browser. // - // The request was made from the `my-project` App Engine app. + // Required: true CallerSuppliedUserAgent string `protobuf:"bytes,2,opt,name=caller_supplied_user_agent,json=callerSuppliedUserAgent,proto3" json:"caller_supplied_user_agent,omitempty"` - // TODO check description - // Request attributes used in IAM condition evaluation. This field contains - // request attributes like request time and access levels associated with - // the request. + // This field contains request attributes like request url, time, etc. // - // To get the whole view of the attributes used in IAM - // condition evaluation, the user must also look into - // `AuditLog.authentication_info.resource_attributes`. - RequestAttributes *AttributeContext_Request `protobuf:"bytes,7,opt,name=request_attributes,json=requestAttributes,proto3" json:"request_attributes,omitempty"` + // Required: true + RequestAttributes *AttributeContext_Request `protobuf:"bytes,3,opt,name=request_attributes,json=requestAttributes,proto3" json:"request_attributes,omitempty"` } func (x *RequestMetadata) Reset() { @@ -732,10 +803,16 @@ type ResponseStatus struct { unknownFields protoimpl.UnknownFields // The http or gRPC status code. - Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + // + // Required: true + Code *wrapperspb.Int32Value `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` // Short description of the error - Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + // + // Required: false + Message *string `protobuf:"bytes,2,opt,name=message,proto3,oneof" json:"message,omitempty"` // Error details + // + // Required: false Details []*structpb.Struct `protobuf:"bytes,3,rep,name=details,proto3" json:"details,omitempty"` } @@ -771,16 +848,16 @@ func (*ResponseStatus) Descriptor() ([]byte, []int) { return file_audit_v1_audit_event_proto_rawDescGZIP(), []int{6} } -func (x *ResponseStatus) GetCode() int32 { +func (x *ResponseStatus) GetCode() *wrapperspb.Int32Value { if x != nil { return x.Code } - return 0 + return nil } func (x *ResponseStatus) GetMessage() string { - if x != nil { - return x.Message + if x != nil && x.Message != nil { + return *x.Message } return "" } @@ -887,61 +964,53 @@ type AttributeContext_Auth struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // TODO check description - // The authenticated principal. Reflects the issuer (`iss`) and subject - // (`sub`) claims within a JWT. The issuer and subject should be `/` - // delimited, with `/` percent-encoded within the subject fragment. For - // Google accounts, the principal format is: - // "https://accounts.google.com/{id}" + // The authenticated principal. Reflects the issuer ("iss") and subject + // ("sub") claims within a JWT. + // + // Format: / + // Where: + // + // Sub-Claim: Sub-Claim from JWT with `/` percent-encoded (url-encoded) + // + // Examples: + // + // "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev" + // + // Required: true Principal string `protobuf:"bytes,1,opt,name=principal,proto3" json:"principal,omitempty"` - // TODO check description // The intended audience(s) for this authentication information. Reflects - // the audience (`aud`) claim within a JWT. The audience - // value(s) depends on the `issuer`, but typically include one or more of - // the following pieces of information: + // the audience ("aud") claim within a JWT, typically the services intended + // to receive the credential. // - // - The services intended to receive the credential such as - // ["pubsub.googleapis.com", "storage.googleapis.com"] - // - A set of service-based scopes. For example, - // ["https://www.googleapis.com/auth/cloud-platform"] - // - The client id of an app, such as the Firebase project id for JWTs - // from Firebase Auth. + // Examples: // - // Consult the documentation for the credential issuer to determine the - // information provided. + // ["https://stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"] + // + // Required: false Audiences []string `protobuf:"bytes,2,rep,name=audiences,proto3" json:"audiences,omitempty"` - // TODO check description - // The authorized presenter of the credential. Reflects the optional - // Authorized Presenter (`azp`) claim within a JWT or the - // OAuth client id. For example, a Google Cloud Platform client id looks - // as follows: "123456789012.apps.googleusercontent.com". - Presenter string `protobuf:"bytes,3,opt,name=presenter,proto3" json:"presenter,omitempty"` - // TODO check description // Structured claims presented with the credential. JWTs include - // `{key: value}` pairs for standard and private claims. The following - // is a subset of the standard required and optional claims that would - // typically be presented for a Google-based JWT: + // {"key": } pairs for standard and private claims. // - // {'iss': 'accounts.google.com', - // 'sub': '113289723416554971153', - // 'aud': ['123456789012', 'pubsub.googleapis.com'], - // 'azp': '123456789012.apps.googleusercontent.com', - // 'email': 'jsmith@example.com', - // 'iat': 1353601026, - // 'exp': 1353604926} + // The following is a subset of the standard required and optional claims that would + // typically be presented for a STACKIT JWT: // - // SAML assertions are similarly specified, but with an identity provider - // dependent structure. - Claims *structpb.Struct `protobuf:"bytes,4,opt,name=claims,proto3" json:"claims,omitempty"` - // TODO check description - // A list of access level resource names that allow resources to be - // accessed by authenticated requester. It is part of Secure GCP processing - // for the incoming request. An access level string has the format: - // "//{api_service_name}/accessPolicies/{policy_id}/accessLevels/{short_name}" + // { + // "aud": "https://stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", + // "email": "max@mail.schwarz", + // "exp": 1721905449, + // "iat": 1721901849, + // "iss": "https://api.dev.stackit.cloud", + // "jti": "45a196e0-480f-4c34-a592-dc5db81c8c3a", + // "nbf": 1721900462, + // "roles": null, + // "sub": "cd94f01a-df2e-4456-902f-48f5e57f0b63", + // "user_id": "", + // "x_client_id": "", + // "zid": "" + // } // - // Example: - // "//accesscontextmanager.googleapis.com/accessPolicies/MY_POLICY_ID/accessLevels/MY_LEVEL" - AccessLevels []string `protobuf:"bytes,5,rep,name=access_levels,json=accessLevels,proto3" json:"access_levels,omitempty"` + // Required: true + Claims *structpb.Struct `protobuf:"bytes,3,opt,name=claims,proto3" json:"claims,omitempty"` } func (x *AttributeContext_Auth) Reset() { @@ -990,13 +1059,6 @@ func (x *AttributeContext_Auth) GetAudiences() []string { return nil } -func (x *AttributeContext_Auth) GetPresenter() string { - if x != nil { - return x.Presenter - } - return "" -} - func (x *AttributeContext_Auth) GetClaims() *structpb.Struct { if x != nil { return x.Claims @@ -1004,13 +1066,6 @@ func (x *AttributeContext_Auth) GetClaims() *structpb.Struct { return nil } -func (x *AttributeContext_Auth) GetAccessLevels() []string { - if x != nil { - return x.AccessLevels - } - return nil -} - // This message defines attributes for an HTTP request. If the actual // request is not an HTTP request, the runtime system should try to map // the actual request to an equivalent HTTP request. @@ -1022,33 +1077,64 @@ type AttributeContext_Request struct { // The unique ID for a request, which can be propagated to downstream // systems. The ID should have low probability of collision // within a single day for a specific service. - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // + // More information can be found here: https://google.aip.dev/155 + // + // Format: + // Where: + // + // Idempotency-key: Typically consists of a id + version + // + // Examples: + // + // 5e3952a9-b628-4be6-ac61-b1c6eb4a110c/5 + // + // Required: false + Id *string `protobuf:"bytes,1,opt,name=id,proto3,oneof" json:"id,omitempty"` // The HTTP request method, such as `GET`, `POST`. + // + // Required: true + // TODO does it make sense to define an enum? Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` // The HTTP request headers. If multiple headers share the same key, they // must be merged according to the HTTP spec. All header keys must be // lowercased, because HTTP header keys are case-insensitive. + // + // Required: true Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` // The HTTP URL path. + // + // Required: true Path string `protobuf:"bytes,4,opt,name=path,proto3" json:"path,omitempty"` // The HTTP request `Host` header value. + // + // Required: true Host string `protobuf:"bytes,5,opt,name=host,proto3" json:"host,omitempty"` // The HTTP URL scheme, such as `http` and `https`. + // + // Required: true Scheme string `protobuf:"bytes,6,opt,name=scheme,proto3" json:"scheme,omitempty"` - // The HTTP URL query in the format of `name1=value1&name2=value2`, as it + // The HTTP URL query in the format of "name1=value1&name2=value2", as it // appears in the first line of the HTTP request. No decoding is performed. - Query string `protobuf:"bytes,7,opt,name=query,proto3" json:"query,omitempty"` + // + // Required: false + Query *string `protobuf:"bytes,7,opt,name=query,proto3,oneof" json:"query,omitempty"` // The timestamp when the `destination` service receives the first byte of // the request. - Time *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=time,proto3" json:"time,omitempty"` + // + // Required: true + Time *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=time,proto3" json:"time,omitempty"` // The network protocol used with the request, such as "http/1.1", // "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids // for details. - Protocol string `protobuf:"bytes,11,opt,name=protocol,proto3" json:"protocol,omitempty"` - // The request authentication. May be absent for unauthenticated requests. - // Derived from the HTTP request `Authorization` header or equivalent. - Auth *AttributeContext_Auth `protobuf:"bytes,13,opt,name=auth,proto3" json:"auth,omitempty"` + // + // Required: true + Protocol string `protobuf:"bytes,9,opt,name=protocol,proto3" json:"protocol,omitempty"` + // The request authentication. + // + // Required: true + Auth *AttributeContext_Auth `protobuf:"bytes,10,opt,name=auth,proto3" json:"auth,omitempty"` } func (x *AttributeContext_Request) Reset() { @@ -1084,8 +1170,8 @@ func (*AttributeContext_Request) Descriptor() ([]byte, []int) { } func (x *AttributeContext_Request) GetId() string { - if x != nil { - return x.Id + if x != nil && x.Id != nil { + return *x.Id } return "" } @@ -1126,8 +1212,8 @@ func (x *AttributeContext_Request) GetScheme() string { } func (x *AttributeContext_Request) GetQuery() string { - if x != nil { - return x.Query + if x != nil && x.Query != nil { + return *x.Query } return "" } @@ -1160,16 +1246,20 @@ type AttributeContext_Response struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The HTTP response status code, such as `200` and `404`. - Code int64 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` - // The HTTP response size in bytes. If unknown, it must be -1. - Size int64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + // The HTTP response size in bytes. + // + // Required: false + Size *wrapperspb.Int64Value `protobuf:"bytes,2,opt,name=size,proto3,oneof" json:"size,omitempty"` // The HTTP response headers. If multiple headers share the same key, they // must be merged according to HTTP spec. All header keys must be // lowercased, because HTTP header keys are case-insensitive. + // + // Required: true Headers map[string]string `protobuf:"bytes,3,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // The timestamp when the `destination` service generates the first byte of + // The timestamp when the "destination" service generates the first byte of // the response. + // + // Required: true Time *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=time,proto3" json:"time,omitempty"` } @@ -1205,18 +1295,11 @@ func (*AttributeContext_Response) Descriptor() ([]byte, []int) { return file_audit_v1_audit_event_proto_rawDescGZIP(), []int{4, 2} } -func (x *AttributeContext_Response) GetCode() int64 { - if x != nil { - return x.Code - } - return 0 -} - -func (x *AttributeContext_Response) GetSize() int64 { +func (x *AttributeContext_Response) GetSize() *wrapperspb.Int64Value { if x != nil { return x.Size } - return 0 + return nil } func (x *AttributeContext_Response) GetHeaders() map[string]string { @@ -1233,105 +1316,6 @@ func (x *AttributeContext_Response) GetTime() *timestamppb.Timestamp { return nil } -// This message defines core attributes for a resource. A resource is an -// addressable (named) entity provided by the destination service. For -// example, a file stored on a network storage service. -type AttributeContext_Resource struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // TODO check description - // The name of the service that this resource belongs to, such as - // `pubsub.googleapis.com`. The service may be different from the DNS - // hostname that actually serves the request. - Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` - // TODO check description - // The stable identifier (name) of a resource on the `service`. A resource - // can be logically identified as "//{resource.service}/{resource.name}". - // The differences between a resource name and a URI are: - // - // - Resource name is a logical identifier, independent of network - // protocol and API version. For example, - // `//pubsub.googleapis.com/projects/123/topics/news-feed`. - // - URI often includes protocol and version information, so it can - // be used directly by applications. For example, - // `https://pubsub.googleapis.com/v1/projects/123/topics/news-feed`. - // - // See https://cloud.google.com/apis/design/resource_names for details. - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` - // TODO check description - // The type of the resource. The syntax is platform-specific because - // different platforms define their resources differently. - // - // For Google APIs, the type format must be "{service}/{kind}". - Type string `protobuf:"bytes,3,opt,name=type,proto3" json:"type,omitempty"` - // TODO check description (AWS) - // The labels or tags on the resource, such as AWS resource tags and - // Kubernetes resource labels. - Labels map[string]string `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *AttributeContext_Resource) Reset() { - *x = AttributeContext_Resource{} - if protoimpl.UnsafeEnabled { - mi := &file_audit_v1_audit_event_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *AttributeContext_Resource) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*AttributeContext_Resource) ProtoMessage() {} - -func (x *AttributeContext_Resource) ProtoReflect() protoreflect.Message { - mi := &file_audit_v1_audit_event_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use AttributeContext_Resource.ProtoReflect.Descriptor instead. -func (*AttributeContext_Resource) Descriptor() ([]byte, []int) { - return file_audit_v1_audit_event_proto_rawDescGZIP(), []int{4, 3} -} - -func (x *AttributeContext_Resource) GetService() string { - if x != nil { - return x.Service - } - return "" -} - -func (x *AttributeContext_Resource) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *AttributeContext_Resource) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *AttributeContext_Resource) GetLabels() map[string]string { - if x != nil { - return x.Labels - } - return nil -} - // Anonymous system principal to be used when no user identity is available. type ServiceAccountDelegationInfo_SystemPrincipal struct { state protoimpl.MessageState @@ -1339,13 +1323,15 @@ type ServiceAccountDelegationInfo_SystemPrincipal struct { unknownFields protoimpl.UnknownFields // Metadata about the service that uses the service account. - ServiceMetadata *structpb.Struct `protobuf:"bytes,3,opt,name=service_metadata,json=serviceMetadata,proto3" json:"service_metadata,omitempty"` + // + // Required: false + ServiceMetadata *structpb.Struct `protobuf:"bytes,1,opt,name=service_metadata,json=serviceMetadata,proto3,oneof" json:"service_metadata,omitempty"` } func (x *ServiceAccountDelegationInfo_SystemPrincipal) Reset() { *x = ServiceAccountDelegationInfo_SystemPrincipal{} if protoimpl.UnsafeEnabled { - mi := &file_audit_v1_audit_event_proto_msgTypes[16] + mi := &file_audit_v1_audit_event_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1358,7 +1344,7 @@ func (x *ServiceAccountDelegationInfo_SystemPrincipal) String() string { func (*ServiceAccountDelegationInfo_SystemPrincipal) ProtoMessage() {} func (x *ServiceAccountDelegationInfo_SystemPrincipal) ProtoReflect() protoreflect.Message { - mi := &file_audit_v1_audit_event_proto_msgTypes[16] + mi := &file_audit_v1_audit_event_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1388,17 +1374,24 @@ type ServiceAccountDelegationInfo_IdpPrincipal struct { unknownFields protoimpl.UnknownFields // STACKIT principal id + // + // Required: true PrincipalId string `protobuf:"bytes,1,opt,name=principal_id,json=principalId,proto3" json:"principal_id,omitempty"` - // Optional email address - PrincipalEmail *string `protobuf:"bytes,2,opt,name=principal_email,json=principalEmail,proto3,oneof" json:"principal_email,omitempty"` + // The email address of the authenticated user. + // Service accounts have email addresses that can be used. + // + // Required: true + PrincipalEmail string `protobuf:"bytes,2,opt,name=principal_email,json=principalEmail,proto3" json:"principal_email,omitempty"` // Metadata about the service that uses the service account. - ServiceMetadata *structpb.Struct `protobuf:"bytes,3,opt,name=service_metadata,json=serviceMetadata,proto3" json:"service_metadata,omitempty"` + // + // Required: false + ServiceMetadata *structpb.Struct `protobuf:"bytes,3,opt,name=service_metadata,json=serviceMetadata,proto3,oneof" json:"service_metadata,omitempty"` } func (x *ServiceAccountDelegationInfo_IdpPrincipal) Reset() { *x = ServiceAccountDelegationInfo_IdpPrincipal{} if protoimpl.UnsafeEnabled { - mi := &file_audit_v1_audit_event_proto_msgTypes[17] + mi := &file_audit_v1_audit_event_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1411,7 +1404,7 @@ func (x *ServiceAccountDelegationInfo_IdpPrincipal) String() string { func (*ServiceAccountDelegationInfo_IdpPrincipal) ProtoMessage() {} func (x *ServiceAccountDelegationInfo_IdpPrincipal) ProtoReflect() protoreflect.Message { - mi := &file_audit_v1_audit_event_proto_msgTypes[17] + mi := &file_audit_v1_audit_event_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1435,8 +1428,8 @@ func (x *ServiceAccountDelegationInfo_IdpPrincipal) GetPrincipalId() string { } func (x *ServiceAccountDelegationInfo_IdpPrincipal) GetPrincipalEmail() string { - if x != nil && x.PrincipalEmail != nil { - return *x.PrincipalEmail + if x != nil { + return x.PrincipalEmail } return "" } @@ -1460,243 +1453,307 @@ var file_audit_v1_audit_event_proto_rawDesc = []byte{ 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x61, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, + 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xd0, 0x03, 0x0a, 0x0d, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, - 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x37, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, - 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x52, 0x0c, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x69, 0x6e, - 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x69, - 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x6f, - 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x38, 0x0a, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x31, 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, - 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x52, 0x08, - 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x16, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, - 0x74, 0x72, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x74, - 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x39, 0x0a, 0x0b, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x82, 0x05, 0x0a, 0x08, 0x41, 0x75, 0x64, 0x69, - 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, - 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x23, 0x0a, - 0x0d, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x13, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, - 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x61, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc1, 0x06, 0x0a, 0x0d, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, + 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x77, 0x0a, 0x08, 0x6c, 0x6f, 0x67, 0x5f, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x5c, 0xba, 0x48, 0x59, 0xc8, 0x01, 0x01, + 0x72, 0x54, 0x32, 0x52, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x5d, 0x2b, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, + 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x2f, 0x6c, 0x6f, 0x67, 0x73, 0x2f, 0x28, 0x3f, 0x3a, 0x61, + 0x64, 0x6d, 0x69, 0x6e, 0x2d, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x7c, 0x73, 0x79, + 0x73, 0x74, 0x65, 0x6d, 0x2d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x7c, 0x70, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x2d, 0x64, 0x65, 0x6e, 0x69, 0x65, 0x64, 0x7c, 0x64, 0x61, 0x74, 0x61, 0x2d, 0x61, 0x63, + 0x63, 0x65, 0x73, 0x73, 0x29, 0x24, 0x52, 0x07, 0x6c, 0x6f, 0x67, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x3f, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x5f, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, + 0x01, 0x01, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, + 0x12, 0x4b, 0x0a, 0x09, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x2e, 0xba, 0x48, 0x2b, 0xc8, 0x01, 0x01, 0x72, 0x26, 0x32, 0x24, 0x5e, + 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, + 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x2f, 0x5b, 0x30, 0x2d, 0x39, + 0x5d, 0x2b, 0x24, 0x52, 0x08, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x49, 0x64, 0x12, 0x43, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, + 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x64, 0x69, 0x74, 0x4c, 0x6f, + 0x67, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x12, 0x33, 0x0a, 0x0e, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xba, 0x48, 0x04, 0x72, + 0x02, 0x10, 0x01, 0x48, 0x00, 0x52, 0x0d, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x88, 0x01, 0x01, 0x12, 0x45, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0xb2, 0x01, + 0x02, 0x38, 0x01, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x3e, + 0x0a, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x15, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x53, + 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x82, + 0x01, 0x02, 0x10, 0x01, 0x52, 0x08, 0x73, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x52, + 0x0a, 0x0c, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x2a, 0xba, 0x48, 0x27, 0x72, 0x25, 0x32, 0x23, 0x5e, 0x5b, 0x30, + 0x2d, 0x39, 0x5d, 0x2b, 0x2d, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x2d, 0x5b, + 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x2d, 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, + 0x48, 0x01, 0x52, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x88, + 0x01, 0x01, 0x12, 0x65, 0x0a, 0x0b, 0x74, 0x72, 0x61, 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x3f, 0xba, 0x48, 0x3c, 0x72, 0x3a, 0x32, 0x38, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x3d, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x28, 0x3f, 0x3a, 0x2c, 0x5b, 0x61, 0x2d, + 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x3d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, + 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x29, 0x2a, 0x48, 0x02, 0x52, 0x0a, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x88, 0x01, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, + 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x42, 0x11, 0x0a, 0x0f, 0x5f, 0x63, 0x6f, 0x72, 0x72, 0x65, 0x6c, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x74, 0x72, 0x61, + 0x63, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0x89, 0x07, 0x0a, 0x08, 0x41, 0x75, 0x64, + 0x69, 0x74, 0x4c, 0x6f, 0x67, 0x12, 0x2d, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, + 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x63, 0x0a, 0x0b, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x5f, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x42, 0xba, 0x48, 0x3f, 0xc8, 0x01, + 0x01, 0x72, 0x3a, 0x32, 0x38, 0x5e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x74, 0x5c, 0x2e, 0x5b, + 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x5c, 0x2e, 0x76, 0x5b, 0x31, 0x2d, 0x39, 0x5d, + 0x5b, 0x30, 0x2d, 0x39, 0x5d, 0x2a, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, + 0x2b, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x0a, 0x6d, + 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x0d, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x69, 0xba, 0x48, 0x66, 0xc8, 0x01, 0x01, 0x72, 0x61, 0x32, 0x5f, 0x5e, 0x5b, 0x61, + 0x2d, 0x7a, 0x5d, 0x2b, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x28, + 0x3f, 0x3a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x28, 0x3f, 0x3a, + 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x28, 0x3f, 0x3a, 0x2d, + 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x29, 0x3f, 0x29, 0x7c, 0x5f, 0x29, 0x29, + 0x3f, 0x28, 0x3f, 0x3a, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x2f, 0x5b, + 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x29, 0x2a, 0x24, 0x52, 0x0c, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x55, 0x0a, 0x13, 0x61, 0x75, + 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, + 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4a, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x61, 0x75, 0x74, 0x68, - 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x44, 0x0a, + 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x4c, 0x0a, 0x10, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, + 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x31, 0x0a, 0x07, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x10, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x72, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, + 0x74, 0x61, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x0f, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x07, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, + 0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x07, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x31, 0x0a, 0x12, 0x6e, 0x75, 0x6d, 0x5f, - 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x03, 0x48, 0x01, 0x52, 0x10, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x33, 0x0a, 0x08, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x33, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x12, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x6d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x9f, 0x02, 0x0a, - 0x12, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, - 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, - 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, - 0x70, 0x61, 0x6c, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, - 0x35, 0x0a, 0x14, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, - 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, - 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x6d, 0x0a, 0x1f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x26, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x1c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x5f, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xbf, - 0x01, 0x0a, 0x11, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x12, 0x18, 0x0a, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x12, 0x54, 0x0a, 0x13, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, - 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x12, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, - 0x22, 0x9d, 0x08, 0x0a, 0x10, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x74, 0x65, 0x78, 0x74, 0x1a, 0xb6, 0x01, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1c, - 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, - 0x61, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x09, 0x61, 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x72, - 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, - 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x2f, 0x0a, 0x06, 0x63, 0x6c, 0x61, 0x69, - 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x57, 0x0a, 0x12, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, + 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x07, 0xba, 0x48, 0x04, 0x22, 0x02, + 0x28, 0x00, 0x48, 0x00, 0x52, 0x10, 0x6e, 0x75, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x08, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, + 0x72, 0x75, 0x63, 0x74, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x08, 0x72, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, - 0x74, 0x52, 0x06, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x73, 0x1a, 0x8f, - 0x03, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, - 0x6f, 0x64, 0x12, 0x49, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, - 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, - 0x68, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, - 0x65, 0x72, 0x79, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, - 0x69, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, - 0x33, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, - 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, - 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x04, - 0x61, 0x75, 0x74, 0x68, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x1a, 0xea, 0x01, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, - 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x4a, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x64, - 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x04, 0x74, 0x69, 0x6d, - 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xd0, 0x01, - 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x47, 0x0a, 0x06, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, - 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, - 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0xbe, 0x01, 0x0a, 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, - 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, - 0x70, 0x12, 0x3b, 0x0a, 0x1a, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x70, 0x70, - 0x6c, 0x69, 0x65, 0x64, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x17, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x53, 0x75, 0x70, - 0x70, 0x6c, 0x69, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x51, - 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, - 0x75, 0x74, 0x65, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x61, 0x75, 0x64, - 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, - 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x11, - 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, - 0x73, 0x22, 0x71, 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, - 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x12, 0x31, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x64, 0x65, 0x74, - 0x61, 0x69, 0x6c, 0x73, 0x22, 0xfd, 0x03, 0x0a, 0x1c, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x63, 0x0a, 0x10, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, - 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x36, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, - 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, - 0x6d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x5a, 0x0a, 0x0d, 0x69, 0x64, - 0x70, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x49, 0x64, 0x70, 0x50, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x48, 0x00, 0x52, 0x0c, 0x69, 0x64, 0x70, 0x50, 0x72, 0x69, - 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x1a, 0x55, 0x0a, 0x0f, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, - 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x42, 0x0a, 0x10, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x0f, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xb7, 0x01, - 0x0a, 0x0c, 0x49, 0x64, 0x70, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x21, - 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, - 0x64, 0x12, 0x2c, 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, 0x70, 0x72, - 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x88, 0x01, 0x01, 0x12, - 0x42, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, - 0x63, 0x74, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x42, 0x12, 0x0a, 0x10, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, - 0x6c, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x42, 0x0b, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x69, 0x74, 0x79, 0x2a, 0x82, 0x01, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x53, 0x65, 0x76, 0x65, - 0x72, 0x69, 0x74, 0x79, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x10, - 0x00, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x64, 0x12, 0x09, 0x0a, 0x04, - 0x49, 0x4e, 0x46, 0x4f, 0x10, 0xc8, 0x01, 0x12, 0x0b, 0x0a, 0x06, 0x4e, 0x4f, 0x54, 0x49, 0x43, - 0x45, 0x10, 0xac, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x57, 0x41, 0x52, 0x4e, 0x49, 0x4e, 0x47, 0x10, - 0x90, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0xf4, 0x03, 0x12, 0x0d, - 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, 0xd8, 0x04, 0x12, 0x0a, 0x0a, - 0x05, 0x41, 0x4c, 0x45, 0x52, 0x54, 0x10, 0xbc, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x4d, 0x45, - 0x52, 0x47, 0x45, 0x4e, 0x43, 0x59, 0x10, 0xa0, 0x06, 0x42, 0x81, 0x01, 0x0a, 0x1c, 0x63, 0x6f, - 0x6d, 0x2e, 0x73, 0x63, 0x68, 0x77, 0x61, 0x72, 0x7a, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, - 0x74, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x0f, 0x41, 0x75, 0x64, 0x69, - 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0f, 0x2e, - 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x3b, 0x61, 0x75, 0x64, 0x69, 0x74, 0x56, 0x31, 0xa2, 0x02, - 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, - 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, 0x41, 0x75, 0x64, - 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x09, 0x41, 0x75, 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x48, 0x01, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, + 0x42, 0x15, 0x0a, 0x13, 0x5f, 0x6e, 0x75, 0x6d, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x22, 0xf4, 0x02, 0x0a, 0x12, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, + 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x2d, 0x0a, 0x0c, 0x70, + 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0b, 0x70, + 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x36, 0x0a, 0x0f, 0x70, 0x72, + 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x0a, 0xc8, 0x01, 0x01, 0x72, 0x05, 0x10, 0x01, 0x18, + 0xff, 0x01, 0x52, 0x0e, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x45, 0x6d, 0x61, + 0x69, 0x6c, 0x12, 0x6f, 0x0a, 0x14, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x42, 0x38, 0xba, 0x48, 0x35, 0x72, 0x33, 0x32, 0x31, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x5d, 0x2b, + 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, + 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x24, 0x48, 0x00, 0x52, 0x12, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x88, 0x01, 0x01, 0x12, 0x6d, 0x0a, 0x1f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, + 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x1c, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, + 0x66, 0x6f, 0x42, 0x17, 0x0a, 0x15, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xa3, 0x02, 0x0a, 0x11, + 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, + 0x6f, 0x12, 0x85, 0x01, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x69, 0xba, 0x48, 0x66, 0xc8, 0x01, 0x01, 0x72, 0x61, 0x32, 0x5f, + 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x5d, 0x2b, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, + 0x5d, 0x2b, 0x28, 0x3f, 0x3a, 0x2f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x28, 0x3f, 0x3a, 0x28, 0x3f, 0x3a, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x28, + 0x3f, 0x3a, 0x2d, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x29, 0x3f, 0x29, 0x7c, + 0x5f, 0x29, 0x29, 0x3f, 0x28, 0x3f, 0x3a, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, + 0x2b, 0x2f, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x2d, 0x5d, 0x2b, 0x29, 0x2a, 0x24, 0x52, + 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x70, 0x65, 0x72, + 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x27, 0xba, + 0x48, 0x24, 0x72, 0x22, 0x32, 0x20, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x2d, 0x5d, 0x2b, 0x28, 0x3f, + 0x3a, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x2d, 0x5d, 0x2b, 0x29, 0x2a, 0x5c, 0x2e, 0x5b, 0x61, + 0x2d, 0x7a, 0x2d, 0x5d, 0x2b, 0x24, 0x48, 0x00, 0x52, 0x0a, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x07, 0x67, 0x72, 0x61, 0x6e, + 0x74, 0x65, 0x64, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x70, 0x65, 0x72, 0x6d, 0x69, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, + 0x64, 0x22, 0xa8, 0x08, 0x0a, 0x10, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, + 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x1a, 0xa8, 0x01, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, + 0x49, 0x0a, 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x2b, 0xba, 0x48, 0x28, 0xc8, 0x01, 0x01, 0x72, 0x23, 0x32, 0x21, 0x5e, 0x5b, + 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x25, 0x2e, 0x5d, 0x2b, 0x2f, 0x5b, + 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x2d, 0x25, 0x2e, 0x5d, 0x2b, 0x24, 0x52, + 0x09, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x75, + 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x75, 0x64, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x37, 0x0a, 0x06, 0x63, 0x6c, 0x61, 0x69, + 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x06, 0x63, 0x6c, 0x61, 0x69, 0x6d, + 0x73, 0x1a, 0xc6, 0x04, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x13, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x02, 0x69, 0x64, 0x88, + 0x01, 0x01, 0x12, 0x22, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x51, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, + 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x1e, 0x0a, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, + 0x02, 0x10, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1e, 0x0a, 0x04, 0x68, 0x6f, 0x73, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, + 0x02, 0x10, 0x01, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x12, 0x22, 0x0a, 0x06, 0x73, 0x63, 0x68, + 0x65, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, + 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x06, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x12, 0x5c, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x41, 0xba, 0x48, + 0x3e, 0x72, 0x3c, 0x32, 0x3a, 0x5e, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, + 0x5d, 0x2b, 0x3d, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x28, + 0x3f, 0x3a, 0x26, 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x3d, + 0x5b, 0x61, 0x2d, 0x7a, 0x41, 0x2d, 0x5a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x29, 0x2a, 0x24, 0x48, + 0x01, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x3b, 0x0a, 0x04, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0xb2, 0x01, 0x02, + 0x38, 0x01, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, + 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x12, 0x3b, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, + 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x42, + 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x04, 0x61, 0x75, 0x74, 0x68, 0x1a, 0x3a, 0x0a, + 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x05, 0x0a, 0x03, 0x5f, 0x69, 0x64, + 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x71, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x9f, 0x02, 0x0a, 0x08, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x56, 0x61, 0x6c, + 0x75, 0x65, 0x42, 0x07, 0xba, 0x48, 0x04, 0x22, 0x02, 0x28, 0x00, 0x48, 0x00, 0x52, 0x04, 0x73, + 0x69, 0x7a, 0x65, 0x88, 0x01, 0x01, 0x12, 0x52, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, + 0x01, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x12, 0x3b, 0x0a, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0xb2, 0x01, 0x02, 0x38, + 0x01, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x22, 0xde, 0x01, 0x0a, + 0x0f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x27, 0x0a, 0x09, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x5f, 0x69, 0x70, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x70, 0x01, 0x52, + 0x08, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x49, 0x70, 0x12, 0x47, 0x0a, 0x1a, 0x63, 0x61, 0x6c, + 0x6c, 0x65, 0x72, 0x5f, 0x73, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x5f, 0x75, 0x73, 0x65, + 0x72, 0x5f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, + 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x17, 0x63, 0x61, 0x6c, 0x6c, 0x65, + 0x72, 0x53, 0x75, 0x70, 0x70, 0x6c, 0x69, 0x65, 0x64, 0x55, 0x73, 0x65, 0x72, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x12, 0x59, 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x61, 0x74, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, + 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x42, 0x06, 0xba, 0x48, 0x03, 0xc8, 0x01, 0x01, 0x52, 0x11, 0x72, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0xab, 0x01, + 0x0a, 0x0e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x12, 0x3b, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0a, 0xba, 0x48, 0x07, + 0xc8, 0x01, 0x01, 0x1a, 0x02, 0x28, 0x00, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x1d, 0x0a, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x31, 0x0a, 0x07, + 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x42, + 0x0a, 0x0a, 0x08, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xba, 0x04, 0x0a, 0x1c, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x44, 0x65, + 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x63, 0x0a, 0x10, + 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, + 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x48, 0x00, + 0x52, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x12, 0x5a, 0x0a, 0x0d, 0x69, 0x64, 0x70, 0x5f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, + 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, + 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x44, 0x65, 0x6c, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x6e, 0x66, 0x6f, + 0x2e, 0x49, 0x64, 0x70, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x48, 0x00, 0x52, + 0x0c, 0x69, 0x64, 0x70, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x1a, 0x6f, 0x0a, + 0x0f, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, + 0x12, 0x47, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0xd3, + 0x01, 0x0a, 0x0c, 0x49, 0x64, 0x70, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, + 0x2d, 0x0a, 0x0c, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, + 0x01, 0x52, 0x0b, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x36, + 0x0a, 0x0f, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x5f, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0d, 0xba, 0x48, 0x0a, 0xc8, 0x01, 0x01, 0x72, + 0x05, 0x10, 0x01, 0x18, 0xff, 0x01, 0x52, 0x0e, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x47, 0x0a, 0x10, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x88, 0x01, 0x01, 0x42, + 0x13, 0x0a, 0x11, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x42, 0x12, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, + 0x79, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x2a, 0x93, 0x01, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, + 0x53, 0x65, 0x76, 0x65, 0x72, 0x69, 0x74, 0x79, 0x12, 0x0f, 0x0a, 0x0b, 0x55, 0x4e, 0x53, 0x50, + 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x46, + 0x41, 0x55, 0x4c, 0x54, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, + 0x64, 0x12, 0x09, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0xc8, 0x01, 0x12, 0x0b, 0x0a, 0x06, + 0x4e, 0x4f, 0x54, 0x49, 0x43, 0x45, 0x10, 0xac, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x57, 0x41, 0x52, + 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x90, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x10, 0xf4, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x52, 0x49, 0x54, 0x49, 0x43, 0x41, 0x4c, 0x10, + 0xd8, 0x04, 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x4c, 0x45, 0x52, 0x54, 0x10, 0xbc, 0x05, 0x12, 0x0e, + 0x0a, 0x09, 0x45, 0x4d, 0x45, 0x52, 0x47, 0x45, 0x4e, 0x43, 0x59, 0x10, 0xa0, 0x06, 0x42, 0x81, + 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x63, 0x68, 0x77, 0x61, 0x72, 0x7a, 0x2e, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x69, 0x74, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, + 0x0f, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, + 0x50, 0x01, 0x5a, 0x0f, 0x2e, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x3b, 0x61, 0x75, 0x64, 0x69, + 0x74, 0x56, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, + 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0xe2, + 0x02, 0x14, 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, + 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x41, 0x75, 0x64, 0x69, 0x74, 0x3a, 0x3a, + 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1712,7 +1769,7 @@ func file_audit_v1_audit_event_proto_rawDescGZIP() []byte { } var file_audit_v1_audit_event_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_audit_v1_audit_event_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_audit_v1_audit_event_proto_msgTypes = make([]protoimpl.MessageInfo, 16) var file_audit_v1_audit_event_proto_goTypes = []interface{}{ (LogSeverity)(0), // 0: audit.v1.LogSeverity (*AuditLogEntry)(nil), // 1: audit.v1.AuditLogEntry @@ -1727,47 +1784,48 @@ var file_audit_v1_audit_event_proto_goTypes = []interface{}{ (*AttributeContext_Auth)(nil), // 10: audit.v1.AttributeContext.Auth (*AttributeContext_Request)(nil), // 11: audit.v1.AttributeContext.Request (*AttributeContext_Response)(nil), // 12: audit.v1.AttributeContext.Response - (*AttributeContext_Resource)(nil), // 13: audit.v1.AttributeContext.Resource - nil, // 14: audit.v1.AttributeContext.Request.HeadersEntry - nil, // 15: audit.v1.AttributeContext.Response.HeadersEntry - nil, // 16: audit.v1.AttributeContext.Resource.LabelsEntry - (*ServiceAccountDelegationInfo_SystemPrincipal)(nil), // 17: audit.v1.ServiceAccountDelegationInfo.SystemPrincipal - (*ServiceAccountDelegationInfo_IdpPrincipal)(nil), // 18: audit.v1.ServiceAccountDelegationInfo.IdpPrincipal - (*timestamppb.Timestamp)(nil), // 19: google.protobuf.Timestamp - (*structpb.Struct)(nil), // 20: google.protobuf.Struct + nil, // 13: audit.v1.AttributeContext.Request.HeadersEntry + nil, // 14: audit.v1.AttributeContext.Response.HeadersEntry + (*ServiceAccountDelegationInfo_SystemPrincipal)(nil), // 15: audit.v1.ServiceAccountDelegationInfo.SystemPrincipal + (*ServiceAccountDelegationInfo_IdpPrincipal)(nil), // 16: audit.v1.ServiceAccountDelegationInfo.IdpPrincipal + (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp + (*structpb.Struct)(nil), // 18: google.protobuf.Struct + (*wrapperspb.Int64Value)(nil), // 19: google.protobuf.Int64Value + (*wrapperspb.Int32Value)(nil), // 20: google.protobuf.Int32Value } var file_audit_v1_audit_event_proto_depIdxs = []int32{ 2, // 0: audit.v1.AuditLogEntry.proto_payload:type_name -> audit.v1.AuditLog 9, // 1: audit.v1.AuditLogEntry.labels:type_name -> audit.v1.AuditLogEntry.LabelsEntry - 19, // 2: audit.v1.AuditLogEntry.timestamp:type_name -> google.protobuf.Timestamp + 17, // 2: audit.v1.AuditLogEntry.timestamp:type_name -> google.protobuf.Timestamp 0, // 3: audit.v1.AuditLogEntry.severity:type_name -> audit.v1.LogSeverity 3, // 4: audit.v1.AuditLog.authentication_info:type_name -> audit.v1.AuthenticationInfo 4, // 5: audit.v1.AuditLog.authorization_info:type_name -> audit.v1.AuthorizationInfo 6, // 6: audit.v1.AuditLog.request_metadata:type_name -> audit.v1.RequestMetadata - 20, // 7: audit.v1.AuditLog.request:type_name -> google.protobuf.Struct + 18, // 7: audit.v1.AuditLog.request:type_name -> google.protobuf.Struct 7, // 8: audit.v1.AuditLog.status:type_name -> audit.v1.ResponseStatus - 20, // 9: audit.v1.AuditLog.response:type_name -> google.protobuf.Struct - 20, // 10: audit.v1.AuditLog.metadata:type_name -> google.protobuf.Struct - 8, // 11: audit.v1.AuthenticationInfo.service_account_delegation_info:type_name -> audit.v1.ServiceAccountDelegationInfo - 13, // 12: audit.v1.AuthorizationInfo.resource_attributes:type_name -> audit.v1.AttributeContext.Resource + 19, // 9: audit.v1.AuditLog.num_response_items:type_name -> google.protobuf.Int64Value + 18, // 10: audit.v1.AuditLog.response:type_name -> google.protobuf.Struct + 18, // 11: audit.v1.AuditLog.metadata:type_name -> google.protobuf.Struct + 8, // 12: audit.v1.AuthenticationInfo.service_account_delegation_info:type_name -> audit.v1.ServiceAccountDelegationInfo 11, // 13: audit.v1.RequestMetadata.request_attributes:type_name -> audit.v1.AttributeContext.Request - 20, // 14: audit.v1.ResponseStatus.details:type_name -> google.protobuf.Struct - 17, // 15: audit.v1.ServiceAccountDelegationInfo.system_principal:type_name -> audit.v1.ServiceAccountDelegationInfo.SystemPrincipal - 18, // 16: audit.v1.ServiceAccountDelegationInfo.idp_principal:type_name -> audit.v1.ServiceAccountDelegationInfo.IdpPrincipal - 20, // 17: audit.v1.AttributeContext.Auth.claims:type_name -> google.protobuf.Struct - 14, // 18: audit.v1.AttributeContext.Request.headers:type_name -> audit.v1.AttributeContext.Request.HeadersEntry - 19, // 19: audit.v1.AttributeContext.Request.time:type_name -> google.protobuf.Timestamp - 10, // 20: audit.v1.AttributeContext.Request.auth:type_name -> audit.v1.AttributeContext.Auth - 15, // 21: audit.v1.AttributeContext.Response.headers:type_name -> audit.v1.AttributeContext.Response.HeadersEntry - 19, // 22: audit.v1.AttributeContext.Response.time:type_name -> google.protobuf.Timestamp - 16, // 23: audit.v1.AttributeContext.Resource.labels:type_name -> audit.v1.AttributeContext.Resource.LabelsEntry - 20, // 24: audit.v1.ServiceAccountDelegationInfo.SystemPrincipal.service_metadata:type_name -> google.protobuf.Struct - 20, // 25: audit.v1.ServiceAccountDelegationInfo.IdpPrincipal.service_metadata:type_name -> google.protobuf.Struct - 26, // [26:26] is the sub-list for method output_type - 26, // [26:26] is the sub-list for method input_type - 26, // [26:26] is the sub-list for extension type_name - 26, // [26:26] is the sub-list for extension extendee - 0, // [0:26] is the sub-list for field type_name + 20, // 14: audit.v1.ResponseStatus.code:type_name -> google.protobuf.Int32Value + 18, // 15: audit.v1.ResponseStatus.details:type_name -> google.protobuf.Struct + 15, // 16: audit.v1.ServiceAccountDelegationInfo.system_principal:type_name -> audit.v1.ServiceAccountDelegationInfo.SystemPrincipal + 16, // 17: audit.v1.ServiceAccountDelegationInfo.idp_principal:type_name -> audit.v1.ServiceAccountDelegationInfo.IdpPrincipal + 18, // 18: audit.v1.AttributeContext.Auth.claims:type_name -> google.protobuf.Struct + 13, // 19: audit.v1.AttributeContext.Request.headers:type_name -> audit.v1.AttributeContext.Request.HeadersEntry + 17, // 20: audit.v1.AttributeContext.Request.time:type_name -> google.protobuf.Timestamp + 10, // 21: audit.v1.AttributeContext.Request.auth:type_name -> audit.v1.AttributeContext.Auth + 19, // 22: audit.v1.AttributeContext.Response.size:type_name -> google.protobuf.Int64Value + 14, // 23: audit.v1.AttributeContext.Response.headers:type_name -> audit.v1.AttributeContext.Response.HeadersEntry + 17, // 24: audit.v1.AttributeContext.Response.time:type_name -> google.protobuf.Timestamp + 18, // 25: audit.v1.ServiceAccountDelegationInfo.SystemPrincipal.service_metadata:type_name -> google.protobuf.Struct + 18, // 26: audit.v1.ServiceAccountDelegationInfo.IdpPrincipal.service_metadata:type_name -> google.protobuf.Struct + 27, // [27:27] is the sub-list for method output_type + 27, // [27:27] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_audit_v1_audit_event_proto_init() } @@ -1909,19 +1967,7 @@ func file_audit_v1_audit_event_proto_init() { return nil } } - file_audit_v1_audit_event_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AttributeContext_Resource); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_audit_v1_audit_event_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_audit_v1_audit_event_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ServiceAccountDelegationInfo_SystemPrincipal); i { case 0: return &v.state @@ -1933,7 +1979,7 @@ func file_audit_v1_audit_event_proto_init() { return nil } } - file_audit_v1_audit_event_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_audit_v1_audit_event_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ServiceAccountDelegationInfo_IdpPrincipal); i { case 0: return &v.state @@ -1946,20 +1992,26 @@ func file_audit_v1_audit_event_proto_init() { } } } + file_audit_v1_audit_event_proto_msgTypes[0].OneofWrappers = []interface{}{} file_audit_v1_audit_event_proto_msgTypes[1].OneofWrappers = []interface{}{} file_audit_v1_audit_event_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_audit_v1_audit_event_proto_msgTypes[3].OneofWrappers = []interface{}{} + file_audit_v1_audit_event_proto_msgTypes[6].OneofWrappers = []interface{}{} file_audit_v1_audit_event_proto_msgTypes[7].OneofWrappers = []interface{}{ (*ServiceAccountDelegationInfo_SystemPrincipal_)(nil), (*ServiceAccountDelegationInfo_IdpPrincipal_)(nil), } - file_audit_v1_audit_event_proto_msgTypes[17].OneofWrappers = []interface{}{} + file_audit_v1_audit_event_proto_msgTypes[10].OneofWrappers = []interface{}{} + file_audit_v1_audit_event_proto_msgTypes[11].OneofWrappers = []interface{}{} + file_audit_v1_audit_event_proto_msgTypes[14].OneofWrappers = []interface{}{} + file_audit_v1_audit_event_proto_msgTypes[15].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_audit_v1_audit_event_proto_rawDesc, NumEnums: 1, - NumMessages: 18, + NumMessages: 16, NumExtensions: 0, NumServices: 0, }, diff --git a/gen/go/audit/v1/audit_event.pb.validate.go b/gen/go/audit/v1/audit_event.pb.validate.go index ee81e9b..0f7bb6e 100644 --- a/gen/go/audit/v1/audit_event.pb.validate.go +++ b/gen/go/audit/v1/audit_event.pb.validate.go @@ -92,8 +92,6 @@ func (m *AuditLogEntry) validate(all bool) error { // no validation rules for Labels - // no validation rules for CorrelationId - if all { switch v := interface{}(m.GetTimestamp()).(type) { case interface{ ValidateAll() error }: @@ -125,9 +123,17 @@ func (m *AuditLogEntry) validate(all bool) error { // no validation rules for Severity - // no validation rules for TraceParent + if m.CorrelationId != nil { + // no validation rules for CorrelationId + } - // no validation rules for TraceState + if m.TraceParent != nil { + // no validation rules for TraceParent + } + + if m.TraceState != nil { + // no validation rules for TraceState + } if len(errors) > 0 { return AuditLogEntryMultiError(errors) @@ -231,6 +237,8 @@ func (m *AuditLog) validate(all bool) error { // no validation rules for ServiceName + // no validation rules for MethodName + // no validation rules for ResourceName if all { @@ -412,41 +420,70 @@ func (m *AuditLog) validate(all bool) error { } } - if all { - switch v := interface{}(m.GetMetadata()).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, AuditLogValidationError{ - field: "Metadata", - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, AuditLogValidationError{ - field: "Metadata", - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return AuditLogValidationError{ - field: "Metadata", - reason: "embedded message failed validation", - cause: err, - } - } - } - - if m.MethodName != nil { - // no validation rules for MethodName - } - if m.NumResponseItems != nil { - // no validation rules for NumResponseItems + + if all { + switch v := interface{}(m.GetNumResponseItems()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, AuditLogValidationError{ + field: "NumResponseItems", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, AuditLogValidationError{ + field: "NumResponseItems", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetNumResponseItems()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return AuditLogValidationError{ + field: "NumResponseItems", + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if m.Metadata != nil { + + if all { + switch v := interface{}(m.GetMetadata()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, AuditLogValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, AuditLogValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetMetadata()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return AuditLogValidationError{ + field: "Metadata", + reason: "embedded message failed validation", + cause: err, + } + } + } + } if len(errors) > 0 { @@ -694,37 +731,12 @@ func (m *AuthorizationInfo) validate(all bool) error { // no validation rules for Resource - // no validation rules for Permission + if m.Permission != nil { + // no validation rules for Permission + } - // no validation rules for Granted - - if all { - switch v := interface{}(m.GetResourceAttributes()).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, AuthorizationInfoValidationError{ - field: "ResourceAttributes", - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, AuthorizationInfoValidationError{ - field: "ResourceAttributes", - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(m.GetResourceAttributes()).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return AuthorizationInfoValidationError{ - field: "ResourceAttributes", - reason: "embedded message failed validation", - cause: err, - } - } + if m.Granted != nil { + // no validation rules for Granted } if len(errors) > 0 { @@ -1062,9 +1074,34 @@ func (m *ResponseStatus) validate(all bool) error { var errors []error - // no validation rules for Code - - // no validation rules for Message + if all { + switch v := interface{}(m.GetCode()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ResponseStatusValidationError{ + field: "Code", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ResponseStatusValidationError{ + field: "Code", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetCode()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResponseStatusValidationError{ + field: "Code", + reason: "embedded message failed validation", + cause: err, + } + } + } for idx, item := range m.GetDetails() { _, _ = idx, item @@ -1100,6 +1137,10 @@ func (m *ResponseStatus) validate(all bool) error { } + if m.Message != nil { + // no validation rules for Message + } + if len(errors) > 0 { return ResponseStatusMultiError(errors) } @@ -1392,8 +1433,6 @@ func (m *AttributeContext_Auth) validate(all bool) error { // no validation rules for Principal - // no validation rules for Presenter - if all { switch v := interface{}(m.GetClaims()).(type) { case interface{ ValidateAll() error }: @@ -1525,8 +1564,6 @@ func (m *AttributeContext_Request) validate(all bool) error { var errors []error - // no validation rules for Id - // no validation rules for Method // no validation rules for Headers @@ -1537,8 +1574,6 @@ func (m *AttributeContext_Request) validate(all bool) error { // no validation rules for Scheme - // no validation rules for Query - if all { switch v := interface{}(m.GetTime()).(type) { case interface{ ValidateAll() error }: @@ -1599,6 +1634,14 @@ func (m *AttributeContext_Request) validate(all bool) error { } } + if m.Id != nil { + // no validation rules for Id + } + + if m.Query != nil { + // no validation rules for Query + } + if len(errors) > 0 { return AttributeContext_RequestMultiError(errors) } @@ -1701,10 +1744,6 @@ func (m *AttributeContext_Response) validate(all bool) error { var errors []error - // no validation rules for Code - - // no validation rules for Size - // no validation rules for Headers if all { @@ -1736,6 +1775,39 @@ func (m *AttributeContext_Response) validate(all bool) error { } } + if m.Size != nil { + + if all { + switch v := interface{}(m.GetSize()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, AttributeContext_ResponseValidationError{ + field: "Size", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, AttributeContext_ResponseValidationError{ + field: "Size", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetSize()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return AttributeContext_ResponseValidationError{ + field: "Size", + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + if len(errors) > 0 { return AttributeContext_ResponseMultiError(errors) } @@ -1816,116 +1888,6 @@ var _ interface { ErrorName() string } = AttributeContext_ResponseValidationError{} -// Validate checks the field values on AttributeContext_Resource with the rules -// defined in the proto definition for this message. If any rules are -// violated, the first error encountered is returned, or nil if there are no violations. -func (m *AttributeContext_Resource) Validate() error { - return m.validate(false) -} - -// ValidateAll checks the field values on AttributeContext_Resource with the -// rules defined in the proto definition for this message. If any rules are -// violated, the result is a list of violation errors wrapped in -// AttributeContext_ResourceMultiError, or nil if none found. -func (m *AttributeContext_Resource) ValidateAll() error { - return m.validate(true) -} - -func (m *AttributeContext_Resource) validate(all bool) error { - if m == nil { - return nil - } - - var errors []error - - // no validation rules for Service - - // no validation rules for Name - - // no validation rules for Type - - // no validation rules for Labels - - if len(errors) > 0 { - return AttributeContext_ResourceMultiError(errors) - } - - return nil -} - -// AttributeContext_ResourceMultiError is an error wrapping multiple validation -// errors returned by AttributeContext_Resource.ValidateAll() if the -// designated constraints aren't met. -type AttributeContext_ResourceMultiError []error - -// Error returns a concatenation of all the error messages it wraps. -func (m AttributeContext_ResourceMultiError) Error() string { - var msgs []string - for _, err := range m { - msgs = append(msgs, err.Error()) - } - return strings.Join(msgs, "; ") -} - -// AllErrors returns a list of validation violation errors. -func (m AttributeContext_ResourceMultiError) AllErrors() []error { return m } - -// AttributeContext_ResourceValidationError is the validation error returned by -// AttributeContext_Resource.Validate if the designated constraints aren't met. -type AttributeContext_ResourceValidationError struct { - field string - reason string - cause error - key bool -} - -// Field function returns field value. -func (e AttributeContext_ResourceValidationError) Field() string { return e.field } - -// Reason function returns reason value. -func (e AttributeContext_ResourceValidationError) Reason() string { return e.reason } - -// Cause function returns cause value. -func (e AttributeContext_ResourceValidationError) Cause() error { return e.cause } - -// Key function returns key value. -func (e AttributeContext_ResourceValidationError) Key() bool { return e.key } - -// ErrorName returns error name. -func (e AttributeContext_ResourceValidationError) ErrorName() string { - return "AttributeContext_ResourceValidationError" -} - -// Error satisfies the builtin error interface -func (e AttributeContext_ResourceValidationError) Error() string { - cause := "" - if e.cause != nil { - cause = fmt.Sprintf(" | caused by: %v", e.cause) - } - - key := "" - if e.key { - key = "key for " - } - - return fmt.Sprintf( - "invalid %sAttributeContext_Resource.%s: %s%s", - key, - e.field, - e.reason, - cause) -} - -var _ error = AttributeContext_ResourceValidationError{} - -var _ interface { - Field() string - Reason() string - Key() bool - Cause() error - ErrorName() string -} = AttributeContext_ResourceValidationError{} - // Validate checks the field values on // ServiceAccountDelegationInfo_SystemPrincipal with the rules defined in the // proto definition for this message. If any rules are violated, the first @@ -1950,33 +1912,37 @@ func (m *ServiceAccountDelegationInfo_SystemPrincipal) validate(all bool) error var errors []error - if all { - switch v := interface{}(m.GetServiceMetadata()).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{ - field: "ServiceMetadata", - reason: "embedded message failed validation", - cause: err, - }) + if m.ServiceMetadata != nil { + + if all { + switch v := interface{}(m.GetServiceMetadata()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{ + field: "ServiceMetadata", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{ + field: "ServiceMetadata", + reason: "embedded message failed validation", + cause: err, + }) + } } - case interface{ Validate() error }: + } else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok { if err := v.Validate(); err != nil { - errors = append(errors, ServiceAccountDelegationInfo_SystemPrincipalValidationError{ + return ServiceAccountDelegationInfo_SystemPrincipalValidationError{ field: "ServiceMetadata", reason: "embedded message failed validation", cause: err, - }) - } - } - } else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return ServiceAccountDelegationInfo_SystemPrincipalValidationError{ - field: "ServiceMetadata", - reason: "embedded message failed validation", - cause: err, + } } } + } if len(errors) > 0 { @@ -2088,37 +2054,39 @@ func (m *ServiceAccountDelegationInfo_IdpPrincipal) validate(all bool) error { // no validation rules for PrincipalId - if all { - switch v := interface{}(m.GetServiceMetadata()).(type) { - case interface{ ValidateAll() error }: - if err := v.ValidateAll(); err != nil { - errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{ - field: "ServiceMetadata", - reason: "embedded message failed validation", - cause: err, - }) - } - case interface{ Validate() error }: - if err := v.Validate(); err != nil { - errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{ - field: "ServiceMetadata", - reason: "embedded message failed validation", - cause: err, - }) - } - } - } else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok { - if err := v.Validate(); err != nil { - return ServiceAccountDelegationInfo_IdpPrincipalValidationError{ - field: "ServiceMetadata", - reason: "embedded message failed validation", - cause: err, - } - } - } + // no validation rules for PrincipalEmail + + if m.ServiceMetadata != nil { + + if all { + switch v := interface{}(m.GetServiceMetadata()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{ + field: "ServiceMetadata", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, ServiceAccountDelegationInfo_IdpPrincipalValidationError{ + field: "ServiceMetadata", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetServiceMetadata()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ServiceAccountDelegationInfo_IdpPrincipalValidationError{ + field: "ServiceMetadata", + reason: "embedded message failed validation", + cause: err, + } + } + } - if m.PrincipalEmail != nil { - // no validation rules for PrincipalEmail } if len(errors) > 0 { diff --git a/gen/go/audit/v1/routable_event.pb.go b/gen/go/audit/v1/routable_event.pb.go index 1f5a65b..54c9c5f 100644 --- a/gen/go/audit/v1/routable_event.pb.go +++ b/gen/go/audit/v1/routable_event.pb.go @@ -380,50 +380,53 @@ var file_audit_v1_routable_event_proto_rawDesc = []byte{ 0x10, 0x01, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2f, 0x0a, 0x0d, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x0a, 0xba, 0x48, 0x07, 0xc8, 0x01, 0x01, 0x72, 0x02, 0x10, 0x01, 0x52, 0x0c, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x54, 0x79, 0x70, 0x65, 0x22, 0xcb, 0x03, 0x0a, 0x12, 0x52, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x54, 0x79, 0x70, 0x65, 0x22, 0xf4, 0x03, 0x0a, 0x12, 0x52, 0x6f, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x41, 0x75, 0x64, 0x69, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x12, 0x38, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x42, 0x19, 0xba, 0x48, 0x16, 0xc8, 0x01, 0x01, 0x72, 0x11, 0x32, 0x0f, - 0x5e, 0x5b, 0x41, 0x2d, 0x5a, 0x5d, 0x2b, 0x5f, 0x5b, 0x41, 0x2d, 0x5a, 0x5d, 0x2b, 0x24, 0x52, - 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x76, 0x69, - 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, - 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x42, 0x0b, 0xba, 0x48, 0x08, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x02, 0x10, - 0x01, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x37, 0x0a, - 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, - 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, - 0x72, 0x12, 0x46, 0x0a, 0x10, 0x75, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, - 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, - 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, - 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0f, 0x75, 0x6e, 0x65, 0x6e, 0x63, 0x72, - 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x40, 0x0a, 0x0e, 0x65, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, - 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0d, 0x65, 0x6e, - 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x42, 0x1b, 0x0a, 0x12, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, - 0x65, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x42, 0x0d, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, 0x2a, 0x57, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, - 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, - 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x49, 0x53, 0x49, - 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x02, - 0x42, 0x84, 0x01, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x73, 0x63, 0x68, 0x77, 0x61, 0x72, 0x7a, - 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x74, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, - 0x31, 0x42, 0x12, 0x52, 0x6f, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0f, 0x2e, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, - 0x3b, 0x61, 0x75, 0x64, 0x69, 0x74, 0x56, 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, - 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, - 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, - 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x41, 0x75, - 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x61, 0x0a, 0x0a, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x42, 0x42, 0xba, 0x48, 0x3f, 0xc8, 0x01, 0x01, 0x72, 0x3a, 0x32, 0x38, + 0x5e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, 0x74, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, + 0x39, 0x5d, 0x2b, 0x5c, 0x2e, 0x76, 0x5b, 0x31, 0x2d, 0x39, 0x5d, 0x5b, 0x30, 0x2d, 0x39, 0x5d, + 0x2a, 0x5c, 0x2e, 0x5b, 0x61, 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x5c, 0x2e, 0x5b, 0x61, + 0x2d, 0x7a, 0x30, 0x2d, 0x39, 0x5d, 0x2b, 0x24, 0x52, 0x09, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x41, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, + 0x76, 0x31, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x42, 0x0b, 0xba, + 0x48, 0x08, 0xc8, 0x01, 0x01, 0x82, 0x01, 0x02, 0x10, 0x01, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x37, 0x0a, 0x0b, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x61, 0x75, + 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x48, 0x00, 0x52, 0x0a, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x49, 0x0a, 0x11, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, + 0x66, 0x69, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x75, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x48, 0x00, 0x52, 0x10, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x12, 0x46, 0x0a, 0x10, 0x75, 0x6e, + 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, + 0x55, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x48, + 0x01, 0x52, 0x0f, 0x75, 0x6e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x40, 0x0a, 0x0e, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x5f, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x75, 0x64, + 0x69, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, 0x44, + 0x61, 0x74, 0x61, 0x48, 0x01, 0x52, 0x0d, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x65, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x42, 0x1b, 0x0a, 0x12, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, + 0x01, 0x42, 0x0d, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x05, 0xba, 0x48, 0x02, 0x08, 0x01, + 0x2a, 0x57, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x1a, + 0x0a, 0x16, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x55, 0x4e, 0x53, + 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x56, 0x49, + 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10, + 0x01, 0x12, 0x16, 0x0a, 0x12, 0x56, 0x49, 0x53, 0x49, 0x42, 0x49, 0x4c, 0x49, 0x54, 0x59, 0x5f, + 0x50, 0x52, 0x49, 0x56, 0x41, 0x54, 0x45, 0x10, 0x02, 0x42, 0x84, 0x01, 0x0a, 0x1c, 0x63, 0x6f, + 0x6d, 0x2e, 0x73, 0x63, 0x68, 0x77, 0x61, 0x72, 0x7a, 0x2e, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x69, + 0x74, 0x2e, 0x61, 0x75, 0x64, 0x69, 0x74, 0x2e, 0x76, 0x31, 0x42, 0x12, 0x52, 0x6f, 0x75, 0x74, + 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, + 0x5a, 0x0f, 0x2e, 0x2f, 0x61, 0x75, 0x64, 0x69, 0x74, 0x3b, 0x61, 0x75, 0x64, 0x69, 0x74, 0x56, + 0x31, 0xa2, 0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x2e, + 0x56, 0x31, 0xca, 0x02, 0x08, 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0xe2, 0x02, 0x14, + 0x41, 0x75, 0x64, 0x69, 0x74, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x09, 0x41, 0x75, 0x64, 0x69, 0x74, 0x3a, 0x3a, 0x56, 0x31, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/main.go b/main.go deleted file mode 100644 index f318f0a..0000000 --- a/main.go +++ /dev/null @@ -1,117 +0,0 @@ -package main - -import ( - "fmt" - - auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-core-platform/common-audit.git/gen/go/audit/v1" - - "github.com/bufbuild/protovalidate-go" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoreflect" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/types/known/structpb" -) - -func main() { - agent := "aaa" - parameters, _ := structpb.NewValue(map[string]any{ - "parameter": "b", - }) - body, _ := structpb.NewValue(map[string]any{ - "body": "b", - }) - auditEvent := auditV1.AuditEvent{ - EventName: "XXX", - EventTrigger: auditV1.EventTrigger_EVENT_TRIGGER_REQUEST, - Request: &auditV1.RequestDetails{ - Endpoint: "XXX", - SourceIpAddress: "127.0.0.1", - UserAgent: &agent, - Parameters: parameters.GetStructValue(), - Body: body.GetStructValue(), - Headers: []*auditV1.RequestHeader{ - { - Key: "abc", - Value: "def", - }, - }, - }, - EventTimeStamp: nil, - Initiator: nil, - Principals: nil, - ResourceId: nil, - ResourceName: nil, - CorrelationId: nil, - Details: nil, - } - - auditEventBytes, err := proto.Marshal(&auditEvent) - if err != nil { - fmt.Println(err.Error()) - return - } - payload := auditV1.UnencryptedData{ - Data: auditEventBytes, - ProtobufType: fmt.Sprintf("%v", auditEvent.ProtoReflect().Descriptor().FullName()), - } - - //var version int32 = 0 - routableEvent := auditV1.RoutableAuditEvent{ - EventName: "A_V1", - Visibility: auditV1.Visibility_VISIBILITY_PRIVATE, - ResourceReference: &auditV1.RoutableAuditEvent_ObjectName{ObjectName: auditV1.ObjectName_OBJECT_NAME_SYSTEM}, - Data: &auditV1.RoutableAuditEvent_UnencryptedData{UnencryptedData: &payload}, - } - - validator, err := protovalidate.New() - if err != nil { - fmt.Println("failed to initialize validator:", err) - } - err = validator.Validate(&auditEvent) - if err != nil { - fmt.Println(err.Error()) - } - - err = validator.Validate(&routableEvent) - if err != nil { - fmt.Println(err.Error()) - } - - routableEventBytes, err := proto.Marshal(&routableEvent) - if err != nil { - fmt.Println(err.Error()) - return - } - - var deserializedRoutableEvent auditV1.RoutableAuditEvent - err = proto.Unmarshal(routableEventBytes, &deserializedRoutableEvent) - if err != nil { - fmt.Println(err.Error()) - return - } - if proto.Equal(&routableEvent, &deserializedRoutableEvent) { - fmt.Println("Event Matched") - } else { - fmt.Println("Event Not Matched") - } - //fmt.Println(deserializedRoutableEvent.String()) - - protoMessage := getProto(deserializedRoutableEvent.GetUnencryptedData().ProtobufType) - err = proto.Unmarshal(deserializedRoutableEvent.GetUnencryptedData().Data, protoMessage) - if err != nil { - fmt.Println(err.Error()) - return - } - deserializedAuditEvent, isAuditEvent := protoMessage.(*auditV1.AuditEvent) - if isAuditEvent { - fmt.Println(deserializedAuditEvent.String()) - } - - fmt.Println(string(auditEventBytes)) -} - -func getProto(dataType string) protoreflect.ProtoMessage { - t, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(dataType)) - m := t.New().Interface() - return m -} diff --git a/proto/audit/v1/audit_event.proto b/proto/audit/v1/audit_event.proto index ba46246..67ec80b 100644 --- a/proto/audit/v1/audit_event.proto +++ b/proto/audit/v1/audit_event.proto @@ -4,6 +4,7 @@ import "buf/validate/validate.proto"; import "google/protobuf/any.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/timestamp.proto"; +import "google/protobuf/wrappers.proto"; import "audit/v1/common.proto"; @@ -13,66 +14,123 @@ option go_package = "./audit;auditV1"; option java_multiple_files = true; option java_package = "com.schwarz.stackit.audit.v1"; -// TODO update numbers of elements in messages -// TODO decide which fields should be optional +// TODO max attribute length +// TODO check regex patterns +// TODO check if gRPC, messaging ans scheduled triggered events work with the schema // The audit log entry can be used to record an incident in the audit log. message AuditLogEntry { // The resource name of the log to which this log entry belongs. - // Example: projects//logs/ - string log_name = 12; + // + // Format: //logs/ + // Where: + // Event-Types: admin-activity, system-event, policy-denied, data-access + // + // Examples: + // "projects/00b0f972-59ff-48f2-a4f9-29c57b75c2fa/logs/admin-activity" + // + // Required: true + string log_name = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+/logs/(?:admin-activity|system-event|policy-denied|data-access)$" + ]; // The log entry payload, which is always an AuditLog for STACKIT Audit Log events. - AuditLog proto_payload = 2; + // + // Required: true + AuditLog proto_payload = 2 [ + (buf.validate.field).required = true + ]; - // TODO can we specify how the format should look like? - // TODO Encode sequence number into it? - // https://softwaremind.com/blog/the-unique-features-of-snowflake-id-and-its-comparison-to-uuid/ // A unique identifier for the log entry. - // Is generated and set by the SDK. - // Format: - // /// - string insert_id = 4; + // Is used to check completeness of audit events over time. + // + // Format: /// + // Where: + // Unix-Timestamp: A UTC unix timestamp in seconds is expected + // Region-Zone: The region and (optional) zone id. If both, separated with a - (dash) + // Worker-Id: The ID of the K8s Pod, Service-Instance, etc (must be unique for a sending service) + // Sequence-Number: Increasing number, representing the message offset per Worker-Id + // If the Worker-Id changes, the sequence-number has to be reset to 0. + // + // Examples: + // "1721899117/eu01/319a7fb9-edd2-46c6-953a-a724bb377c61/8792726390909855142" + // + // Required: true + string insert_id = 3[ + (buf.validate.field).required = true, + // TODO how do worker ids look like? + (buf.validate.field).string.pattern = "^[0-9]+/[a-z0-9]+/[a-z0-9-]+/[0-9]+$" + ]; // A set of user-defined (key, value) data that provides additional // information about the log entry. - map labels = 11; + // + // Required: true + map labels = 4 [ + (buf.validate.field).required = true + ]; // Correlate multiple audit logs by setting the same id - string correlation_id = 15; + // + // Required: false + optional string correlation_id = 5 [ + (buf.validate.field).string.min_len = 1 + ]; // The time the event described by the log entry occurred. - google.protobuf.Timestamp timestamp = 9; + // + // Required: true + google.protobuf.Timestamp timestamp = 6 [ + (buf.validate.field).required = true, + (buf.validate.field).timestamp.lt_now = true + ]; // The severity of the log entry. - LogSeverity severity = 10; + // + // Required: true + LogSeverity severity = 7 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; - // W3C conform trace parent header: + // Customer set W3C conform trace parent header: // https://www.w3.org/TR/trace-context/#traceparent-header // - // Example: - // `00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01` - string trace_parent = 22; + // Format: --- + // + // Examples: + // "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" + // + // Required: false + optional string trace_parent = 8 [ + (buf.validate.field).string.pattern = "^[0-9]+-[a-z0-9]+-[a-z0-9]+-[0-9]+$" + ]; - // W3C conform trace state header: + // Customer set W3C conform trace state header: // https://www.w3.org/TR/trace-context/#tracestate-header // - // Example: - // `rojo=00f067aa0ba902b7,congo=t61rcWkgMzE`. - string trace_state = 27; + // Format: =[,=] + // + // Examples: + // "rojo=00f067aa0ba902b7,congo=t61rcWkgMzE" + // + // Required: false + optional string trace_state = 9 [ + (buf.validate.field).string.pattern = "[a-zA-Z0-9]+=[a-zA-Z0-9]+(?:,[a-zA-Z0-9]+=[a-zA-Z0-9]+)*" + ]; } // The severity of the event described in a log entry, expressed as one of the -// standard severity levels listed below. For your reference, the levels are -// assigned the listed numeric values. The effect of using numeric values other -// than those listed is undefined. -// Copied from -// https://github.com/googleapis/googleapis/blob/master/google/logging/type/log_severity.proto +// standard severity levels listed below. enum LogSeverity { - // (0) The log entry has no assigned severity level. - DEFAULT = 0; + UNSPECIFIED = 0; + + // (1) The log entry has no assigned severity level. + // TODO check index + DEFAULT = 1; // (100) Debug or trace information. DEBUG = 100; @@ -103,87 +161,156 @@ enum LogSeverity { // Common audit log format for STACKIT API operations. message AuditLog { - // The name of the API service performing the operation. For example, - // `"resource-manager"`. - string service_name = 7; + // The name of the API service performing the operation. + // + // Examples: + // "resource-manager" + // + // Required: true + string service_name = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; - // TODO: Add extra field to open api spec for the method_name + // TODO rename into operation? // The name of the service method or operation. - // The format should is: - // stackit.... // - // For example, + // Format: stackit.... // - // "stackit.resourcemanager.v1.organization.created" - // "stackit.authorization.v2.organization.moved" - // "stackit.authorization.v2.folder.moved" - optional string method_name = 8; + // Examples: + // "stackit.resourcemanager.v1.organization.created" + // "stackit.authorization.v2.organization.moved" + // "stackit.authorization.v2.folder.moved" + // + // Required: true + string method_name = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).string.pattern = "^stackit\\.[a-z0-9]+\\.v[1-9][0-9]*\\.[a-z0-9]+\\.[a-z0-9]+$" + ]; // The resource or collection that is the target of the operation. // The name is a scheme-less URI, not including the API service name. - // For example: // - // "projects//zones//vms/" - // "projects//zones//vms//ports/" - // "projects//zones//instances/instance-20240723-184227 - string resource_name = 11; + // Format: /[/locations/][/
] + // Where: + // Region-Zone: Optional region and zone id. If both, separated with a - (dash). Alternatively _ (underscore). + // Details: Optional "/" pairs + // + // Examples: + // "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/instances/instance-20240723-174217" + // "projects/dd7d1807-54e9-4426-8994-721758b5b554/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8" + // + // Required: true + string resource_name = 3[ + (buf.validate.field).required = true, + (buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+(?:/locations/(?:(?:[a-z0-9]+(?:-[a-z0-9]+)?)|_))?(?:/[a-z0-9]+/[a-z0-9-]+)*$" + ]; // Authentication information. - AuthenticationInfo authentication_info = 3; + // + // Required: true + AuthenticationInfo authentication_info = 4 [ + (buf.validate.field).required = true + ]; - // Authorization information. If there are multiple - // resources or permissions involved, then there is + // Authorization information. If there are multiple resources or permissions involved, then there is // one AuthorizationInfo element for each {resource, permission} tuple. - repeated AuthorizationInfo authorization_info = 9; + // + // Required: false + repeated AuthorizationInfo authorization_info = 5; // Metadata about the operation. - RequestMetadata request_metadata = 4; + // + // Required: true + RequestMetadata request_metadata = 6 [ + (buf.validate.field).required = true + ]; // The operation request. This may not include all request parameters, // such as those that are too large, privacy-sensitive, or duplicated // elsewhere in the log record. // It should never include user-generated data, such as file contents. - google.protobuf.Struct request = 16; + // + // Required: true + google.protobuf.Struct request = 7 [ + (buf.validate.field).required = true + ]; // The status of the overall operation. - ResponseStatus status = 2; + // + // Required: true + ResponseStatus status = 8 [ + (buf.validate.field).required = true + ]; // The number of items returned from a List or Query API method, // if applicable. - optional int64 num_response_items = 12; + // + // Required: false + optional google.protobuf.Int64Value num_response_items = 9 [ + (buf.validate.field).int64.gte = 0 + ]; // The operation response. This may not include all response elements, // such as those that are too large, privacy-sensitive, or duplicated // elsewhere in the log record. - google.protobuf.Struct response = 17; + // + // Required: true + google.protobuf.Struct response = 10 [ + (buf.validate.field).required = true + ]; // Other service-specific data about the request, response, and other // information associated with the current audited event. - google.protobuf.Struct metadata = 18; + // + // Required: false + optional google.protobuf.Struct metadata = 11; } // Authentication information for the operation. message AuthenticationInfo { - // Principal id - string principal_id = 1; + // STACKIT principal id + // + // Required: true + string principal_id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; - // The email address of the authenticated user - string principal_email = 2; + // The email address of the authenticated user. + // Service accounts have email addresses that can be used. + // + // Required: true + string principal_email = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1, + (buf.validate.field).string.max_len = 255 + ]; // The name of the service account used to create or exchange // credentials for authenticating the service account making the request. - // Example: // - // "projects/{PROJECT_ID}/serviceAccounts/{ACCOUNT}" - optional string service_account_name = 5; + // Format: projects//serviceAccounts/ + // + // Examples: + // "projects/29b2c56f-f712-4a9c-845b-f0907158e53c/serviceAccounts/a606dc68-8b97-421b-89a9-116bcbd004df" + // + // Required: false + optional string service_account_name = 3 [ + (buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+/serviceAccounts/[a-zA-Z0-9-]+$" + ]; // Identity delegation history of an authenticated service account that makes // the request. It contains information on the real authorities that try to // access STACKIT resources by delegating on a service account. When multiple // authorities present, they are guaranteed to be sorted based on the original // ordering of the identity delegation events. - repeated ServiceAccountDelegationInfo service_account_delegation_info = 6; + // + // Required: false + repeated ServiceAccountDelegationInfo service_account_delegation_info = 4; } // Authorization information for the operation. @@ -191,37 +318,44 @@ message AuthorizationInfo { // The resource being accessed, as a REST-style string. // - // For example: - // Project scoped resource: projects/test-project-123/zones/us-central1-b/instances/instance-20240723-174217 - // Global Resource: projects/_/buckets/adfeaf - string resource = 1; + // Format: /[/locations/][/
] + // Where: + // Region-Zone: Optional region and zone id. If both, separated with a - (dash). Alternatively _ (underscore). + // Details: Optional "/" pairs + // + // Examples: + // "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/instances/instance-20240723-174217" + // "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8" + // + // Required: true + string resource = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+(?:/locations/(?:(?:[a-z0-9]+(?:-[a-z0-9]+)?)|_))?(?:/[a-z0-9]+/[a-z0-9-]+)*$" + ]; // The required IAM permission. - string permission = 2; + // + // Examples: + // "resourcemanager.project.edit" + // + // Required: false + optional string permission = 2 [ + (buf.validate.field).string.pattern = "^[a-z-]+(?:\\.[a-z-]+)*\\.[a-z-]+$" + ]; // Whether or not authorization for `resource` and `permission` // was granted. - bool granted = 3; + // + // Required: false + optional bool granted = 3; } -// TODO check description // This message defines the standard attribute vocabulary for STACKIT APIs. // // An attribute is a piece of metadata that describes an activity on a network -// service. For example, the size of an HTTP request, or the status code of -// an HTTP response. -// -// Each attribute has a type and a name, which is logically defined as -// a proto message field in `AttributeContext`. The field type becomes the -// attribute type, and the field path becomes the attribute name. For example, -// the attribute `source.ip` maps to field `AttributeContext.source.ip`. -// -// This message definition is guaranteed not to have any wire breaking change. -// So you can use it directly for passing attributes across different systems. -// -// NOTE: Different system may generate different subset of attributes. Please -// verify the system specification before relying on an attribute generated -// a system. +// service. message AttributeContext { // This message defines request authentication attributes. Terminology is @@ -229,55 +363,57 @@ message AttributeContext { // correlate to concepts in other standards. message Auth { - // TODO check description - // The authenticated principal. Reflects the issuer (`iss`) and subject - // (`sub`) claims within a JWT. The issuer and subject should be `/` - // delimited, with `/` percent-encoded within the subject fragment. For - // Google accounts, the principal format is: - // "https://accounts.google.com/{id}" - string principal = 1; + // The authenticated principal. Reflects the issuer ("iss") and subject + // ("sub") claims within a JWT. + // + // Format: / + // Where: + // Sub-Claim: Sub-Claim from JWT with `/` percent-encoded (url-encoded) + // + // Examples: + // "https%3A%2F%2Faccounts.dev.stackit.cloud/stackit-resource-manager-dev" + // + // Required: true + string principal = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.pattern = "^[a-zA-Z0-9-%.]+/[a-zA-Z0-9-%.]+$" + ]; - // TODO check description // The intended audience(s) for this authentication information. Reflects - // the audience (`aud`) claim within a JWT. The audience - // value(s) depends on the `issuer`, but typically include one or more of - // the following pieces of information: + // the audience ("aud") claim within a JWT, typically the services intended + // to receive the credential. // - // * The services intended to receive the credential such as - // ["pubsub.googleapis.com", "storage.googleapis.com"] - // * A set of service-based scopes. For example, - // ["https://www.googleapis.com/auth/cloud-platform"] - // * The client id of an app, such as the Firebase project id for JWTs - // from Firebase Auth. + // Examples: + // ["https://stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", "stackit", "api"] // - // Consult the documentation for the credential issuer to determine the - // information provided. + // Required: false repeated string audiences = 2; - // TODO check description - // The authorized presenter of the credential. Reflects the optional - // Authorized Presenter (`azp`) claim within a JWT or the - // OAuth client id. For example, a Google Cloud Platform client id looks - // as follows: "123456789012.apps.googleusercontent.com". - string presenter = 3; - - // TODO check description // Structured claims presented with the credential. JWTs include - // `{key: value}` pairs for standard and private claims. The following - // is a subset of the standard required and optional claims that would - // typically be presented for a Google-based JWT: + // {"key": } pairs for standard and private claims. // - // {'iss': 'accounts.google.com', - // 'sub': '113289723416554971153', - // 'aud': ['123456789012', 'pubsub.googleapis.com'], - // 'azp': '123456789012.apps.googleusercontent.com', - // 'email': 'jsmith@example.com', - // 'iat': 1353601026, - // 'exp': 1353604926} + // The following is a subset of the standard required and optional claims that would + // typically be presented for a STACKIT JWT: // - // SAML assertions are similarly specified, but with an identity provider - // dependent structure. - google.protobuf.Struct claims = 4; + // { + // "aud": "https://stackit-resource-manager-dev.apps.01.cf.eu01.stackit.cloud", + // "email": "max@mail.schwarz", + // "exp": 1721905449, + // "iat": 1721901849, + // "iss": "https://api.dev.stackit.cloud", + // "jti": "45a196e0-480f-4c34-a592-dc5db81c8c3a", + // "nbf": 1721900462, + // "roles": null, + // "sub": "cd94f01a-df2e-4456-902f-48f5e57f0b63", + // "user_id": "", + // "x_client_id": "", + // "zid": "" + // } + // + // Required: true + google.protobuf.Struct claims = 3 [ + (buf.validate.field).required = true + ]; } // This message defines attributes for an HTTP request. If the actual @@ -288,62 +424,126 @@ message AttributeContext { // The unique ID for a request, which can be propagated to downstream // systems. The ID should have low probability of collision // within a single day for a specific service. - string id = 1; + // + // More information can be found here: https://google.aip.dev/155 + // + // Format: + // Where: + // Idempotency-key: Typically consists of a id + version + // + // Examples: + // 5e3952a9-b628-4be6-ac61-b1c6eb4a110c/5 + // + // Required: false + optional string id = 1; // The HTTP request method, such as `GET`, `POST`. - string method = 2; + // + // Required: true + // TODO does it make sense to define an enum? + string method = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; // The HTTP request headers. If multiple headers share the same key, they // must be merged according to the HTTP spec. All header keys must be // lowercased, because HTTP header keys are case-insensitive. - map headers = 3; + // + // Required: true + map headers = 3 [ + (buf.validate.field).required = true + ]; // The HTTP URL path. - string path = 4; + // + // Required: true + string path = 4 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; // The HTTP request `Host` header value. - string host = 5; + // + // Required: true + string host = 5 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; // The HTTP URL scheme, such as `http` and `https`. - string scheme = 6; + // + // Required: true + string scheme = 6 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; - // The HTTP URL query in the format of `name1=value1&name2=value2`, as it + // The HTTP URL query in the format of "name1=value1&name2=value2", as it // appears in the first line of the HTTP request. No decoding is performed. - string query = 7; + // + // Required: false + optional string query = 7 [ + (buf.validate.field).string.pattern = "^[a-zA-Z0-9]+=[a-zA-Z0-9]+(?:&[a-zA-Z0-9]+=[a-zA-Z0-9]+)*$" + ]; // The timestamp when the `destination` service receives the first byte of // the request. - google.protobuf.Timestamp time = 9; + // + // Required: true + google.protobuf.Timestamp time = 8 [ + (buf.validate.field).required = true, + (buf.validate.field).timestamp.lt_now = true + ]; // The network protocol used with the request, such as "http/1.1", // "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See // https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids // for details. - string protocol = 11; + // + // Required: true + string protocol = 9 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; - // The request authentication. May be absent for unauthenticated requests. - // Derived from the HTTP request `Authorization` header or equivalent. - Auth auth = 13; + // The request authentication. + // + // Required: true + Auth auth = 10 [ + (buf.validate.field).required = true + ]; } // This message defines attributes for a typical network response. It // generally models semantics of an HTTP response. + // TODO do we need another status code attribute in the Response? message Response { - // The HTTP response status code, such as `200` and `404`. - int64 code = 1; - - // The HTTP response size in bytes. If unknown, it must be -1. - int64 size = 2; + // The HTTP response size in bytes. + // + // Required: false + optional google.protobuf.Int64Value size = 1 [ + (buf.validate.field).int64.gte = 0 + ]; // The HTTP response headers. If multiple headers share the same key, they // must be merged according to HTTP spec. All header keys must be // lowercased, because HTTP header keys are case-insensitive. - map headers = 3; + // + // Required: true + map headers = 2 [ + (buf.validate.field).required = true + ]; - // The timestamp when the `destination` service generates the first byte of + // The timestamp when the "destination" service generates the first byte of // the response. - google.protobuf.Timestamp time = 4; + // + // Required: true + google.protobuf.Timestamp time = 3 [ + (buf.validate.field).required = true, + (buf.validate.field).timestamp.lt_now = true + ]; } } @@ -352,33 +552,34 @@ message RequestMetadata { // The IP address of the caller. // For caller from internet, this will be public IPv4 or IPv6 address. - // For caller from a VM / K8s Service / etc, this - // will be the SIT proxy's IPv4 address. - string caller_ip = 1; + // For caller from a VM / K8s Service / etc, this will be the SIT proxy's IPv4 address. + // + // Required: true + string caller_ip = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.ip = true + ]; - // TODO check description // The user agent of the caller. - // This information is not authenticated and should be treated accordingly. - // For example: // - // + `google-api-python-client/1.4.0`: - // The request was made by the Google API client for Python. - // + `Cloud SDK Command Line Tool apitools-client/1.0 gcloud/0.9.62`: - // The request was made by the Google Cloud SDK CLI (gcloud). - // + `AppEngine-Google; (+http://code.google.com/appengine; appid: - // s~my-project`: - // The request was made from the `my-project` App Engine app. - string caller_supplied_user_agent = 2; + // Examples: + // "OpenAPI-Generator/1.0.0/go" + // -> The request was made by the STACKIT SDK GO client or STACKIT CLI + // "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" + // -> The request was made by a web browser. + // + // Required: true + string caller_supplied_user_agent = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; - // TODO check description - // Request attributes used in IAM condition evaluation. This field contains - // request attributes like request time and access levels associated with - // the request. + // This field contains request attributes like request url, time, etc. // - // To get the whole view of the attributes used in IAM - // condition evaluation, the user must also look into - // `AuditLog.authentication_info.resource_attributes`. - AttributeContext.Request request_attributes = 7; + // Required: true + AttributeContext.Request request_attributes = 3 [ + (buf.validate.field).required = true + ]; } // The `Status` type defines a logical error model that is suitable for @@ -388,12 +589,25 @@ message RequestMetadata { message ResponseStatus { // The http or gRPC status code. - int32 code = 1; + // + // Examples: + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + // https://grpc.github.io/grpc/core/md_doc_statuscodes.html + // + // Required: true + google.protobuf.Int32Value code = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).int32.gte = 0 + ]; // Short description of the error - string message = 2; + // + // Required: false + optional string message = 2; // Error details + // + // Required: false repeated google.protobuf.Struct details = 3; } @@ -404,25 +618,42 @@ message ServiceAccountDelegationInfo { message SystemPrincipal { // Metadata about the service that uses the service account. - google.protobuf.Struct service_metadata = 3; + // + // Required: false + optional google.protobuf.Struct service_metadata = 1; } // STACKIT idp principal. message IdpPrincipal { // STACKIT principal id - string principal_id = 1; + // + // Required: true + string principal_id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1 + ]; - // Optional email address - optional string principal_email = 2; + // The email address of the authenticated user. + // Service accounts have email addresses that can be used. + // + // Required: true + string principal_email = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).string.min_len = 1, + (buf.validate.field).string.max_len = 255 + ]; // Metadata about the service that uses the service account. - google.protobuf.Struct service_metadata = 3; + // + // Required: false + optional google.protobuf.Struct service_metadata = 3; } // Entity that creates credentials for service account and assumes its // identity for authentication. oneof Authority { + option (buf.validate.oneof).required = true; // System identity SystemPrincipal system_principal = 1; diff --git a/proto/audit/v1/routable_event.proto b/proto/audit/v1/routable_event.proto index 5f44180..eaf00b1 100644 --- a/proto/audit/v1/routable_event.proto +++ b/proto/audit/v1/routable_event.proto @@ -44,7 +44,10 @@ message RoutableAuditEvent { // Functional event name with pattern _, e.g. ORGANIZATION_CREATED // Will be copied over by the SDK from the AuditEvent - string event_name = 1 [(buf.validate.field).required = true, (buf.validate.field).string.pattern = "^[A-Z]+_[A-Z]+$"]; + string event_name = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.pattern = "^stackit\\.[a-z0-9]+\\.v[1-9][0-9]*\\.[a-z0-9]+\\.[a-z0-9]+$" + ]; // Visibility relevant for differentiating between internal and public events Visibility visibility = 2 [(buf.validate.field).required = true, (buf.validate.field).enum.defined_only = true];