Skip to content

Commit ef72cb0

Browse files
Codegen Image Security Hardening (#6461)
* refactor(codegen): add builder stage for Go plugins Signed-off-by: Mohammed Firdous <124298708+mohammedfirdouss@users.noreply.github.com> * feat(codegen): add downloader stage for pre-built binaries Signed-off-by: Mohammed Firdous <124298708+mohammedfirdouss@users.noreply.github.com> * feat(codegen): implement multi-stage Docker build for security hardening and reduced image size Signed-off-by: Mohammed Firdous <124298708+mohammedfirdouss@users.noreply.github.com> --------- Signed-off-by: Mohammed Firdous <124298708+mohammedfirdouss@users.noreply.github.com>
1 parent 367c15d commit ef72cb0

File tree

1 file changed

+94
-54
lines changed

1 file changed

+94
-54
lines changed

tool/codegen/Dockerfile

Lines changed: 94 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,102 @@
1-
# Builder image to build go program.
1+
# Stage 1: Builder - Build Go-based plugins
2+
23
FROM golang:1.25.2 AS builder
34

5+
# Version configuration
6+
ARG PROTOC_GEN_GO_VER=1.27.1
7+
ARG PROTOC_GEN_GO_GRPC_VER=1.2.0
8+
ARG PROTOC_GEN_VALIDATE_VER=0.6.6
9+
ARG GOMOCK_VER=0.6.0
10+
11+
# Build protoc-gen-auth from source
412
COPY protoc-gen-auth /protoc-gen-auth
513
RUN cd /protoc-gen-auth \
6-
&& go build -o /usr/local/bin/protoc-gen-auth . \
7-
&& chmod +x /usr/local/bin/protoc-gen-auth
8-
9-
# Codegen image which is actually being used.
10-
FROM golang:1.25.2
11-
12-
# This is version of protobuf installed in the image.
13-
# See https://pkgs.alpinelinux.org/packages?name=protobuf&branch=v3.16
14-
# NOTE: Start from protobuf v3.20.1, the protoc-gen-js is not included in protobuf package.
15-
ENV PROTOC_GEN_JS_VER=3.21.2
16-
ENV PROTOC_GEN_GO_VER=1.27.1
17-
ENV PROTOC_GEN_GRPC_WEB_VER=1.3.1
18-
ENV PROTOC_GEN_GO_GRPC_VER=1.2.0
19-
ENV PROTOC_GEN_VALIDATE_VER=0.6.6
20-
ENV GOMOCK_VER=0.6.0
21-
22-
# dependecies and protoc
23-
RUN apt update && apt install -y protobuf-compiler
24-
25-
# protoc-gen-go
26-
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v${PROTOC_GEN_GO_VER}
27-
28-
# protoc-gen-go-grpc
29-
RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v${PROTOC_GEN_GO_GRPC_VER}
30-
31-
# protoc-gen-grpc-web
32-
RUN wget https://github.com/grpc/grpc-web/releases/download/${PROTOC_GEN_GRPC_WEB_VER}/protoc-gen-grpc-web-${PROTOC_GEN_GRPC_WEB_VER}-linux-x86_64 \
33-
&& mv protoc-gen-grpc-web-${PROTOC_GEN_GRPC_WEB_VER}-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web \
34-
&& chmod +x /usr/local/bin/protoc-gen-grpc-web
35-
36-
# protoc-gen-validate
37-
RUN go install github.com/envoyproxy/protoc-gen-validate@v${PROTOC_GEN_VALIDATE_VER} \
38-
&& wget -q https://github.com/envoyproxy/protoc-gen-validate/archive/refs/tags/v${PROTOC_GEN_VALIDATE_VER}.tar.gz -O protoc-gen-validate.tar.gz \
39-
&& mkdir -p /go/src/github.com/envoyproxy \
40-
&& tar xvfz protoc-gen-validate.tar.gz -C /go/src/github.com/envoyproxy \
41-
&& rm protoc-gen-validate.tar.gz \
42-
&& mv /go/src/github.com/envoyproxy/protoc-gen-validate-${PROTOC_GEN_VALIDATE_VER} /go/src/github.com/envoyproxy/protoc-gen-validate
43-
44-
# protoc-gen-js
45-
# This is a workaround to use it https://github.com/protocolbuffers/protobuf-javascript/issues/127#issuecomment-1361047597
14+
&& go build -o /out/protoc-gen-auth . \
15+
&& chmod +x /out/protoc-gen-auth
16+
17+
# Install Go-based protoc plugins
18+
RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v${PROTOC_GEN_GO_VER} \
19+
&& go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v${PROTOC_GEN_GO_GRPC_VER} \
20+
&& go install github.com/envoyproxy/protoc-gen-validate@v${PROTOC_GEN_VALIDATE_VER} \
21+
&& go install go.uber.org/mock/mockgen@v${GOMOCK_VER}
22+
23+
# Copy built binaries to output directory
24+
RUN mkdir -p /out \
25+
&& cp /go/bin/protoc-gen-go /out/ \
26+
&& cp /go/bin/protoc-gen-go-grpc /out/ \
27+
&& cp /go/bin/protoc-gen-validate /out/ \
28+
&& cp /go/bin/mockgen /out/
29+
30+
# Download protoc-gen-validate proto files (needed for validate imports)
31+
RUN wget -q https://github.com/envoyproxy/protoc-gen-validate/archive/refs/tags/v${PROTOC_GEN_VALIDATE_VER}.tar.gz -O /tmp/validate.tar.gz \
32+
&& mkdir -p /out/validate-protos \
33+
&& tar xzf /tmp/validate.tar.gz -C /out/validate-protos --strip-components=1 \
34+
&& rm /tmp/validate.tar.gz
35+
36+
# Stage 2: Downloader - Download pre-built binaries
37+
38+
FROM debian:bookworm-slim AS downloader
39+
40+
RUN apt-get update && apt-get install -y --no-install-recommends wget ca-certificates \
41+
&& rm -rf /var/lib/apt/lists/*
42+
43+
# Download protoc-gen-grpc-web
44+
ARG PROTOC_GEN_GRPC_WEB_VER=1.3.1
45+
RUN wget -q https://github.com/grpc/grpc-web/releases/download/${PROTOC_GEN_GRPC_WEB_VER}/protoc-gen-grpc-web-${PROTOC_GEN_GRPC_WEB_VER}-linux-x86_64 \
46+
-O /protoc-gen-grpc-web \
47+
&& chmod +x /protoc-gen-grpc-web
48+
49+
# Download protoc-gen-js for both architectures
50+
# This is a workaround: https://github.com/protocolbuffers/protobuf-javascript/issues/127#issuecomment-1361047597
51+
52+
ARG PROTOC_GEN_JS_VER=3.21.2
4653
RUN for target in x86_64 aarch_64; do \
47-
mkdir /protoc-gen-js-${target} && cd /protoc-gen-js-${target} \
48-
&& wget https://github.com/protocolbuffers/protobuf-javascript/releases/download/v${PROTOC_GEN_JS_VER}/protobuf-javascript-${PROTOC_GEN_JS_VER}-linux-${target}.tar.gz \
49-
&& tar xvfz protobuf-javascript-${PROTOC_GEN_JS_VER}-linux-${target}.tar.gz \
50-
&& chmod +x bin/protoc-gen-js \
51-
&& rm -rf protobuf-javascript-${PROTOC_GEN_JS_VER}-linux-${target}.tar.gz; \
52-
done && \
53-
mv /protoc-gen-js-aarch_64/ /protoc-gen-js-aarch64/
54-
55-
# protoc-gen-auth
56-
COPY --from=builder /usr/local/bin/protoc-gen-auth /usr/local/bin/
57-
58-
# gomock
59-
RUN go install go.uber.org/mock/mockgen@v${GOMOCK_VER}
54+
mkdir -p /protoc-gen-js-${target} \
55+
&& wget -q https://github.com/protocolbuffers/protobuf-javascript/releases/download/v${PROTOC_GEN_JS_VER}/protobuf-javascript-${PROTOC_GEN_JS_VER}-linux-${target}.tar.gz \
56+
&& tar xzf protobuf-javascript-${PROTOC_GEN_JS_VER}-linux-${target}.tar.gz -C /protoc-gen-js-${target} \
57+
&& chmod +x /protoc-gen-js-${target}/bin/protoc-gen-js \
58+
&& rm protobuf-javascript-${PROTOC_GEN_JS_VER}-linux-${target}.tar.gz; \
59+
done \
60+
&& mv /protoc-gen-js-aarch_64 /protoc-gen-js-aarch64
61+
62+
63+
# Stage 3: Final - Minimal runtime image
64+
FROM debian:bookworm-slim AS final
65+
66+
# Install protoc, proto files, and ca-certificates
67+
# libprotobuf-dev includes standard proto files in /usr/include/google/protobuf/
68+
RUN apt-get update \
69+
&& apt-get install -y --no-install-recommends \
70+
protobuf-compiler \
71+
libprotobuf-dev \
72+
ca-certificates \
73+
git \
74+
&& rm -rf /var/lib/apt/lists/*
75+
76+
# Copy Go runtime from golang image
77+
# mockgen uses 'go list' and 'go build' internally
78+
COPY --from=golang:1.25.2 /usr/local/go /usr/local/go
79+
ENV GOROOT=/usr/local/go
80+
ENV GOPATH=/go
81+
ENV PATH=$GOPATH/bin:$GOROOT/bin:$PATH
82+
83+
# Create necessary directories
84+
RUN mkdir -p /go/bin /go/src/github.com/envoyproxy
85+
86+
# Copy built Go plugins from builder
87+
COPY --from=builder /out/protoc-gen-go /go/bin/
88+
COPY --from=builder /out/protoc-gen-go-grpc /go/bin/
89+
COPY --from=builder /out/protoc-gen-validate /go/bin/
90+
COPY --from=builder /out/mockgen /go/bin/
91+
COPY --from=builder /out/protoc-gen-auth /usr/local/bin/
92+
93+
# Copy validate proto files (needed for -I include path in codegen.sh)
94+
COPY --from=builder /out/validate-protos /go/src/github.com/envoyproxy/protoc-gen-validate
95+
96+
# Copy downloaded binaries from downloader
97+
COPY --from=downloader /protoc-gen-grpc-web /usr/local/bin/
98+
COPY --from=downloader /protoc-gen-js-x86_64 /protoc-gen-js-x86_64
99+
COPY --from=downloader /protoc-gen-js-aarch64 /protoc-gen-js-aarch64
60100

61101
VOLUME /repo
62102
WORKDIR /repo

0 commit comments

Comments
 (0)