mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
Add audit events for approving & denying an EnrollPairing (#69505)
* Add audit events for approving & denying an `EnrollPairing` * Add web changes * Drop `device.enroll_pairing.approve` from `eventGroupTypes` * "not approved" -> "denied" * Update wording around `device.enroll_pairing.approve` emitted on failure While working on the RPC handler implementation, I realized that `TV011W` is not emitted on MFA failures. This commit updates the godoc and the fixture accordingly. * Update `deny` audit event wording around expiry In a typical scenario there will be no one to observe expiry, so this event won't be emitted on enroll pairing expiry. I'll update the RFD accordingly soon. For now just putting this here since I have no other outstanding OSS PRs. * Remove no longer necessary TODO comment "Retryability" will be implemented one level above the storage layer, in the RPC handler, so the comment here is no longer necessary. * Remove `error` field from `device.enroll_pairing.deny` Now that it's only going to be used for an explicit user denial, there's no need to carry the `error` field.
This commit is contained in:
@@ -3534,6 +3534,83 @@ Example:
|
||||
}
|
||||
```
|
||||
|
||||
## device.enroll_pairing.approve
|
||||
|
||||
There are multiple events with the `device.enroll_pairing.approve` type.
|
||||
|
||||
### TV011I
|
||||
|
||||
Device Enroll Pairing Approved
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"cluster_name": "im-a-cluster-name",
|
||||
"code": "TV011I",
|
||||
"device": {
|
||||
"asset_tag": "M2CQVQV64R",
|
||||
"device_id": "",
|
||||
"os_type": 4
|
||||
},
|
||||
"ei": 0,
|
||||
"event": "device.enroll_pairing.approve",
|
||||
"success": true,
|
||||
"time": "2024-04-08T19:39:48.1Z",
|
||||
"uid": "b8c4f0a2-5e6d-7f8a-0123-abc456789012",
|
||||
"user": "llama"
|
||||
}
|
||||
```
|
||||
|
||||
### TV011W
|
||||
|
||||
Device Enroll Pairing Approval Failed
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"cluster_name": "im-a-cluster-name",
|
||||
"code": "TV011W",
|
||||
"device": {
|
||||
"asset_tag": "M2CQVQV64R",
|
||||
"device_id": "",
|
||||
"os_type": 4
|
||||
},
|
||||
"ei": 0,
|
||||
"error": "enroll pairing is not awaiting approval",
|
||||
"event": "device.enroll_pairing.approve",
|
||||
"success": false,
|
||||
"time": "2024-04-08T19:40:48.1Z",
|
||||
"uid": "b8c4f0a2-5e6d-7f8a-0123-abc456789013",
|
||||
"user": "llama"
|
||||
}
|
||||
```
|
||||
|
||||
## device.enroll_pairing.deny
|
||||
|
||||
Device Enroll Pairing Denied
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"cluster_name": "im-a-cluster-name",
|
||||
"code": "TV012W",
|
||||
"device": {
|
||||
"asset_tag": "M2CQVQV64R",
|
||||
"device_id": "",
|
||||
"os_type": 4
|
||||
},
|
||||
"ei": 0,
|
||||
"event": "device.enroll_pairing.deny",
|
||||
"success": false,
|
||||
"time": "2024-04-08T19:41:48.1Z",
|
||||
"uid": "c9d5a1b3-6f7e-8a9b-2345-bcd567890123",
|
||||
"user": "llama"
|
||||
}
|
||||
```
|
||||
|
||||
## device.enroll_pairing.request
|
||||
|
||||
There are multiple events with the `device.enroll_pairing.request` type.
|
||||
|
||||
@@ -712,6 +712,14 @@ const (
|
||||
// awaiting approval. It is also emitted on failure (e.g. an invalid token),
|
||||
// before any transition, in which case there is no associated user.
|
||||
DeviceEnrollPairingRequestEvent = "device.enroll_pairing.request"
|
||||
// DeviceEnrollPairingApproveEvent is emitted when the user approves an enroll
|
||||
// pairing in the Web UI, which lets the device retrieve its enrollment token.
|
||||
// It is also emitted on a failed approval attempt, for example one arriving
|
||||
// after the pairing expired or was already approved.
|
||||
DeviceEnrollPairingApproveEvent = "device.enroll_pairing.approve"
|
||||
// DeviceEnrollPairingDenyEvent is emitted when the user denies an enroll
|
||||
// pairing in the Web UI.
|
||||
DeviceEnrollPairingDenyEvent = "device.enroll_pairing.deny"
|
||||
|
||||
// BotJoinEvent is emitted when a bot joins
|
||||
BotJoinEvent = "bot.join"
|
||||
|
||||
@@ -530,6 +530,13 @@ const (
|
||||
// DeviceEnrollPairingRequestFailureCode is the device enroll pairing request
|
||||
// failure code.
|
||||
DeviceEnrollPairingRequestFailureCode = "TV010W"
|
||||
// DeviceEnrollPairingApproveCode is the device enroll pairing approve code.
|
||||
DeviceEnrollPairingApproveCode = "TV011I"
|
||||
// DeviceEnrollPairingApproveFailureCode is the device enroll pairing approve
|
||||
// failure code.
|
||||
DeviceEnrollPairingApproveFailureCode = "TV011W"
|
||||
// DeviceEnrollPairingDenyCode is the device enroll pairing deny code.
|
||||
DeviceEnrollPairingDenyCode = "TV012W"
|
||||
|
||||
// LoginRuleCreateCode is the login rule create code.
|
||||
LoginRuleCreateCode = "TLR00I"
|
||||
|
||||
@@ -297,7 +297,9 @@ func FromEventFields(fields EventFields) (events.AuditEvent, error) {
|
||||
DeviceEnrollTokenCreateEvent,
|
||||
DeviceWebTokenCreateEvent,
|
||||
DeviceAuthenticateConfirmEvent,
|
||||
DeviceEnrollPairingRequestEvent:
|
||||
DeviceEnrollPairingRequestEvent,
|
||||
DeviceEnrollPairingApproveEvent,
|
||||
DeviceEnrollPairingDenyEvent:
|
||||
e = &events.DeviceEvent2{}
|
||||
case LockCreatedEvent:
|
||||
e = &events.LockCreate{}
|
||||
|
||||
@@ -156,6 +156,8 @@ var eventsMap = map[string]apievents.AuditEvent{
|
||||
DeviceWebTokenCreateEvent: &apievents.DeviceEvent2{},
|
||||
DeviceAuthenticateConfirmEvent: &apievents.DeviceEvent2{},
|
||||
DeviceEnrollPairingRequestEvent: &apievents.DeviceEvent2{},
|
||||
DeviceEnrollPairingApproveEvent: &apievents.DeviceEvent2{},
|
||||
DeviceEnrollPairingDenyEvent: &apievents.DeviceEvent2{},
|
||||
LockCreatedEvent: &apievents.LockCreate{},
|
||||
LockDeletedEvent: &apievents.LockDelete{},
|
||||
RecoveryCodeGeneratedEvent: &apievents.RecoveryCodeGenerate{},
|
||||
|
||||
@@ -208,8 +208,6 @@ func (s *EnrollPairingService) RequestEnrollPairingApproval(ctx context.Context,
|
||||
}
|
||||
|
||||
const errNotAwaitingDevice = "enroll pairing is not awaiting a device"
|
||||
// TODO(ravicious): Make the call retryable from the same device, as described
|
||||
// in the Interrputibility section of RFD 32e.
|
||||
if pairing.GetStatus().GetState() != devicepb.EnrollPairingState_ENROLL_PAIRING_STATE_AWAITING_DEVICE {
|
||||
return nil, trace.CompareFailed(errNotAwaitingDevice)
|
||||
}
|
||||
|
||||
@@ -208,6 +208,9 @@ export const EventIconMap: Record<EventCode, any> = {
|
||||
[eventCodes.DEVICE_AUTHENTICATE_CONFIRM]: Icons.Info,
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_REQUEST]: Icons.Info,
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_REQUEST_FAILURE]: Icons.Info,
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_APPROVE]: Icons.Info,
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_APPROVE_FAILURE]: Icons.Info,
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_DENY]: Icons.Info,
|
||||
[eventCodes.MFA_DEVICE_ADD]: Icons.Info,
|
||||
[eventCodes.MFA_DEVICE_DELETE]: Icons.Info,
|
||||
[eventCodes.BILLING_CARD_CREATE]: Icons.CreditCard,
|
||||
|
||||
@@ -3321,6 +3321,52 @@ export const events = [
|
||||
time: '2024-04-08T19:38:48.1Z',
|
||||
uid: 'a7b3e9f1-4d5c-6a8b-9012-def345678902',
|
||||
},
|
||||
{
|
||||
cluster_name: 'im-a-cluster-name',
|
||||
code: 'TV011I',
|
||||
device: {
|
||||
asset_tag: 'M2CQVQV64R',
|
||||
device_id: '',
|
||||
os_type: 4,
|
||||
},
|
||||
ei: 0,
|
||||
event: 'device.enroll_pairing.approve',
|
||||
success: true,
|
||||
time: '2024-04-08T19:39:48.1Z',
|
||||
uid: 'b8c4f0a2-5e6d-7f8a-0123-abc456789012',
|
||||
user: 'llama',
|
||||
},
|
||||
{
|
||||
cluster_name: 'im-a-cluster-name',
|
||||
code: 'TV011W',
|
||||
device: {
|
||||
asset_tag: 'M2CQVQV64R',
|
||||
device_id: '',
|
||||
os_type: 4,
|
||||
},
|
||||
ei: 0,
|
||||
error: 'enroll pairing is not awaiting approval',
|
||||
event: 'device.enroll_pairing.approve',
|
||||
success: false,
|
||||
time: '2024-04-08T19:40:48.1Z',
|
||||
uid: 'b8c4f0a2-5e6d-7f8a-0123-abc456789013',
|
||||
user: 'llama',
|
||||
},
|
||||
{
|
||||
cluster_name: 'im-a-cluster-name',
|
||||
code: 'TV012W',
|
||||
device: {
|
||||
asset_tag: 'M2CQVQV64R',
|
||||
device_id: '',
|
||||
os_type: 4,
|
||||
},
|
||||
ei: 0,
|
||||
event: 'device.enroll_pairing.deny',
|
||||
success: false,
|
||||
time: '2024-04-08T19:41:48.1Z',
|
||||
uid: 'c9d5a1b3-6f7e-8a9b-2345-bcd567890123',
|
||||
user: 'llama',
|
||||
},
|
||||
{
|
||||
cluster_name: 'im-a-cluster-name',
|
||||
code: 'TLR00I',
|
||||
|
||||
@@ -1507,6 +1507,34 @@ export const formatters: Formatters = {
|
||||
? `Device enrollment request failed${formatDevice(device)}: ${error}`
|
||||
: `Device enrollment request failed${formatDevice(device)}`,
|
||||
},
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_APPROVE]: {
|
||||
type: 'device.enroll_pairing.approve',
|
||||
desc: 'Device Enroll Pairing Approved',
|
||||
format: ({ user, device }) =>
|
||||
`User [${user}] approved the device enrollment request${formatDevice(device)}`,
|
||||
},
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_APPROVE_FAILURE]: {
|
||||
type: 'device.enroll_pairing.approve',
|
||||
desc: 'Device Enroll Pairing Approval Failed',
|
||||
format: ({ user, device, error }) => {
|
||||
let msg = `User [${user}] failed to approve the device enrollment request${formatDevice(device)}`;
|
||||
if (error) {
|
||||
msg += `: ${error}`;
|
||||
}
|
||||
return msg;
|
||||
},
|
||||
},
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_DENY]: {
|
||||
type: 'device.enroll_pairing.deny',
|
||||
desc: 'Device Enroll Pairing Denied',
|
||||
format: ({ user, device, error }) => {
|
||||
let msg = `Device enrollment request for user [${user}] was denied${formatDevice(device)}`;
|
||||
if (error) {
|
||||
msg += `: ${error}`;
|
||||
}
|
||||
return msg;
|
||||
},
|
||||
},
|
||||
[eventCodes.X11_FORWARD]: {
|
||||
type: 'x11-forward',
|
||||
desc: 'X11 Forwarding Requested',
|
||||
|
||||
@@ -123,6 +123,9 @@ export const eventCodes = {
|
||||
DEVICE_AUTHENTICATE_CONFIRM: 'TV009I',
|
||||
DEVICE_ENROLL_PAIRING_REQUEST: 'TV010I',
|
||||
DEVICE_ENROLL_PAIRING_REQUEST_FAILURE: 'TV010W',
|
||||
DEVICE_ENROLL_PAIRING_APPROVE: 'TV011I',
|
||||
DEVICE_ENROLL_PAIRING_APPROVE_FAILURE: 'TV011W',
|
||||
DEVICE_ENROLL_PAIRING_DENY: 'TV012W',
|
||||
EXEC_FAILURE: 'T3002E',
|
||||
EXEC: 'T3002I',
|
||||
GITHUB_CONNECTOR_CREATED: 'T8000I',
|
||||
@@ -1434,6 +1437,17 @@ export type RawEvents = {
|
||||
typeof eventCodes.DEVICE_ENROLL_PAIRING_REQUEST_FAILURE,
|
||||
Merge<DeviceEventFields, { error?: string }>
|
||||
>;
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_APPROVE]: RawDeviceEvent<
|
||||
typeof eventCodes.DEVICE_ENROLL_PAIRING_APPROVE
|
||||
>;
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_APPROVE_FAILURE]: RawEvent<
|
||||
typeof eventCodes.DEVICE_ENROLL_PAIRING_APPROVE_FAILURE,
|
||||
Merge<DeviceEventFields, { error?: string }>
|
||||
>;
|
||||
[eventCodes.DEVICE_ENROLL_PAIRING_DENY]: RawEvent<
|
||||
typeof eventCodes.DEVICE_ENROLL_PAIRING_DENY,
|
||||
Merge<DeviceEventFields, { error?: string }>
|
||||
>;
|
||||
[eventCodes.UNKNOWN]: RawEvent<
|
||||
typeof eventCodes.UNKNOWN,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user