audit-go/pkg/audit/api/builder.go
Christian Schaible (EXT) cdea0ac81a Merged PR 801769: feat: Make the request body accessible and modifiable in the audit event builder
Makes the request body accessible and modifiable in the audit event builder to enable SDK users to hide secrets in request bodies captured in the request body (by middlewares). Also updates dependencies.

Security-concept-update-needed: false.

JIRA Work Item: STACKITALO-284
2025-06-30 06:34:51 +00:00

683 lines
24 KiB
Go

package api
import (
"context"
"errors"
"fmt"
"time"
"github.com/google/uuid"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
auditV1 "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/gen/go/audit/v1"
internalAuditApi "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/internal/audit/api"
pkgAuditCommon "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/pkg/audit/common"
pkgAuditUtils "dev.azure.com/schwarzit/schwarzit.stackit-public/audit-go.git/pkg/audit/utils"
)
const quadZero = "0.0.0.0"
type SequenceNumber uint64
type AuditParameters struct {
// A map that is added as "details" to the message
Details map[string]interface{}
// The type of the event
EventType pkgAuditCommon.EventType
// A set of user-defined (key, value) data that provides additional
// information about the log entry.
Labels map[string]string
// UUID identifier of the object, the audit event refers to
ObjectId string
// Type of the object, the audit event refers to
ObjectType pkgAuditCommon.ObjectType
ResponseBody any
// Log severity
Severity auditV1.LogSeverity
}
func getObjectIdAndTypeFromAuditParams(
auditParams *AuditParameters,
) (string, *pkgAuditCommon.ObjectType, error) {
objectId := auditParams.ObjectId
if objectId == "" {
return "", nil, errors.New("object id missing")
}
var objectType *pkgAuditCommon.ObjectType
if auditParams.ObjectType != "" {
objectType = &auditParams.ObjectType
}
if objectType == nil {
return "", nil, errors.New("object type missing")
}
if err := objectType.IsSupportedType(); err != nil {
return "", nil, err
}
return objectId, objectType, nil
}
// AuditLogEntryBuilder collects audit params to construct auditV1.AuditLogEntry
type AuditLogEntryBuilder struct {
auditParams AuditParameters
auditRequest internalAuditApi.AuditRequest
auditResponse internalAuditApi.AuditResponse
auditMetadata internalAuditApi.AuditMetadata
// Region and optional zone id. If both, separated with a - (dash).
// Example: eu01
location string
// Opentelemetry tracer
tracer trace.Tracer
// The ID of the K8s Pod, Service-Instance, etc. (must be unique for a sending service)
workerId string
}
// NewAuditLogEntryBuilder returns a builder to construct auditV1.AuditLogEntry
func NewAuditLogEntryBuilder() *AuditLogEntryBuilder {
requestTime := time.Now().UTC()
return &AuditLogEntryBuilder{
auditParams: AuditParameters{
EventType: pkgAuditCommon.EventTypeAdminActivity,
},
auditRequest: internalAuditApi.AuditRequest{
Request: &pkgAuditCommon.ApiRequest{},
RequestClientIP: quadZero,
RequestCorrelationId: nil,
RequestId: nil,
RequestTime: &requestTime,
},
auditResponse: internalAuditApi.AuditResponse{
ResponseBodyBytes: nil,
ResponseStatusCode: 200,
ResponseHeaders: make(map[string][]string),
ResponseNumItems: nil,
ResponseTime: nil,
},
auditMetadata: internalAuditApi.AuditMetadata{
AuditInsertId: "",
AuditLabels: nil,
AuditLogName: "",
AuditLogSeverity: auditV1.LogSeverity_LOG_SEVERITY_DEFAULT,
AuditOperationName: "",
AuditPermission: nil,
AuditPermissionGranted: nil,
AuditResourceName: "",
AuditServiceName: "",
AuditTime: nil,
},
location: "",
tracer: otel.Tracer("audit-log-entry-builder"),
workerId: "",
}
}
func (builder *AuditLogEntryBuilder) AsSystemEvent() *AuditLogEntryBuilder {
if builder.auditRequest.Request == nil {
builder.auditRequest.Request = &pkgAuditCommon.ApiRequest{}
}
if builder.auditRequest.Request.Header == nil {
builder.auditRequest.Request.Header = map[string][]string{"user-agent": {"none"}}
}
if builder.auditRequest.Request.Host == "" {
builder.auditRequest.Request.Host = quadZero
}
if builder.auditRequest.Request.Method == "" {
builder.auditRequest.Request.Method = "OTHER"
}
if builder.auditRequest.Request.Scheme == "" {
builder.auditRequest.Request.Scheme = "none"
}
if builder.auditRequest.Request.Proto == "" {
builder.auditRequest.Request.Proto = "none"
}
if builder.auditRequest.Request.URL.Path == "" {
builder.auditRequest.Request.URL.Path = "none"
}
if builder.auditRequest.RequestClientIP == "" {
builder.auditRequest.RequestClientIP = quadZero
}
builder.WithEventType(pkgAuditCommon.EventTypeSystemEvent)
return builder
}
// WithRequiredApiRequest adds api request details
func (builder *AuditLogEntryBuilder) WithRequiredApiRequest(request pkgAuditCommon.ApiRequest) *AuditLogEntryBuilder {
builder.auditRequest.Request = &request
return builder
}
// GetApiRequest returns the api request details
func (builder *AuditLogEntryBuilder) GetApiRequest() *pkgAuditCommon.ApiRequest {
return builder.auditRequest.Request
}
func (builder *AuditLogEntryBuilder) GetApiRequestBody() *pkgAuditCommon.ApiRequest {
return builder.auditRequest.Request
}
// WithRequiredLocation adds the region and optional zone id. If both, separated with a - (dash).
// Example: eu01
func (builder *AuditLogEntryBuilder) WithRequiredLocation(location string) *AuditLogEntryBuilder {
builder.location = location
return builder
}
// WithRequiredRequestClientIp adds the client ip
func (builder *AuditLogEntryBuilder) WithRequiredRequestClientIp(requestClientIp string) *AuditLogEntryBuilder {
builder.auditRequest.RequestClientIP = requestClientIp
return builder
}
// WithRequestCorrelationId adds an optional request correlation id
func (builder *AuditLogEntryBuilder) WithRequestCorrelationId(requestCorrelationId string) *AuditLogEntryBuilder {
builder.auditRequest.RequestCorrelationId = &requestCorrelationId
return builder
}
// WithRequestId adds an optional request id
func (builder *AuditLogEntryBuilder) WithRequestId(requestId string) *AuditLogEntryBuilder {
builder.auditRequest.RequestId = &requestId
return builder
}
// WithRequestTime sets the request time on the builder. If not set - the instantiation time of the builder is used.
func (builder *AuditLogEntryBuilder) WithRequestTime(requestTime time.Time) *AuditLogEntryBuilder {
builder.auditRequest.RequestTime = &requestTime
return builder
}
// WithRequiredServiceName adds the service name in lowercase (allowed characters are [a-z-]).
func (builder *AuditLogEntryBuilder) WithRequiredServiceName(serviceName string) *AuditLogEntryBuilder {
builder.auditMetadata.AuditServiceName = serviceName
return builder
}
// WithRequiredWorkerId adds the ID of the K8s Pod, Service-Instance, etc. (must be unique for a sending service)
func (builder *AuditLogEntryBuilder) WithRequiredWorkerId(workerId string) *AuditLogEntryBuilder {
builder.workerId = workerId
return builder
}
// WithRequiredObjectId adds the object identifier.
// May be prefilled by audit middleware (if the identifier can be extracted from the url path).
func (builder *AuditLogEntryBuilder) WithRequiredObjectId(objectId string) *AuditLogEntryBuilder {
builder.auditParams.ObjectId = objectId
return builder
}
// WithRequiredObjectType adds the object type.
// May be prefilled by audit middleware (if the type can be extracted from the url path).
func (builder *AuditLogEntryBuilder) WithRequiredObjectType(objectType pkgAuditCommon.ObjectType) *AuditLogEntryBuilder {
builder.auditParams.ObjectType = objectType
return builder
}
// WithRequiredOperation adds the name of the service method or operation.
//
// Format: stackit.<product>.<version>.<type-chain>.<operation>
// Where:
//
// Product: The name of the service in lowercase
// Version: Optional API version
// Type-Chain: Chained path to object
// Operation: The name of the operation in lowercase
//
// Examples:
//
// "stackit.resource-manager.v1.organizations.create"
// "stackit.authorization.v1.projects.volumes.create"
// "stackit.authorization.v2alpha.projects.volumes.create"
// "stackit.authorization.v2.folders.move"
// "stackit.resource-manager.health"
func (builder *AuditLogEntryBuilder) WithRequiredOperation(operation string) *AuditLogEntryBuilder {
builder.auditMetadata.AuditOperationName = operation
return builder
}
// WithAuditPermission adds the IAM permission
//
// Examples:
//
// "resourcemanager.project.edit"
func (builder *AuditLogEntryBuilder) WithAuditPermission(permission string) *AuditLogEntryBuilder {
builder.auditMetadata.AuditPermission = &permission
return builder
}
// WithAuditPermissionCheckResult adds the IAM permission check result
func (builder *AuditLogEntryBuilder) WithAuditPermissionCheckResult(permissionCheckResult bool) *AuditLogEntryBuilder {
builder.auditMetadata.AuditPermissionGranted = &permissionCheckResult
return builder
}
// WithLabels adds A set of user-defined (key, value) data that provides additional
// information about the log entry.
func (builder *AuditLogEntryBuilder) WithLabels(labels map[string]string) *AuditLogEntryBuilder {
builder.auditMetadata.AuditLabels = &labels
return builder
}
// WithNumResponseItems adds the number of items returned to the client if applicable.
func (builder *AuditLogEntryBuilder) WithNumResponseItems(numResponseItems int64) *AuditLogEntryBuilder {
builder.auditResponse.ResponseNumItems = &numResponseItems
return builder
}
// WithEventType overwrites the default event type EventTypeAdminActivity
func (builder *AuditLogEntryBuilder) WithEventType(eventType pkgAuditCommon.EventType) *AuditLogEntryBuilder {
builder.auditParams.EventType = eventType
return builder
}
// WithDetails adds an optional details object to the audit log entry
func (builder *AuditLogEntryBuilder) WithDetails(details map[string]interface{}) *AuditLogEntryBuilder {
builder.auditParams.Details = details
return builder
}
// WithSeverity overwrites the default log severity level auditV1.LogSeverity_LOG_SEVERITY_DEFAULT
func (builder *AuditLogEntryBuilder) WithSeverity(severity auditV1.LogSeverity) *AuditLogEntryBuilder {
builder.auditMetadata.AuditLogSeverity = severity
return builder
}
// WithStatusCode adds the (http) response status code
func (builder *AuditLogEntryBuilder) WithStatusCode(statusCode int) *AuditLogEntryBuilder {
builder.auditResponse.ResponseStatusCode = statusCode
return builder
}
// WithResponseBody adds the response body to the builder and transforms it in the Build method (json serializable or protobuf message expected)
func (builder *AuditLogEntryBuilder) WithResponseBody(responseBody any) *AuditLogEntryBuilder {
builder.auditParams.ResponseBody = responseBody
return builder
}
// WithResponseBodyBytes adds the response body as bytes (serialized json or protobuf message expected)
func (builder *AuditLogEntryBuilder) WithResponseBodyBytes(responseBody []byte) *AuditLogEntryBuilder {
builder.auditResponse.ResponseBodyBytes = responseBody
return builder
}
// WithResponseHeaders adds response headers
func (builder *AuditLogEntryBuilder) WithResponseHeaders(responseHeaders map[string][]string) *AuditLogEntryBuilder {
builder.auditResponse.ResponseHeaders = responseHeaders
return builder
}
// WithResponseTime adds the time when the response is sent
func (builder *AuditLogEntryBuilder) WithResponseTime(responseTime time.Time) *AuditLogEntryBuilder {
builder.auditResponse.ResponseTime = &responseTime
return builder
}
// Build constructs the auditV1.AuditLogEntry.
//
// Parameters:
// - A context object
// - A SequenceNumber
//
// Returns:
// - The auditV1.AuditLogEntry protobuf message or
// - Error if the entry cannot be built
func (builder *AuditLogEntryBuilder) Build(ctx context.Context, sequenceNumber SequenceNumber) (*auditV1.AuditLogEntry, error) {
_, span := builder.tracer.Start(ctx, "build-audit-log-entry")
defer span.End()
auditTime := time.Now()
builder.auditMetadata.AuditTime = &auditTime
objectId, objectType, err := getObjectIdAndTypeFromAuditParams(&builder.auditParams)
if err != nil {
return nil, err
}
if builder.auditResponse.ResponseBodyBytes != nil && builder.auditParams.ResponseBody != nil {
return nil, errors.New("responseBodyBytes and responseBody set")
} else if builder.auditParams.ResponseBody != nil {
responseBytes, err := ResponseBodyToBytes(builder.auditParams.ResponseBody)
if err != nil {
return nil, err
}
builder.auditResponse.ResponseBodyBytes = responseBytes
}
resourceName := fmt.Sprintf("%s/%s", objectType.Plural(), objectId)
var logIdentifier string
var logType pkgAuditCommon.ObjectType
if builder.auditParams.EventType == pkgAuditCommon.EventTypeSystemEvent {
logIdentifier = pkgAuditCommon.SystemIdentifier.Identifier
logType = pkgAuditCommon.ObjectTypeSystem
} else {
logIdentifier = objectId
logType = *objectType
}
builder.auditMetadata.AuditInsertId = internalAuditApi.NewInsertId(time.Now().UTC(), builder.location, builder.workerId, uint64(sequenceNumber))
builder.auditMetadata.AuditLogName = fmt.Sprintf("%s/%s/logs/%s", logType.Plural(), logIdentifier, builder.auditParams.EventType)
builder.auditMetadata.AuditResourceName = resourceName
var details map[string]interface{}
if len(builder.auditParams.Details) > 0 {
details = builder.auditParams.Details
}
// Instantiate the audit event
return internalAuditApi.NewAuditLogEntry(
builder.auditRequest,
builder.auditResponse,
details,
builder.auditMetadata,
)
}
// AuditEventBuilder collects audit log parameters, validates input and
// returns a cloud event that can be sent to the audit log system.
type AuditEventBuilder struct {
// The audit api used to validate, serialize and send events
api pkgAuditCommon.AuditApi
// The audit log entry builder which is used to build the actual protobuf message
auditLogEntryBuilder *AuditLogEntryBuilder
// Status whether the event has been built
built bool
// Sequence number generator providing sequential increasing numbers for the insert IDs
sequenceNumberGenerator pkgAuditUtils.SequenceNumberGenerator
// Opentelemetry tracer
tracer trace.Tracer
// Visibility of the event
visibility auditV1.Visibility
}
// NewAuditEventBuilder returns a builder that collects audit log parameters,
// validates input and returns a cloud event that can be sent to the audit log system.
func NewAuditEventBuilder(
// The audit api used to validate, serialize and send events
api pkgAuditCommon.AuditApi,
// The sequence number generator can be used to get and revert sequence numbers to build audit log events
sequenceNumberGenerator pkgAuditUtils.SequenceNumberGenerator,
// The service name in lowercase (allowed characters are [a-z-]).
serviceName string,
// The ID of the K8s Pod, Service-Instance, etc. (must be unique for a sending service)
workerId string,
// The location of the service (e.g. eu01)
location string,
) *AuditEventBuilder {
return &AuditEventBuilder{
api: api,
auditLogEntryBuilder: NewAuditLogEntryBuilder().
WithRequiredServiceName(serviceName).
WithRequiredWorkerId(workerId).
WithRequiredLocation(location),
sequenceNumberGenerator: sequenceNumberGenerator,
tracer: otel.Tracer("audit-event-builder"),
visibility: auditV1.Visibility_VISIBILITY_PUBLIC,
}
}
// NextSequenceNumber returns the next sequence number from utils.SequenceNumberGenerator.
// In case of an error RevertSequenceNumber must be called to prevent gaps in the sequence of numbers.
func (builder *AuditEventBuilder) NextSequenceNumber() SequenceNumber {
return SequenceNumber(builder.sequenceNumberGenerator.Next())
}
// RevertSequenceNumber can be called to decrease the sequence number on the utils.SequenceNumberGenerator in case of an error
func (builder *AuditEventBuilder) RevertSequenceNumber(number SequenceNumber) {
builder.sequenceNumberGenerator.Revert(uint64(number))
}
func (builder *AuditEventBuilder) AsSystemEvent() *AuditEventBuilder {
builder.auditLogEntryBuilder.AsSystemEvent()
builder.WithVisibility(auditV1.Visibility_VISIBILITY_PRIVATE)
return builder
}
// WithAuditLogEntryBuilder overwrites the preconfigured AuditLogEntryBuilder
func (builder *AuditEventBuilder) WithAuditLogEntryBuilder(auditLogEntryBuilder *AuditLogEntryBuilder) *AuditEventBuilder {
builder.auditLogEntryBuilder = auditLogEntryBuilder
return builder
}
// WithRequiredApiRequest adds api request details
func (builder *AuditEventBuilder) WithRequiredApiRequest(request pkgAuditCommon.ApiRequest) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithRequiredApiRequest(request)
return builder
}
// GetApiRequest returns the api request details
func (builder *AuditEventBuilder) GetApiRequest() *pkgAuditCommon.ApiRequest {
return builder.auditLogEntryBuilder.GetApiRequest()
}
// WithRequiredRequestClientIp adds the client ip
func (builder *AuditEventBuilder) WithRequiredRequestClientIp(requestClientIp string) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithRequiredRequestClientIp(requestClientIp)
return builder
}
// WithRequestCorrelationId adds an optional request correlation id
func (builder *AuditEventBuilder) WithRequestCorrelationId(requestCorrelationId string) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithRequestCorrelationId(requestCorrelationId)
return builder
}
// WithRequestId adds an optional request id
func (builder *AuditEventBuilder) WithRequestId(requestId string) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithRequestId(requestId)
return builder
}
// WithRequestTime sets the request time on the builder. If not set - the instantiation time of the builder is used.
func (builder *AuditEventBuilder) WithRequestTime(requestTime time.Time) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithRequestTime(requestTime)
return builder
}
// WithRequiredObjectId adds the object identifier.
// May be prefilled by audit middleware (if the identifier can be extracted from the url path).
func (builder *AuditEventBuilder) WithRequiredObjectId(objectId string) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithRequiredObjectId(objectId)
return builder
}
// WithRequiredObjectType adds the object type.
// May be prefilled by audit middleware (if the type can be extracted from the url path).
func (builder *AuditEventBuilder) WithRequiredObjectType(objectType pkgAuditCommon.ObjectType) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithRequiredObjectType(objectType)
return builder
}
// WithRequiredOperation adds the name of the service method or operation.
//
// Format: stackit.<product>.<version>.<type-chain>.<operation>
// Where:
//
// Product: The name of the service in lowercase
// Version: Optional API version
// Type-Chain: Chained path to object
// Operation: The name of the operation in lowercase
//
// Examples:
//
// "stackit.resource-manager.v1.organizations.create"
// "stackit.authorization.v1.projects.volumes.create"
// "stackit.authorization.v2alpha.projects.volumes.create"
// "stackit.authorization.v2.folders.move"
// "stackit.resource-manager.health"
func (builder *AuditEventBuilder) WithRequiredOperation(operation string) *AuditEventBuilder {
builder.auditLogEntryBuilder.auditMetadata.AuditOperationName = operation
return builder
}
// WithAuditPermission adds the IAM permission
//
// Examples:
//
// "resourcemanager.project.edit"
func (builder *AuditEventBuilder) WithAuditPermission(permission string) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithAuditPermission(permission)
return builder
}
// WithAuditPermissionCheckResult adds the IAM permission check result
func (builder *AuditEventBuilder) WithAuditPermissionCheckResult(permissionCheckResult bool) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithAuditPermissionCheckResult(permissionCheckResult)
return builder
}
// WithLabels adds A set of user-defined (key, value) data that provides additional
// information about the log entry.
func (builder *AuditEventBuilder) WithLabels(labels map[string]string) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithLabels(labels)
return builder
}
// WithNumResponseItems adds the number of items returned to the client if applicable.
func (builder *AuditEventBuilder) WithNumResponseItems(numResponseItems int64) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithNumResponseItems(numResponseItems)
return builder
}
// WithEventType overwrites the default event type EventTypeAdminActivity
func (builder *AuditEventBuilder) WithEventType(eventType pkgAuditCommon.EventType) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithEventType(eventType)
return builder
}
// WithDetails adds an optional details object to the audit log entry
func (builder *AuditEventBuilder) WithDetails(details map[string]interface{}) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithDetails(details)
return builder
}
// WithSeverity overwrites the default log severity level auditV1.LogSeverity_LOG_SEVERITY_DEFAULT
func (builder *AuditEventBuilder) WithSeverity(severity auditV1.LogSeverity) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithSeverity(severity)
return builder
}
// WithStatusCode adds the (http) response status code
func (builder *AuditEventBuilder) WithStatusCode(statusCode int) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithStatusCode(statusCode)
return builder
}
// WithResponseBody adds the response body to the builder and transforms it in the Build method (json serializable or protobuf message expected)
func (builder *AuditEventBuilder) WithResponseBody(responseBody any) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithResponseBody(responseBody)
return builder
}
// WithResponseBodyBytes adds the response body as bytes (serialized json or protobuf message expected)
func (builder *AuditEventBuilder) WithResponseBodyBytes(responseBody []byte) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithResponseBodyBytes(responseBody)
return builder
}
// WithResponseHeaders adds response headers
func (builder *AuditEventBuilder) WithResponseHeaders(responseHeaders map[string][]string) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithResponseHeaders(responseHeaders)
return builder
}
// WithResponseTime adds the time when the response is sent
func (builder *AuditEventBuilder) WithResponseTime(responseTime time.Time) *AuditEventBuilder {
builder.auditLogEntryBuilder.WithResponseTime(responseTime)
return builder
}
// WithVisibility overwrites the default visibility auditV1.Visibility_VISIBILITY_PUBLIC
func (builder *AuditEventBuilder) WithVisibility(visibility auditV1.Visibility) *AuditEventBuilder {
builder.visibility = visibility
return builder
}
// IsBuilt returns the status whether the cloud event has been built
func (builder *AuditEventBuilder) IsBuilt() bool {
return builder.built
}
// MarkAsBuilt sets the internal built flag to true.
// This is useful in middlewares where the IsBuilt method is used
// to check if an event has been constructed.
func (builder *AuditEventBuilder) MarkAsBuilt() {
builder.built = true
}
// Build constructs the CloudEvent.
//
// Parameters:
// - A context object
// - A sequence number. AuditEventBuilder.NextSequenceNumber can be used to get the next SequenceNumber.
//
// Returns:
// - The CloudEvent containing the audit log entry
// - The RoutableIdentifier required for routing the cloud event
// - The operation name
// - Error if the event cannot be built
func (builder *AuditEventBuilder) Build(ctx context.Context, sequenceNumber SequenceNumber) (*pkgAuditCommon.CloudEvent, *pkgAuditCommon.RoutableIdentifier, error) {
if builder.auditLogEntryBuilder == nil {
return nil, nil, fmt.Errorf("audit log entry builder not set")
}
ctx, span := builder.tracer.Start(ctx, "build-audit-event")
defer span.End()
visibility := builder.visibility
objectId := builder.auditLogEntryBuilder.auditParams.ObjectId
objectType := builder.auditLogEntryBuilder.auditParams.ObjectType
var routingIdentifier *pkgAuditCommon.RoutableIdentifier
if builder.auditLogEntryBuilder.auditParams.EventType == pkgAuditCommon.EventTypeSystemEvent {
routingIdentifier = internalAuditApi.NewAuditRoutingIdentifier(uuid.Nil.String(), pkgAuditCommon.ObjectTypeSystem)
if objectId == "" {
objectId = uuid.Nil.String()
builder.WithRequiredObjectId(objectId)
}
if objectType == "" {
objectType = pkgAuditCommon.ObjectTypeSystem
builder.WithRequiredObjectType(objectType)
}
} else {
routingIdentifier = internalAuditApi.NewAuditRoutingIdentifier(objectId, objectType)
}
auditLogEntry, err := builder.auditLogEntryBuilder.Build(ctx, sequenceNumber)
if err != nil {
return nil, nil, err
}
// Validate and serialize the protobuf event into a cloud event
cloudEvent, err := builder.api.ValidateAndSerialize(ctx, auditLogEntry, visibility, routingIdentifier)
if err != nil {
return nil, nil, err
}
builder.built = true
return cloudEvent,
routingIdentifier,
nil
}