mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-11 22:49:54 +00:00
Add audit event for Classifier delete, docs, and web UI support (#67763)
* Add audit event for Classifier delete, docs, and web UI support * Add failure code for the Classifier delete audit event * Add web UI and docs support for Classifier audit failure codes
This commit is contained in:
@@ -5203,6 +5203,7 @@ message OneOf {
|
||||
events.BeamsConfigDelete BeamsConfigDelete = 259;
|
||||
events.ClassifierCreate ClassifierCreate = 260;
|
||||
events.ClassifierUpdate ClassifierUpdate = 261;
|
||||
events.ClassifierDelete ClassifierDelete = 262;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10827,3 +10828,41 @@ message ClassifierUpdate {
|
||||
(gogoproto.casttype) = "Struct"
|
||||
];
|
||||
}
|
||||
|
||||
// ClassifierDelete is emitted when a classifier is deleted.
|
||||
message ClassifierDelete {
|
||||
// Metadata is a common event metadata
|
||||
Metadata Metadata = 1 [
|
||||
(gogoproto.nullable) = false,
|
||||
(gogoproto.embed) = true,
|
||||
(gogoproto.jsontag) = ""
|
||||
];
|
||||
|
||||
// ResourceMetadata is a common resource event metadata
|
||||
ResourceMetadata Resource = 2 [
|
||||
(gogoproto.nullable) = false,
|
||||
(gogoproto.embed) = true,
|
||||
(gogoproto.jsontag) = ""
|
||||
];
|
||||
|
||||
// User is a common user event metadata
|
||||
UserMetadata User = 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) = ""
|
||||
];
|
||||
|
||||
// Status indicates whether the deletion was successful.
|
||||
Status Status = 5 [
|
||||
(gogoproto.nullable) = false,
|
||||
(gogoproto.embed) = true,
|
||||
(gogoproto.jsontag) = ""
|
||||
];
|
||||
}
|
||||
|
||||
@@ -3046,3 +3046,7 @@ func (m *ClassifierCreate) TrimToMaxSize(_ int) AuditEvent {
|
||||
func (m *ClassifierUpdate) TrimToMaxSize(_ int) AuditEvent {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ClassifierDelete) TrimToMaxSize(_ int) AuditEvent {
|
||||
return m
|
||||
}
|
||||
|
||||
+1982
-1531
File diff suppressed because it is too large
Load Diff
@@ -1064,6 +1064,10 @@ func ToOneOf(in AuditEvent) (*OneOf, error) {
|
||||
out.Event = &OneOf_ClassifierUpdate{
|
||||
ClassifierUpdate: e,
|
||||
}
|
||||
case *ClassifierDelete:
|
||||
out.Event = &OneOf_ClassifierDelete{
|
||||
ClassifierDelete: e,
|
||||
}
|
||||
|
||||
default:
|
||||
slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType())
|
||||
|
||||
@@ -1743,6 +1743,63 @@ Example:
|
||||
}
|
||||
```
|
||||
|
||||
## classifier.delete
|
||||
|
||||
There are multiple events with the `classifier.delete` type.
|
||||
|
||||
### INF016I
|
||||
|
||||
Classifier Deleted
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"addr.remote": "127.0.0.1:62460",
|
||||
"cluster_name": "teleport.dev",
|
||||
"code": "INF016I",
|
||||
"ei": 0,
|
||||
"event": "classifier.delete",
|
||||
"name": "my-classifier",
|
||||
"success": true,
|
||||
"time": "2025-03-04T16:03:21.869Z",
|
||||
"uid": "b0973df2-4bee-4a67-9925-575c1d38cc80",
|
||||
"user": "08fcd522-edcb-492d-8752-90494a28b70e.teleport.dev",
|
||||
"user_cluster_name": "teleport.dev",
|
||||
"user_kind": 3,
|
||||
"user_roles": [
|
||||
"Admin"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### INF016E
|
||||
|
||||
Classifier Deletion Failed
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"addr.remote": "127.0.0.1:62460",
|
||||
"cluster_name": "teleport.dev",
|
||||
"code": "INF016E",
|
||||
"ei": 0,
|
||||
"event": "classifier.delete",
|
||||
"name": "my-classifier",
|
||||
"error": "classifier \"my-classifier\" doesn't exist",
|
||||
"success": false,
|
||||
"time": "2025-03-04T16:03:31.869Z",
|
||||
"uid": "b3973df2-4bee-4a67-9925-575c1d38cc80",
|
||||
"user": "08fcd522-edcb-492d-8752-90494a28b70e.teleport.dev",
|
||||
"user_cluster_name": "teleport.dev",
|
||||
"user_kind": 3,
|
||||
"user_roles": [
|
||||
"Admin"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## classifier.update
|
||||
|
||||
There are multiple events with the `classifier.update` type.
|
||||
|
||||
@@ -1042,6 +1042,8 @@ const (
|
||||
ClassifierCreateEvent = "classifier.create"
|
||||
// ClassifierUpdateEvent is emitted when a classifier resource is updated.
|
||||
ClassifierUpdateEvent = "classifier.update"
|
||||
// ClassifierDeleteEvent is emitted when a classifier resource is deleted.
|
||||
ClassifierDeleteEvent = "classifier.delete"
|
||||
|
||||
// SessionSummarizedEvent is emitted when a session summary is created.
|
||||
SessionSummarizedEvent = "session.summarized"
|
||||
|
||||
@@ -906,6 +906,10 @@ const (
|
||||
ClassifierUpdateCode = "INF015I"
|
||||
// ClassifierUpdateFailureCode is the classifier update failure event code.
|
||||
ClassifierUpdateFailureCode = "INF015E"
|
||||
// ClassifierDeleteCode is the classifier delete event code.
|
||||
ClassifierDeleteCode = "INF016I"
|
||||
// ClassifierDeleteFailureCode is the classifier delete failure event code.
|
||||
ClassifierDeleteFailureCode = "INF016E"
|
||||
|
||||
// CertAuthOverrideCreateCode is the cert_auth_override create event code.
|
||||
CertAuthOverrideCreateCode = "TCO01I"
|
||||
|
||||
@@ -638,6 +638,8 @@ func FromEventFields(fields EventFields) (events.AuditEvent, error) {
|
||||
e = &events.ClassifierCreate{}
|
||||
case ClassifierUpdateEvent:
|
||||
e = &events.ClassifierUpdate{}
|
||||
case ClassifierDeleteEvent:
|
||||
e = &events.ClassifierDelete{}
|
||||
|
||||
case SessionSummarizedEvent:
|
||||
e = &events.SessionSummarized{}
|
||||
|
||||
@@ -291,6 +291,9 @@ var eventsMap = map[string]apievents.AuditEvent{
|
||||
RetrievalModelCreateEvent: &apievents.RetrievalModelCreate{},
|
||||
RetrievalModelUpdateEvent: &apievents.RetrievalModelUpdate{},
|
||||
RetrievalModelDeleteEvent: &apievents.RetrievalModelDelete{},
|
||||
ClassifierCreateEvent: &apievents.ClassifierCreate{},
|
||||
ClassifierUpdateEvent: &apievents.ClassifierUpdate{},
|
||||
ClassifierDeleteEvent: &apievents.ClassifierDelete{},
|
||||
SessionSummarizedEvent: &apievents.SessionSummarized{},
|
||||
SCIMListingEvent: &apievents.SCIMListingEvent{},
|
||||
SCIMGetEvent: &apievents.SCIMResourceEvent{},
|
||||
@@ -1749,6 +1752,66 @@ func TestInferenceEvents(t *testing.T) {
|
||||
eventCode: BeamsConfigDeleteCode,
|
||||
hasPayload: false,
|
||||
},
|
||||
{
|
||||
name: "ClassifierCreate",
|
||||
event: &apievents.ClassifierCreate{
|
||||
Metadata: apievents.Metadata{
|
||||
Type: ClassifierCreateEvent,
|
||||
Code: ClassifierCreateCode,
|
||||
Time: testTime,
|
||||
ClusterName: "test-cluster",
|
||||
},
|
||||
ResourceMetadata: apievents.ResourceMetadata{
|
||||
Name: "test-classifier",
|
||||
},
|
||||
UserMetadata: apievents.UserMetadata{
|
||||
User: "test-user",
|
||||
},
|
||||
},
|
||||
eventType: ClassifierCreateEvent,
|
||||
eventCode: ClassifierCreateCode,
|
||||
hasPayload: true,
|
||||
},
|
||||
{
|
||||
name: "ClassifierUpdate",
|
||||
event: &apievents.ClassifierUpdate{
|
||||
Metadata: apievents.Metadata{
|
||||
Type: ClassifierUpdateEvent,
|
||||
Code: ClassifierUpdateCode,
|
||||
Time: testTime,
|
||||
ClusterName: "test-cluster",
|
||||
},
|
||||
ResourceMetadata: apievents.ResourceMetadata{
|
||||
Name: "test-classifier",
|
||||
},
|
||||
UserMetadata: apievents.UserMetadata{
|
||||
User: "test-user",
|
||||
},
|
||||
},
|
||||
eventType: ClassifierUpdateEvent,
|
||||
eventCode: ClassifierUpdateCode,
|
||||
hasPayload: true,
|
||||
},
|
||||
{
|
||||
name: "ClassifierDelete",
|
||||
event: &apievents.ClassifierDelete{
|
||||
Metadata: apievents.Metadata{
|
||||
Type: ClassifierDeleteEvent,
|
||||
Code: ClassifierDeleteCode,
|
||||
Time: testTime,
|
||||
ClusterName: "test-cluster",
|
||||
},
|
||||
ResourceMetadata: apievents.ResourceMetadata{
|
||||
Name: "test-classifier",
|
||||
},
|
||||
UserMetadata: apievents.UserMetadata{
|
||||
User: "test-user",
|
||||
},
|
||||
},
|
||||
eventType: ClassifierDeleteEvent,
|
||||
eventCode: ClassifierDeleteCode,
|
||||
hasPayload: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
@@ -377,6 +377,8 @@ export const EventIconMap: Record<EventCode, any> = {
|
||||
[eventCodes.CLASSIFIER_CREATE_FAILURE]: Icons.Warning,
|
||||
[eventCodes.CLASSIFIER_UPDATE]: Icons.Info,
|
||||
[eventCodes.CLASSIFIER_UPDATE_FAILURE]: Icons.Warning,
|
||||
[eventCodes.CLASSIFIER_DELETE]: Icons.Info,
|
||||
[eventCodes.CLASSIFIER_DELETE_FAILURE]: Icons.Warning,
|
||||
[eventCodes.SESSION_SUMMARIZED]: Icons.Info,
|
||||
[eventCodes.SESSION_SUMMARIZED_FAILURE]: Icons.Warning,
|
||||
[eventCodes.CERT_AUTH_OVERRIDE_CREATE]: Icons.Info,
|
||||
|
||||
@@ -4983,6 +4983,37 @@ export const events = [
|
||||
user_kind: 3,
|
||||
user_roles: ['Admin'],
|
||||
},
|
||||
{
|
||||
'addr.remote': '127.0.0.1:62460',
|
||||
cluster_name: 'teleport.dev',
|
||||
code: 'INF016I',
|
||||
ei: 0,
|
||||
event: 'classifier.delete',
|
||||
name: 'my-classifier',
|
||||
success: true,
|
||||
time: '2025-03-04T16:03:21.869Z',
|
||||
uid: 'b0973df2-4bee-4a67-9925-575c1d38cc80',
|
||||
user: '08fcd522-edcb-492d-8752-90494a28b70e.teleport.dev',
|
||||
user_cluster_name: 'teleport.dev',
|
||||
user_kind: 3,
|
||||
user_roles: ['Admin'],
|
||||
},
|
||||
{
|
||||
'addr.remote': '127.0.0.1:62460',
|
||||
cluster_name: 'teleport.dev',
|
||||
code: 'INF016E',
|
||||
ei: 0,
|
||||
event: 'classifier.delete',
|
||||
name: 'my-classifier',
|
||||
error: 'classifier "my-classifier" doesn\'t exist',
|
||||
success: false,
|
||||
time: '2025-03-04T16:03:31.869Z',
|
||||
uid: 'b3973df2-4bee-4a67-9925-575c1d38cc80',
|
||||
user: '08fcd522-edcb-492d-8752-90494a28b70e.teleport.dev',
|
||||
user_cluster_name: 'teleport.dev',
|
||||
user_kind: 3,
|
||||
user_roles: ['Admin'],
|
||||
},
|
||||
{
|
||||
cluster_name: 'teleport.dev',
|
||||
code: 'INF010I',
|
||||
|
||||
@@ -2669,6 +2669,17 @@ export const formatters: Formatters = {
|
||||
format: ({ name, user }) =>
|
||||
`Classifier [${name}] failed to be updated by [${user}]`,
|
||||
},
|
||||
[eventCodes.CLASSIFIER_DELETE]: {
|
||||
type: 'classifier.delete',
|
||||
desc: 'Classifier Deleted',
|
||||
format: ({ name, user }) => `Classifier [${name}] was deleted by [${user}]`,
|
||||
},
|
||||
[eventCodes.CLASSIFIER_DELETE_FAILURE]: {
|
||||
type: 'classifier.delete',
|
||||
desc: 'Classifier Deletion Failed',
|
||||
format: ({ name, user }) =>
|
||||
`Classifier [${name}] failed to be deleted by [${user}]`,
|
||||
},
|
||||
[eventCodes.SESSION_SUMMARIZED]: {
|
||||
type: 'session.summarized',
|
||||
desc: 'Session Summarized',
|
||||
|
||||
@@ -401,6 +401,8 @@ export const eventCodes = {
|
||||
CLASSIFIER_CREATE_FAILURE: 'INF014E',
|
||||
CLASSIFIER_UPDATE: 'INF015I',
|
||||
CLASSIFIER_UPDATE_FAILURE: 'INF015E',
|
||||
CLASSIFIER_DELETE: 'INF016I',
|
||||
CLASSIFIER_DELETE_FAILURE: 'INF016E',
|
||||
CERT_AUTH_OVERRIDE_CREATE: 'TCO01I',
|
||||
CERT_AUTH_OVERRIDE_UPDATE: 'TCO02I',
|
||||
CERT_AUTH_OVERRIDE_UPSERT: 'TCO03I',
|
||||
@@ -2354,6 +2356,14 @@ export type RawEvents = {
|
||||
typeof eventCodes.CLASSIFIER_UPDATE_FAILURE,
|
||||
HasName
|
||||
>;
|
||||
[eventCodes.CLASSIFIER_DELETE]: RawEvent<
|
||||
typeof eventCodes.CLASSIFIER_DELETE,
|
||||
HasName
|
||||
>;
|
||||
[eventCodes.CLASSIFIER_DELETE_FAILURE]: RawEvent<
|
||||
typeof eventCodes.CLASSIFIER_DELETE_FAILURE,
|
||||
HasName
|
||||
>;
|
||||
[eventCodes.SESSION_SUMMARIZED]: RawEvent<
|
||||
typeof eventCodes.SESSION_SUMMARIZED,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user