From 561ae62c4c22f0074aea4004583cbce6278435ca Mon Sep 17 00:00:00 2001 From: Jordan McClintock Date: Thu, 16 Apr 2026 20:05:36 +0000 Subject: [PATCH] feat(grpc): add configurable maximum size limit for received gRPC messages Signed-off-by: Jordan McClintock --- .../conf/controlplane/config/v1/conf.pb.go | 31 +++++++++++++------ .../conf/controlplane/config/v1/conf.proto | 3 ++ app/controlplane/internal/server/grpc.go | 15 ++++++--- deployment/chainloop/Chart.yaml | 2 +- .../templates/controlplane/configmap.yaml | 3 ++ deployment/chainloop/values.yaml | 3 ++ 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/app/controlplane/internal/conf/controlplane/config/v1/conf.pb.go b/app/controlplane/internal/conf/controlplane/config/v1/conf.pb.go index 2c509046b..93b76c989 100644 --- a/app/controlplane/internal/conf/controlplane/config/v1/conf.pb.go +++ b/app/controlplane/internal/conf/controlplane/config/v1/conf.pb.go @@ -1264,13 +1264,16 @@ func (x *Server_TLS) GetPrivateKey() string { } type Server_GRPC struct { - state protoimpl.MessageState `protogen:"open.v1"` - Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"` - Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"` - Timeout *durationpb.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"` - TlsConfig *Server_TLS `protobuf:"bytes,4,opt,name=tls_config,json=tlsConfig,proto3" json:"tls_config,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"` + Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"` + Timeout *durationpb.Duration `protobuf:"bytes,3,opt,name=timeout,proto3" json:"timeout,omitempty"` + TlsConfig *Server_TLS `protobuf:"bytes,4,opt,name=tls_config,json=tlsConfig,proto3" json:"tls_config,omitempty"` + // Maximum size in bytes of received gRPC messages. + // Defaults to 4MB (4194304) if not set. Use this to allow larger attestations. + MaxRecvMsgSize int32 `protobuf:"varint,5,opt,name=max_recv_msg_size,json=maxRecvMsgSize,proto3" json:"max_recv_msg_size,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *Server_GRPC) Reset() { @@ -1331,6 +1334,13 @@ func (x *Server_GRPC) GetTlsConfig() *Server_TLS { return nil } +func (x *Server_GRPC) GetMaxRecvMsgSize() int32 { + if x != nil { + return x.MaxRecvMsgSize + } + return 0 +} + type Data_Database struct { state protoimpl.MessageState `protogen:"open.v1"` Driver string `protobuf:"bytes,1,opt,name=driver,proto3" json:"driver,omitempty"` @@ -1696,7 +1706,7 @@ const file_controlplane_config_v1_conf_proto_rawDesc = "" + "\x03url\x18\x04 \x01(\tR\x03url\"R\n" + "\x13ReferrerSharedIndex\x12\x18\n" + "\aenabled\x18\x01 \x01(\bR\aenabled\x12!\n" + - "\fallowed_orgs\x18\x02 \x03(\tR\vallowedOrgs\"\xd3\x04\n" + + "\fallowed_orgs\x18\x02 \x03(\tR\vallowedOrgs\"\xfe\x04\n" + "\x06Server\x127\n" + "\x04http\x18\x01 \x01(\v2#.controlplane.config.v1.Server.HTTPR\x04http\x127\n" + "\x04grpc\x18\x02 \x01(\v2#.controlplane.config.v1.Server.GRPCR\x04grpc\x12F\n" + @@ -1709,13 +1719,14 @@ const file_controlplane_config_v1_conf_proto_rawDesc = "" + "\x03TLS\x12 \n" + "\vcertificate\x18\x01 \x01(\tR\vcertificate\x12\x1f\n" + "\vprivate_key\x18\x02 \x01(\tR\n" + - "privateKey\x1a\xb5\x01\n" + + "privateKey\x1a\xe0\x01\n" + "\x04GRPC\x12\x18\n" + "\anetwork\x18\x01 \x01(\tR\anetwork\x12\x1b\n" + "\x04addr\x18\x02 \x01(\tB\a\xbaH\x04r\x02\x10\x01R\x04addr\x123\n" + "\atimeout\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\atimeout\x12A\n" + "\n" + - "tls_config\x18\x04 \x01(\v2\".controlplane.config.v1.Server.TLSR\ttlsConfig\"\x9a\x02\n" + + "tls_config\x18\x04 \x01(\v2\".controlplane.config.v1.Server.TLSR\ttlsConfig\x12)\n" + + "\x11max_recv_msg_size\x18\x05 \x01(\x05R\x0emaxRecvMsgSize\"\x9a\x02\n" + "\x04Data\x12A\n" + "\bdatabase\x18\x01 \x01(\v2%.controlplane.config.v1.Data.DatabaseR\bdatabase\x1a\xce\x01\n" + "\bDatabase\x12\x16\n" + diff --git a/app/controlplane/internal/conf/controlplane/config/v1/conf.proto b/app/controlplane/internal/conf/controlplane/config/v1/conf.proto index 22b6032e1..39b62d36b 100644 --- a/app/controlplane/internal/conf/controlplane/config/v1/conf.proto +++ b/app/controlplane/internal/conf/controlplane/config/v1/conf.proto @@ -174,6 +174,9 @@ message Server { string addr = 2 [(buf.validate.field).string.min_len = 1]; google.protobuf.Duration timeout = 3; TLS tls_config = 4; + // Maximum size in bytes of received gRPC messages. + // Defaults to 4MB (4194304) if not set. Use this to allow larger attestations. + int32 max_recv_msg_size = 5; } HTTP http = 1; diff --git a/app/controlplane/internal/server/grpc.go b/app/controlplane/internal/server/grpc.go index 97c7960bc..610ae4437 100644 --- a/app/controlplane/internal/server/grpc.go +++ b/app/controlplane/internal/server/grpc.go @@ -48,6 +48,7 @@ import ( "github.com/go-kratos/kratos/v2/transport/grpc" protovalidateMiddleware "github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors/protovalidate" grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" + grpcLib "google.golang.org/grpc" ) type Opts struct { @@ -89,14 +90,14 @@ type Opts struct { GroupSvc *service.GroupService ProjectSvc *service.ProjectService // Utils - Logger log.Logger - ServerConfig *conf.Server - AuthConfig *conf.Auth + Logger log.Logger + ServerConfig *conf.Server + AuthConfig *conf.Auth FederatedConfig *conf.FederatedAuthentication OperationAuthConfig *conf.OperationAuthorizationProvider BootstrapConfig *conf.Bootstrap - Credentials credentials.ReaderWriter - Validator protovalidate.Validator + Credentials credentials.ReaderWriter + Validator protovalidate.Validator } var ( @@ -146,6 +147,10 @@ func NewGRPCServer(opts *Opts) (*grpc.Server, error) { } } + if v := opts.ServerConfig.Grpc.GetMaxRecvMsgSize(); v > 0 { + serverOpts = append(serverOpts, grpc.Options(grpcLib.MaxRecvMsgSize(int(v)))) + } + srv := grpc.NewServer(serverOpts...) v1.RegisterWorkflowServiceServer(srv, opts.WorkflowSvc) v1.RegisterStatusServiceServer(srv, service.NewStatusService(opts.AuthSvc.AuthURLs.Login, Version, opts.CASClientUseCase, opts.BootstrapConfig)) diff --git a/deployment/chainloop/Chart.yaml b/deployment/chainloop/Chart.yaml index c4721f014..f1ff15ab9 100644 --- a/deployment/chainloop/Chart.yaml +++ b/deployment/chainloop/Chart.yaml @@ -7,7 +7,7 @@ description: Chainloop is an open source software supply chain control plane, a type: application # Bump the patch (not minor, not major) version on each change in the Chart Source code -version: 1.369.0 +version: 1.369.1 # Do not update appVersion, this is handled automatically by the release process appVersion: v1.93.2 diff --git a/deployment/chainloop/templates/controlplane/configmap.yaml b/deployment/chainloop/templates/controlplane/configmap.yaml index 97182bcf5..7e7a991fa 100644 --- a/deployment/chainloop/templates/controlplane/configmap.yaml +++ b/deployment/chainloop/templates/controlplane/configmap.yaml @@ -31,6 +31,9 @@ data: grpc: addr: "0.0.0.0:{{ .Values.controlplane.containerPorts.grpc }}" timeout: 10s + {{- if .Values.controlplane.grpcMaxRecvMsgSize }} + max_recv_msg_size: {{ .Values.controlplane.grpcMaxRecvMsgSize }} + {{- end }} {{- if include "controlplane.tls-secret-name" . }} tls_config: certificate: /data/server-certs/tls.crt diff --git a/deployment/chainloop/values.yaml b/deployment/chainloop/values.yaml index 320e76afc..d2b773b0c 100644 --- a/deployment/chainloop/values.yaml +++ b/deployment/chainloop/values.yaml @@ -141,6 +141,9 @@ controlplane: tag: "v1.93.2" + ## @param controlplane.grpcMaxRecvMsgSize Maximum size in bytes of received gRPC messages. Increase to allow larger attestations. Defaults to the gRPC standard 4MB (4194304) if not set. + grpcMaxRecvMsgSize: "" + ## @param controlplane.containerPorts.http controlplane HTTP container port ## @param controlplane.containerPorts.grpc controlplane gRPC container port ## @param controlplane.containerPorts.metrics controlplane prometheus metrics container port