Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions api/proto/teleport/legacy/types/events/events.proto
Original file line number Diff line number Diff line change
Expand Up @@ -4885,6 +4885,8 @@ message OneOf {
events.BoundKeypairRecovery BoundKeypairRecovery = 220;
events.BoundKeypairRotation BoundKeypairRotation = 221;
events.BoundKeypairJoinStateVerificationFailed BoundKeypairJoinStateVerificationFailed = 222;
events.MCPSessionListenSSEStream MCPSessionListenSSEStream = 223;
events.MCPSessionInvalidHTTPRequest MCPSessionInvalidHTTPRequest = 224;
}
}

Expand Down Expand Up @@ -8714,6 +8716,16 @@ message MCPSessionEnd {
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// Status contains common command or operation status fields.
//
// The protocol spec states that the MCP server may refuse the clients from
// terminating the session.
// https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#session-management
Status Status = 7 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
}

// MCPJSONRPCMessage includes details of a MCP request or notification.
Expand Down Expand Up @@ -8803,6 +8815,92 @@ message MCPSessionNotification {
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "message,omitempty"
];
// Status contains information whether the request is successful or not.
Status status = 6 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
}

// MCPSessionListenSSEStream is emitted when client sends a GET request to a
// streamable HTTP MCP server for listening server notifications via a SSE
// stream.
message MCPSessionListenSSEStream {
// 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) = ""
];
// SessionMetadata is a common event session metadata
SessionMetadata session = 3 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// App is a common application resource metadata.
AppMetadata app = 4 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// Status contains information whether the request is successful or not.
Status status = 5 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
}

// MCPSessionInvalidHTTPRequest is a blanket event for all requests that we do
// not understand (usually out of MCP spec).
message MCPSessionInvalidHTTPRequest {
// 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) = ""
];
// SessionMetadata is a common event session metadata
SessionMetadata session = 3 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];
// App is a common application resource metadata.
AppMetadata app = 4 [
(gogoproto.nullable) = false,
(gogoproto.embed) = true,
(gogoproto.jsontag) = ""
];

// Path is relative path in the URL.
string path = 5 [(gogoproto.jsontag) = "path"];
// Method is the request HTTP method, like GET/POST/DELETE/etc.
string method = 6 [(gogoproto.jsontag) = "method"];
// RawQuery are the encoded query values.
string raw_query = 7 [(gogoproto.jsontag) = "raw_query"];
// Body is the request HTTP body.
bytes body = 8 [(gogoproto.jsontag) = "body"];
// Headers are the HTTP request headers.
wrappers.LabelValues headers = 9 [
(gogoproto.nullable) = false,
(gogoproto.jsontag) = "headers,omitempty",
(gogoproto.customtype) = "github.com/gravitational/teleport/api/types/wrappers.Traits"
];
}

// BoundKeypairRecovery is emitted when a client performs a self recovery using
Expand Down
31 changes: 31 additions & 0 deletions api/types/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2601,6 +2601,37 @@ func (m *MCPSessionNotification) TrimToMaxSize(maxSize int) AuditEvent {
return out
}

func (m *MCPSessionListenSSEStream) TrimToMaxSize(maxSize int) AuditEvent {
return m
}

func (m *MCPSessionInvalidHTTPRequest) TrimToMaxSize(maxSize int) AuditEvent {
size := m.Size()
if size <= maxSize {
return m
}

out := utils.CloneProtoMsg(m)
out.Path = ""
out.RawQuery = ""
out.Headers = nil
out.Body = nil

maxSize = adjustedMaxSize(out, maxSize)

customFieldsCount := nonEmptyStrs(m.Path, m.RawQuery) + nonEmptyTraits(m.Headers)
if len(m.Body) != 0 {
customFieldsCount++
}
maxFieldsSize := maxSizePerField(maxSize, customFieldsCount)

out.Path = trimStr(m.Path, maxFieldsSize)
out.RawQuery = trimStr(m.RawQuery, maxFieldsSize)
out.Body = []byte(trimStr(string(m.Body), maxFieldsSize))
out.Headers = trimTraits(m.Headers, maxFieldsSize)
return out
}

func (m *BoundKeypairRecovery) TrimToMaxSize(maxSize int) AuditEvent {
size := m.Size()
if size <= maxSize {
Expand Down
Loading
Loading