From 3995f2e6ae7b32e38183f4ed6c3a34c3d33b1d40 Mon Sep 17 00:00:00 2001 From: Jim Date: Sun, 16 Apr 2023 11:27:54 -0400 Subject: [PATCH] feat: add proper audit events for UpstreamMessage The upstream messages all basically looked the same; regardless of which message was sent. This PR adds DetailsUpstreamMessage to audit events emitted by UpstreamMessage requests/response --- .../upstream_message_service_controller.go | 27 ++++++++++++++++++- internal/observability/event/event.go | 17 ++++++++---- internal/observability/event/event_audit.go | 20 ++++++++++++-- 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/internal/daemon/cluster/handlers/upstream_message_service_controller.go b/internal/daemon/cluster/handlers/upstream_message_service_controller.go index 7ea41fcaa..fab8848a7 100644 --- a/internal/daemon/cluster/handlers/upstream_message_service_controller.go +++ b/internal/daemon/cluster/handlers/upstream_message_service_controller.go @@ -148,11 +148,36 @@ func (s *controllerUpstreamMessageServiceServer) UpstreamMessage(ctx context.Con return nil, status.Errorf(codes.Internal, "%s: error decrypting request message: %v", op, err) } } - + clonedMsg := proto.Clone(msg) + if err := event.WriteAudit(ctx, "handlers.(controllerUpstreamMessageServiceServer).UpstreamMessage", + event.WithRequest( + &event.Request{ + DetailsUpstreamMessage: &event.UpstreamMessage{ + Message: clonedMsg, + Type: string(clonedMsg.ProtoReflect().Descriptor().Name()), + }, + }, + )); err != nil { + // error was NOT event'd above... + _ = errors.Wrap(ctx, err, op, errors.WithCode(errors.Internal), errors.WithMsg("error writing upstream message unwrapped details request")) + } respMsg, respStatusErr := h.Handler(ctx, msg) if respStatusErr != nil { return nil, respStatusErr } + clonedResp := proto.Clone(respMsg) + if err := event.WriteAudit(ctx, "handlers.(controllerUpstreamMessageServiceServer).UpstreamMessage", + event.WithResponse( + &event.Response{ + DetailsUpstreamMessage: &event.UpstreamMessage{ + Message: clonedResp, + Type: string(clonedResp.ProtoReflect().Descriptor().Name()), + }, + }, + )); err != nil { + // error was NOT event'd above... + _ = errors.Wrap(ctx, err, op, errors.WithCode(errors.Internal), errors.WithMsg("error writing upstream message unwrapped details response")) + } switch { case h.Encrypted() == false: pt, err := proto.Marshal(respMsg) diff --git a/internal/observability/event/event.go b/internal/observability/event/event.go index f3c23778f..a30662868 100644 --- a/internal/observability/event/event.go +++ b/internal/observability/event/event.go @@ -48,12 +48,19 @@ type Auth struct { } type Request struct { - Operation string `json:"operation,omitempty" class:"public"` // std audit field - Endpoint string `json:"endpoint,omitempty" class:"public"` // std audit field - Details proto.Message `json:"details,omitempty"` // boundary field + Operation string `json:"operation,omitempty" class:"public"` // std audit field + Endpoint string `json:"endpoint,omitempty" class:"public"` // std audit field + Details proto.Message `json:"details,omitempty"` // boundary field + DetailsUpstreamMessage *UpstreamMessage `json:"details_upstream_message,omitempty"` // boundary field } type Response struct { - StatusCode int `json:"status_code,omitempty"` // std audit - Details proto.Message `json:"details,omitempty"` // boundary field + StatusCode int `json:"status_code,omitempty"` // std audit + Details proto.Message `json:"details,omitempty"` // boundary field + DetailsUpstreamMessage *UpstreamMessage `json:"details_upstream_message,omitempty"` // boundary field +} + +type UpstreamMessage struct { + Type string `json:"type,omitempty" class:"public"` // boundary field + Message proto.Message `json:"message,omitempty"` // boundary field } diff --git a/internal/observability/event/event_audit.go b/internal/observability/event/event_audit.go index 6e5ae4b9a..eb9ee2518 100644 --- a/internal/observability/event/event_audit.go +++ b/internal/observability/event/event_audit.go @@ -132,7 +132,21 @@ func (a *audit) ComposeFrom(events []*eventlogger.Event) (eventlogger.EventType, payload.Auth = gated.Auth } if gated.Request != nil { - payload.Request = gated.Request + if payload.Request == nil { + payload.Request = &Request{} + } + if gated.Request.Endpoint != "" { + payload.Request.Endpoint = gated.Request.Endpoint + } + if gated.Request.Operation != "" { + payload.Request.Operation = gated.Request.Operation + } + if gated.Request.Details != nil { + payload.Request.Details = gated.Request.Details + } + if gated.Request.DetailsUpstreamMessage != nil { + payload.Request.DetailsUpstreamMessage = gated.Request.DetailsUpstreamMessage + } } if gated.Response != nil { if payload.Response == nil { @@ -144,11 +158,13 @@ func (a *audit) ComposeFrom(events []*eventlogger.Event) (eventlogger.EventType, if gated.Response.Details != nil { payload.Response.Details = gated.Response.Details } + if gated.Response.DetailsUpstreamMessage != nil { + payload.Response.DetailsUpstreamMessage = gated.Response.DetailsUpstreamMessage + } } if !gated.Timestamp.IsZero() { payload.Timestamp = gated.Timestamp } - } payload.Id = validId payload.Version = auditVersion