Skip to content

Commit

Permalink
GitHub proxy part 7: audit events (#49923)
Browse files Browse the repository at this point in the history
* GitHub proxy part 7: audit events

* make Git Command consistent

* fix typo
  • Loading branch information
greedy52 authored Dec 11, 2024
1 parent d87a04d commit 576192d
Show file tree
Hide file tree
Showing 10 changed files with 3,543 additions and 2,400 deletions.
67 changes: 67 additions & 0 deletions api/proto/teleport/legacy/types/events/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4707,6 +4707,7 @@ message OneOf {
events.WorkloadIdentityCreate WorkloadIdentityCreate = 194;
events.WorkloadIdentityUpdate WorkloadIdentityUpdate = 195;
events.WorkloadIdentityDelete WorkloadIdentityDelete = 196;
events.GitCommand GitCommand = 197;
}
}

Expand Down Expand Up @@ -7800,3 +7801,69 @@ message WorkloadIdentityDelete {
(gogoproto.jsontag) = ""
];
}

// GitCommand is emitted when a user performs a Git fetch or push command.
message GitCommand {
// 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) = ""
];

// SessionMetadata is a common event session metadata
SessionMetadata Session = 4 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];

// ServerMetadata is a common server metadata
ServerMetadata Server = 5 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];

// CommandMetadata is a common command metadata
CommandMetadata Command = 6 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];

// Service is the type of the git request like git-upload-pack or
// git-receive-pack.
string service = 8 [(gogoproto.jsontag) = "service"];
// Path is the Git repo path, usually <org>/<repo>.
string path = 9 [(gogoproto.jsontag) = "path"];

// Actions defines details for a Git push.
repeated GitCommandAction actions = 10 [(gogoproto.jsontag) = "actions,omitempty"];
}

// GitCommandAction defines details for a Git push.
message GitCommandAction {
// Action type like create or update.
string Action = 1 [(gogoproto.jsontag) = "action,omitempty"];
// Reference name like ref/main/my_branch.
string Reference = 2 [(gogoproto.jsontag) = "reference,omitempty"];
// Old is the old hash.
string Old = 3 [(gogoproto.jsontag) = "old,omitempty"];
// New is the new hash.
string New = 4 [(gogoproto.jsontag) = "new,omitempty"];
}
4 changes: 4 additions & 0 deletions api/types/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2402,3 +2402,7 @@ func (m *WorkloadIdentityUpdate) TrimToMaxSize(maxSize int) AuditEvent {
func (m *WorkloadIdentityDelete) TrimToMaxSize(_ int) AuditEvent {
return m
}

func (m *GitCommand) TrimToMaxSize(_ int) AuditEvent {
return m
}
5,765 changes: 3,365 additions & 2,400 deletions api/types/events/events.pb.go

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions api/types/events/oneof.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,10 @@ func ToOneOf(in AuditEvent) (*OneOf, error) {
out.Event = &OneOf_WorkloadIdentityDelete{
WorkloadIdentityDelete: e,
}
case *GitCommand:
out.Event = &OneOf_GitCommand{
GitCommand: e,
}
default:
slog.ErrorContext(context.Background(), "Attempted to convert dynamic event of unknown type into protobuf event.", "event_type", in.GetType())
unknown := &Unknown{}
Expand Down
3 changes: 3 additions & 0 deletions lib/events/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,9 @@ const (
WorkloadIdentityUpdateEvent = "workload_identity.update"
// WorkloadIdentityDeleteEvent is emitted when a WorkloadIdentity resource is deleted.
WorkloadIdentityDeleteEvent = "workload_identity.delete"

// GitCommandEvent is emitted when a Git command is executed.
GitCommandEvent = "git.command"
)

// Add an entry to eventsMap in lib/events/events_test.go when you add
Expand Down
5 changes: 5 additions & 0 deletions lib/events/codes.go
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,11 @@ const (
// WorkloadIdentityDeleteCode is the workload identity delete event code.
WorkloadIdentityDeleteCode = "WID003I"

// GitCommandCode is the git command event code
GitCommandCode = "TGIT001I"
// GitCommandFailureCode is the git command feature event code.
GitCommandFailureCode = "TGIT001E"

// UnknownCode is used when an event of unknown type is encountered.
UnknownCode = apievents.UnknownCode
)
Expand Down
2 changes: 2 additions & 0 deletions web/packages/teleport/src/Audit/EventList/EventTypeCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,8 @@ const EventIconMap: Record<EventCode, any> = {
[eventCodes.CONTACT_CREATE]: Icons.Info,
[eventCodes.CONTACT_DELETE]: Icons.Info,
[eventCodes.UNKNOWN]: Icons.Question,
[eventCodes.GIT_COMMAND]: Icons.GitHub,
[eventCodes.GIT_COMMAND_FAILURE]: Icons.GitHub,
};

export default function renderTypeCell(event: Event) {
Expand Down
35 changes: 35 additions & 0 deletions web/packages/teleport/src/Audit/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3742,6 +3742,41 @@ export const events = [
user: '30a6b2e1-3b61-4965-92cf-b4f84e9dc683.lenix',
user_kind: 1,
},
{
code: 'TGIT001E',
event: 'git.command',
time: '2024-12-07T11:11:11.111Z',
uid: '7699b806-e717-4821-85a5-d2f41acbe373',
user: 'Linus.Torvalds',
service: 'git-upload-pack',
exitError: 'some-error',
path: 'my-org/my-repo',
},
{
code: 'TGIT001I',
event: 'git.command',
time: '2024-12-07T11:11:11.112Z',
uid: '7699b806-e717-4821-85a5-d2f41acbe373',
user: 'Linus.Torvalds',
service: 'git-upload-pack',
path: 'my-org/my-repo',
},
{
code: 'TGIT001I',
event: 'git.command',
time: '2024-12-07T11:11:11.112Z',
uid: '7699b806-e717-4821-85a5-d2f41acbe373',
user: 'Linus.Torvalds',
service: 'git-receive-pack',
path: 'my-org/my-repo',
actions: [
{
action: 'update',
reference: 'refs/heads/my-branch',
new: 'd3adb33f1234567890abcdef1234567890abcdef',
},
],
},
].map(makeEvent);

// Do not add new events to this array, add it to `events` list.
Expand Down
35 changes: 35 additions & 0 deletions web/packages/teleport/src/services/audit/makeEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1914,6 +1914,41 @@ export const formatters: Formatters = {
format: ({ unknown_type, unknown_code }) =>
`Unknown '${unknown_type}' event (${unknown_code})`,
},
[eventCodes.GIT_COMMAND]: {
type: 'git.command',
desc: 'Git Command',
format: ({ user, service, path, actions }) => {
// "git-upload-pack" are fetches like "git fetch", "git pull".
if (service === 'git-upload-pack') {
return `User [${user}] has fetched from [${path}]`;
}
// "git-receive-pack" are pushes. Usually it should have one action.
if (service === 'git-receive-pack') {
if (actions && actions.length == 1) {
switch (actions[0].action) {
case 'delete':
return `User [${user}] has deleted [${actions[0].reference}] from [${path}]`;
case 'create':
return `User [${user}] has created [${actions[0].reference}] on [${path}]`;
case 'update':
return `User [${user}] has updated [${actions[0].reference}] to [${actions[0].new.substring(0, 7)}] on [${path}]`;
}
}
return `User [${user}] has attempted a push to [${path}]`;
}
if (service && path) {
return `User [${user}] has executed a Git Command [${service}] at [${path}]`;
}
return `User [${user}] has executed a Git Command`;
},
},
[eventCodes.GIT_COMMAND_FAILURE]: {
type: 'git.command',
desc: 'Git Command Failed',
format: ({ user, exitError, service, path }) => {
return `User [${user}] Git Command [${service}] at [${path}] failed [${exitError}]`;
},
},
};

const unknownFormatter = {
Expand Down
23 changes: 23 additions & 0 deletions web/packages/teleport/src/services/audit/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ export const eventCodes = {
PLUGIN_DELETE: 'PG003I',
CONTACT_CREATE: 'TCTC001I',
CONTACT_DELETE: 'TCTC002I',
GIT_COMMAND: 'TGIT001I',
GIT_COMMAND_FAILURE: 'TGIT001E',
} as const;

/**
Expand Down Expand Up @@ -1753,6 +1755,27 @@ export type RawEvents = {
contact_type: number;
}
>;
[eventCodes.GIT_COMMAND]: RawEvent<
typeof eventCodes.GIT_COMMAND,
{
service: string;
path: string;
actions?: {
action: string;
reference: string;
new?: string;
old?: string;
}[];
}
>;
[eventCodes.GIT_COMMAND_FAILURE]: RawEvent<
typeof eventCodes.GIT_COMMAND_FAILURE,
{
service: string;
path: string;
exitError: string;
}
>;
};

/**
Expand Down

0 comments on commit 576192d

Please sign in to comment.