added audit events for discovery config actions (#43750)

Co-authored-by: Andrew LeFevre <Andrew LeFevre>
This commit is contained in:
Andrew LeFevre
2024-07-03 12:41:22 +00:00
committed by GitHub
co-authored by Andrew LeFevre
parent d9bcd2e2da
commit 629f2d347f
9 changed files with 2856 additions and 1038 deletions
@@ -4003,6 +4003,123 @@ message DeviceEvent2 {
];
}
// DiscoveryConfigCreate is emitted when a discovery config is created.
message DiscoveryConfigCreate {
// Metadata is a common event metadata
Metadata Metadata = 1 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// User is a common user event metadata
UserMetadata User = 2 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ResourceMetadata is a common resource event metadata
ResourceMetadata Resource = 3 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ConnectionMetadata holds information about the connection
ConnectionMetadata Connection = 4 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
}
// DiscoveryConfigUpdate is emitted when a discovery config is updated.
message DiscoveryConfigUpdate {
// Metadata is a common event metadata
Metadata Metadata = 1 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// User is a common user event metadata
UserMetadata User = 2 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ResourceMetadata is a common resource event metadata
ResourceMetadata Resource = 3 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ConnectionMetadata holds information about the connection
ConnectionMetadata Connection = 4 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
}
// DiscoveryConfigDelete is emitted when a discovery config is deleted.
message DiscoveryConfigDelete {
// Metadata is a common event metadata
Metadata Metadata = 1 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// User is a common user event metadata
UserMetadata User = 2 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ResourceMetadata is a common resource event metadata
ResourceMetadata Resource = 3 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ConnectionMetadata holds information about the connection
ConnectionMetadata Connection = 4 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
}
// DiscoveryConfigDeleteAll is emitted when all discovery configs are deleted.
message DiscoveryConfigDeleteAll {
// Metadata is a common event metadata
Metadata Metadata = 1 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// User is a common user event metadata
UserMetadata User = 2 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// ConnectionMetadata holds information about the connection
ConnectionMetadata Connection = 3 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
}
// OneOf is a union of one of audit events submitted to the auth service
message OneOf {
// Event is one of the audit events
@@ -4165,6 +4282,10 @@ message OneOf {
events.AccessPathChanged AccessPathChanged = 157;
events.SpannerRPC SpannerRPC = 158;
events.DatabaseSessionCommandResult DatabaseSessionCommandResult = 159;
events.DiscoveryConfigCreate DiscoveryConfigCreate = 160;
events.DiscoveryConfigUpdate DiscoveryConfigUpdate = 161;
events.DiscoveryConfigDelete DiscoveryConfigDelete = 162;
events.DiscoveryConfigDeleteAll DiscoveryConfigDeleteAll = 163;
}
}
+2605 -1036
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -672,6 +672,22 @@ func ToOneOf(in AuditEvent) (*OneOf, error) {
out.Event = &OneOf_DatabaseSessionCommandResult{
DatabaseSessionCommandResult: e,
}
case *DiscoveryConfigCreate:
out.Event = &OneOf_DiscoveryConfigCreate{
DiscoveryConfigCreate: e,
}
case *DiscoveryConfigUpdate:
out.Event = &OneOf_DiscoveryConfigUpdate{
DiscoveryConfigUpdate: e,
}
case *DiscoveryConfigDelete:
out.Event = &OneOf_DiscoveryConfigDelete{
DiscoveryConfigDelete: e,
}
case *DiscoveryConfigDeleteAll:
out.Event = &OneOf_DiscoveryConfigDeleteAll{
DiscoveryConfigDeleteAll: e,
}
default:
slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType())
@@ -31,7 +31,9 @@ import (
"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/discoveryconfig"
conv "github.com/gravitational/teleport/api/types/discoveryconfig/convert/v1"
apievents "github.com/gravitational/teleport/api/types/events"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/services"
)
@@ -48,6 +50,9 @@ type ServiceConfig struct {
// Clock is the clock.
Clock clockwork.Clock
// Emitter emits audit events.
Emitter apievents.Emitter
}
// CheckAndSetDefaults checks the ServiceConfig fields and returns an error if
@@ -60,6 +65,9 @@ func (s *ServiceConfig) CheckAndSetDefaults() error {
if s.Backend == nil {
return trace.BadParameter("backend is required")
}
if s.Emitter == nil {
return trace.BadParameter("emitter is required")
}
if s.Logger == nil {
s.Logger = logrus.New().WithField(teleport.ComponentKey, "discoveryconfig_crud_service")
@@ -80,6 +88,7 @@ type Service struct {
authorizer authz.Authorizer
backend services.DiscoveryConfigs
clock clockwork.Clock
emitter apievents.Emitter
}
// NewService returns a new DiscoveryConfigs gRPC service.
@@ -93,6 +102,7 @@ func NewService(cfg ServiceConfig) (*Service, error) {
authorizer: cfg.Authorizer,
backend: cfg.Backend,
clock: cfg.Clock,
emitter: cfg.Emitter,
}, nil
}
@@ -167,6 +177,21 @@ func (s *Service) CreateDiscoveryConfig(ctx context.Context, req *discoveryconfi
return nil, trace.Wrap(err)
}
if err := s.emitter.EmitAuditEvent(ctx, &apievents.DiscoveryConfigCreate{
Metadata: apievents.Metadata{
Type: events.DiscoveryConfigCreateEvent,
Code: events.DiscoveryConfigCreateCode,
},
UserMetadata: authCtx.GetUserMetadata(),
ResourceMetadata: apievents.ResourceMetadata{
Name: resp.GetName(),
Expires: resp.Expiry(),
},
ConnectionMetadata: authz.ConnectionMetadata(ctx),
}); err != nil {
s.log.WithError(err).Warn("Failed to emit discovery config create event.")
}
return conv.ToProto(resp), nil
}
@@ -198,6 +223,21 @@ func (s *Service) UpdateDiscoveryConfig(ctx context.Context, req *discoveryconfi
return nil, trace.Wrap(err)
}
if err := s.emitter.EmitAuditEvent(ctx, &apievents.DiscoveryConfigUpdate{
Metadata: apievents.Metadata{
Type: events.DiscoveryConfigUpdateEvent,
Code: events.DiscoveryConfigUpdateCode,
},
UserMetadata: authCtx.GetUserMetadata(),
ResourceMetadata: apievents.ResourceMetadata{
Name: resp.GetName(),
Expires: resp.Expiry(),
},
ConnectionMetadata: authz.ConnectionMetadata(ctx),
}); err != nil {
s.log.WithError(err).Warn("Failed to emit discovery config update event.")
}
return conv.ToProto(resp), nil
}
@@ -226,6 +266,21 @@ func (s *Service) UpsertDiscoveryConfig(ctx context.Context, req *discoveryconfi
return nil, trace.Wrap(err)
}
if err := s.emitter.EmitAuditEvent(ctx, &apievents.DiscoveryConfigCreate{
Metadata: apievents.Metadata{
Type: events.DiscoveryConfigCreateEvent,
Code: events.DiscoveryConfigCreateCode,
},
UserMetadata: authCtx.GetUserMetadata(),
ResourceMetadata: apievents.ResourceMetadata{
Name: resp.GetName(),
Expires: resp.Expiry(),
},
ConnectionMetadata: authz.ConnectionMetadata(ctx),
}); err != nil {
s.log.WithError(err).Warn("Failed to emit discovery config create event.")
}
return conv.ToProto(resp), nil
}
@@ -244,6 +299,20 @@ func (s *Service) DeleteDiscoveryConfig(ctx context.Context, req *discoveryconfi
return nil, trace.Wrap(err)
}
if err := s.emitter.EmitAuditEvent(ctx, &apievents.DiscoveryConfigDelete{
Metadata: apievents.Metadata{
Type: events.DiscoveryConfigDeleteEvent,
Code: events.DiscoveryConfigDeleteCode,
},
UserMetadata: authCtx.GetUserMetadata(),
ResourceMetadata: apievents.ResourceMetadata{
Name: req.Name,
},
ConnectionMetadata: authz.ConnectionMetadata(ctx),
}); err != nil {
s.log.WithError(err).Warn("Failed to emit discovery config delete event.")
}
return &emptypb.Empty{}, nil
}
@@ -262,6 +331,17 @@ func (s *Service) DeleteAllDiscoveryConfigs(ctx context.Context, _ *discoverycon
return nil, trace.Wrap(err)
}
if err := s.emitter.EmitAuditEvent(ctx, &apievents.DiscoveryConfigDeleteAll{
Metadata: apievents.Metadata{
Type: events.DiscoveryConfigDeleteAllEvent,
Code: events.DiscoveryConfigDeleteAllCode,
},
UserMetadata: authCtx.GetUserMetadata(),
ConnectionMetadata: authz.ConnectionMetadata(ctx),
}); err != nil {
s.log.WithError(err).Warn("Failed to emit discovery config delete all event.")
}
return &emptypb.Empty{}, nil
}
@@ -35,6 +35,7 @@ import (
"github.com/gravitational/teleport/api/types/header"
"github.com/gravitational/teleport/lib/authz"
"github.com/gravitational/teleport/lib/backend/memory"
"github.com/gravitational/teleport/lib/events"
"github.com/gravitational/teleport/lib/services"
"github.com/gravitational/teleport/lib/services/local"
"github.com/gravitational/teleport/lib/tlsca"
@@ -430,7 +431,7 @@ func TestUpdateDiscoveryConfigStatus(t *testing.T) {
for _, tc := range tt {
tc := tc
t.Run(tc.name, func(t *testing.T) {
localCtx := authorizerForSystemRole(t, ctx, string(tc.systemRole), localClient)
localCtx := authorizerForSystemRole(ctx, string(tc.systemRole))
dcName := uuid.NewString()
if tc.setup != nil {
@@ -468,7 +469,7 @@ func authorizerForDummyUser(t *testing.T, ctx context.Context, roleSpec types.Ro
})
}
func authorizerForSystemRole(t *testing.T, ctx context.Context, systemRole string, localClient localClient) context.Context {
func authorizerForSystemRole(ctx context.Context, systemRole string) context.Context {
return authz.ContextWithUser(ctx, authz.BuiltinRole{
Username: uuid.NewString(),
Role: types.SystemRole(systemRole),
@@ -540,9 +541,12 @@ func initSvc(t *testing.T, clusterName string) (context.Context, localClient, *S
localResourceService, err := local.NewDiscoveryConfigService(backend)
require.NoError(t, err)
emitter := events.NewDiscardEmitter()
resourceSvc, err := NewService(ServiceConfig{
Backend: localResourceService,
Authorizer: authorizer,
Emitter: emitter,
})
require.NoError(t, err)
+1
View File
@@ -5300,6 +5300,7 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
Authorizer: cfg.Authorizer,
Backend: cfg.AuthServer.Services,
Clock: cfg.AuthServer.clock,
Emitter: cfg.Emitter,
})
if err != nil {
return nil, trace.Wrap(err)
+9
View File
@@ -770,6 +770,15 @@ const (
AccessGraphAccessPathChangedEvent = "access_graph.access_path_changed"
// TODO(jakule): Remove once e is updated to the new name.
AccessGraphAccessPathChanged = AccessGraphAccessPathChangedEvent
// DiscoveryConfigCreatedEvent is emitted when a discovery config is created.
DiscoveryConfigCreateEvent = "discovery_config.create"
// DiscoveryConfigUpdatedEvent is emitted when a discovery config is updated.
DiscoveryConfigUpdateEvent = "discovery_config.update"
// DiscoveryConfigDeletedEvent is emitted when a discovery config is deleted.
DiscoveryConfigDeleteEvent = "discovery_config.delete"
// DiscoveryConfigDeletedAllEvent is emitted when all discovery configs are deleted.
DiscoveryConfigDeleteAllEvent = "discovery_config.delete_all"
)
const (
+9
View File
@@ -620,6 +620,15 @@ const (
// AccessGraphAccessPathChangedCode is the access graph access path changed event code.
AccessGraphAccessPathChangedCode = "TAG001I"
// DiscoveryConfigCreateCode is the discovery config created event code.
DiscoveryConfigCreateCode = "DC001I"
// DiscoveryConfigUpdateCode is the discovery config updated event code.
DiscoveryConfigUpdateCode = "DC002I"
// DiscoveryConfigDeleteCode is the discovery config delete event code.
DiscoveryConfigDeleteCode = "DC003I"
// DiscoveryConfigDeleteAllCode is the discovery config delete all event code.
DiscoveryConfigDeleteAllCode = "DC004I"
// UnknownCode is used when an event of unknown type is encountered.
UnknownCode = apievents.UnknownCode
)
+9
View File
@@ -392,6 +392,15 @@ func FromEventFields(fields EventFields) (events.AuditEvent, error) {
case CassandraExecuteEventCode:
e = &events.CassandraExecute{}
case DiscoveryConfigCreateCode:
e = &events.DiscoveryConfigCreate{}
case DiscoveryConfigUpdateCode:
e = &events.DiscoveryConfigUpdate{}
case DiscoveryConfigDeleteCode:
e = &events.DiscoveryConfigDelete{}
case DiscoveryConfigDeleteAllCode:
e = &events.DiscoveryConfigDeleteAll{}
default:
log.Errorf("Attempted to convert dynamic event of unknown type %q into protobuf event.", eventType)
unknown := &events.Unknown{}