Skip to content
Open
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
8 changes: 4 additions & 4 deletions Dockerfile.gcp-pd
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
FROM registry.ci.openshift.org/ocp/builder:rhel-9-golang-1.26-openshift-5.0 AS builder
WORKDIR /go/src/github.com/openshift/gcp-pd-csi-driver-operator
COPY legacy/gcp-pd-csi-driver-operator .
RUN make
WORKDIR /go/src/github.com/openshift/csi-operator
COPY . .

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Do not copy the entire build context.

COPY . . places every repository file into the builder stage, potentially including secrets, credentials, and unrelated artifacts. Copy only the manifests and source directories required by this build target.

As per path instructions, “COPY specific files, not entire context.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Dockerfile.gcp-pd` at line 3, Replace the broad COPY . . instruction in the
Dockerfile build stage with explicit COPY directives for only the manifests and
source directories required by this build target. Exclude secrets, credentials,
build artifacts, and unrelated repository files from the builder context.

Source: Path instructions

RUN make GO_BUILD_PACKAGES=./cmd/gcp-pd-csi-driver-operator

FROM registry.ci.openshift.org/ocp/5.0:base-rhel9
COPY --from=builder /go/src/github.com/openshift/gcp-pd-csi-driver-operator/gcp-pd-csi-driver-operator /usr/bin/
COPY --from=builder /go/src/github.com/openshift/csi-operator/bin/gcp-pd-csi-driver-operator /usr/bin/
ENTRYPOINT ["/usr/bin/gcp-pd-csi-driver-operator"]
LABEL io.k8s.display-name="OpenShift GCP PD CSI Driver Operator" \
io.k8s.description="The GCP PD CSI Driver Operator installs and maintains the GCP PD CSI Driver on a cluster."
Comment on lines 6 to 10

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Missing non-root USER directive in final image.

The final stage runs the operator without setting a non-root USER, so the container defaults to root. As per path instructions, "USER non-root; never run as root."

🔒 Proposed fix
 FROM registry.ci.openshift.org/ocp/5.0:base-rhel9
 COPY --from=builder /go/src/github.com/openshift/csi-operator/bin/gcp-pd-csi-driver-operator /usr/bin/
+USER 65532:65532
 ENTRYPOINT ["/usr/bin/gcp-pd-csi-driver-operator"]
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
FROM registry.ci.openshift.org/ocp/5.0:base-rhel9
COPY --from=builder /go/src/github.com/openshift/gcp-pd-csi-driver-operator/gcp-pd-csi-driver-operator /usr/bin/
COPY --from=builder /go/src/github.com/openshift/csi-operator/bin/gcp-pd-csi-driver-operator /usr/bin/
ENTRYPOINT ["/usr/bin/gcp-pd-csi-driver-operator"]
LABEL io.k8s.display-name="OpenShift GCP PD CSI Driver Operator" \
io.k8s.description="The GCP PD CSI Driver Operator installs and maintains the GCP PD CSI Driver on a cluster."
FROM registry.ci.openshift.org/ocp/5.0:base-rhel9
COPY --from=builder /go/src/github.com/openshift/csi-operator/bin/gcp-pd-csi-driver-operator /usr/bin/
USER 65532:65532
ENTRYPOINT ["/usr/bin/gcp-pd-csi-driver-operator"]
LABEL io.k8s.display-name="OpenShift GCP PD CSI Driver Operator" \
io.k8s.description="The GCP PD CSI Driver Operator installs and maintains the GCP PD CSI Driver on a cluster."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Dockerfile.gcp-pd` around lines 6 - 10, Update the final image stage in the
Dockerfile around the gcp-pd-csi-driver-operator ENTRYPOINT to add a non-root
USER directive, ensuring the operator runs as non-root while preserving the
existing image metadata and startup command.

Source: Path instructions

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gcp-pd-controller-privileged-binding
subjects:
- kind: ServiceAccount
name: gcp-pd-csi-driver-controller-sa
namespace: openshift-cluster-csi-drivers
roleRef:
kind: ClusterRole
name: gcp-pd-privileged-role
apiGroup: rbac.authorization.k8s.io
7 changes: 7 additions & 0 deletions assets/overlays/gcp-pd/generated/standalone/cabundle_cm.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
labels:
config.openshift.io/inject-trusted-cabundle: "true"
name: gcp-pd-csi-driver-trusted-ca-bundle
namespace: openshift-cluster-csi-drivers
331 changes: 331 additions & 0 deletions assets/overlays/gcp-pd/generated/standalone/controller.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
kind: Deployment
apiVersion: apps/v1
metadata:
name: gcp-pd-csi-driver-controller
namespace: openshift-cluster-csi-drivers
annotations:
config.openshift.io/inject-proxy: csi-driver
config.openshift.io/inject-proxy-cabundle: csi-driver
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 0
selector:
matchLabels:
app: gcp-pd-csi-driver-controller
template:
metadata:
labels:
app: gcp-pd-csi-driver-controller
annotations:
openshift.io/required-scc: hostnetwork-v2
target.workload.openshift.io/management: '{"effect": "PreferredDuringScheduling"}'
spec:
hostNetwork: true
serviceAccountName: gcp-pd-csi-driver-controller-sa
priorityClassName: system-cluster-critical
nodeSelector:
node-role.kubernetes.io/master: ""
tolerations:
- key: CriticalAddonsOnly
operator: Exists
- key: node-role.kubernetes.io/master
operator: Exists
effect: "NoSchedule"
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: gcp-pd-csi-driver-controller
topologyKey: kubernetes.io/hostname
containers:
- name: csi-driver
securityContext:
readOnlyRootFilesystem: true
image: ${DRIVER_IMAGE}
imagePullPolicy: IfNotPresent
args:
- --endpoint=$(CSI_ENDPOINT)
- --logtostderr
- --v=${LOG_LEVEL}
- --enable-storage-pools=true
- --allow-hdha-provisioning=true
- --supports-dynamic-throughput-provisioning=hyperdisk-balanced,hyperdisk-throughput,hyperdisk-ml
- --supports-dynamic-iops-provisioning=hyperdisk-balanced,hyperdisk-extreme
env:
- name: GOOGLE_APPLICATION_CREDENTIALS
value: "/etc/cloud-sa/service_account.json"
- name: CSI_ENDPOINT
value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock
ports:
- name: healthz
# Due to hostNetwork, this port is open on a node!
containerPort: 10301
protocol: TCP
livenessProbe:
httpGet:
path: /healthz
port: healthz
initialDelaySeconds: 10
timeoutSeconds: 3
periodSeconds: 10
failureThreshold: 5
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
- name: cloud-sa-volume
readOnly: true
mountPath: "/etc/cloud-sa"
- name: bound-sa-token
mountPath: /var/run/secrets/openshift/serviceaccount
readOnly: true
resources:
requests:
memory: 50Mi
cpu: 10m
- name: csi-provisioner
securityContext:
readOnlyRootFilesystem: true
image: ${PROVISIONER_IMAGE}
imagePullPolicy: IfNotPresent
args:
- --csi-address=$(ADDRESS)
- --default-fstype=ext4
- --feature-gates=Topology=true
- --extra-create-metadata=true
- --http-endpoint=localhost:8202
- --timeout=250s
- --leader-election
- --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION}
- --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE}
- --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD}
- --controller-publish-readonly
- --v=${LOG_LEVEL}
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
resources:
requests:
memory: 50Mi
cpu: 10m
# kube-rbac-proxy for external-provisioner container.
# Provides https proxy for http-based external-provisioner metrics.
- name: provisioner-kube-rbac-proxy
securityContext:
readOnlyRootFilesystem: true
args:
- --secure-listen-address=0.0.0.0:9202
- --upstream=http://127.0.0.1:8202/
- --tls-cert-file=/etc/tls/private/tls.crt
- --tls-private-key-file=/etc/tls/private/tls.key
- --tls-cipher-suites=${TLS_CIPHER_SUITES}
- --tls-min-version=${TLS_MIN_VERSION}
- --logtostderr=true
image: ${KUBE_RBAC_PROXY_IMAGE}
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9202
name: provisioner-m
protocol: TCP
resources:
requests:
memory: 20Mi
cpu: 10m
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /etc/tls/private
name: metrics-serving-cert
- name: csi-attacher
securityContext:
readOnlyRootFilesystem: true
image: ${ATTACHER_IMAGE}
imagePullPolicy: IfNotPresent
args:
- --csi-address=$(ADDRESS)
- --http-endpoint=localhost:8203
- --leader-election
- --timeout=250s
- --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION}
- --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE}
- --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD}
- --v=${LOG_LEVEL}
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
resources:
requests:
memory: 50Mi
cpu: 10m
- name: attacher-kube-rbac-proxy
securityContext:
readOnlyRootFilesystem: true
args:
- --secure-listen-address=0.0.0.0:9203
- --upstream=http://127.0.0.1:8203/
- --tls-cert-file=/etc/tls/private/tls.crt
- --tls-private-key-file=/etc/tls/private/tls.key
- --tls-cipher-suites=${TLS_CIPHER_SUITES}
- --tls-min-version=${TLS_MIN_VERSION}
- --logtostderr=true
image: ${KUBE_RBAC_PROXY_IMAGE}
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9203
name: attacher-m
protocol: TCP
resources:
requests:
memory: 20Mi
cpu: 10m
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /etc/tls/private
name: metrics-serving-cert
- name: csi-resizer
securityContext:
readOnlyRootFilesystem: true
image: ${RESIZER_IMAGE}
imagePullPolicy: IfNotPresent
args:
- --csi-address=$(ADDRESS)
- --http-endpoint=localhost:8204
- --leader-election
- --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION}
- --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE}
- --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD}
- --v=${LOG_LEVEL}
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- name: socket-dir
mountPath: /var/lib/csi/sockets/pluginproxy/
resources:
requests:
memory: 50Mi
cpu: 10m
- name: resizer-kube-rbac-proxy
securityContext:
readOnlyRootFilesystem: true
args:
- --secure-listen-address=0.0.0.0:9204
- --upstream=http://127.0.0.1:8204/
- --tls-cert-file=/etc/tls/private/tls.crt
- --tls-private-key-file=/etc/tls/private/tls.key
- --tls-cipher-suites=${TLS_CIPHER_SUITES}
- --tls-min-version=${TLS_MIN_VERSION}
- --logtostderr=true
image: ${KUBE_RBAC_PROXY_IMAGE}
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9204
name: resizer-m
protocol: TCP
resources:
requests:
memory: 20Mi
cpu: 10m
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /etc/tls/private
name: metrics-serving-cert
- name: csi-snapshotter
securityContext:
readOnlyRootFilesystem: true
image: ${SNAPSHOTTER_IMAGE}
imagePullPolicy: IfNotPresent
args:
- --csi-address=$(ADDRESS)
- --metrics-address=localhost:8205
- --leader-election
- --timeout=300s
- --leader-election-lease-duration=${LEADER_ELECTION_LEASE_DURATION}
- --leader-election-renew-deadline=${LEADER_ELECTION_RENEW_DEADLINE}
- --leader-election-retry-period=${LEADER_ELECTION_RETRY_PERIOD}
- --v=${LOG_LEVEL}
env:
- name: ADDRESS
value: /var/lib/csi/sockets/pluginproxy/csi.sock
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /var/lib/csi/sockets/pluginproxy/
name: socket-dir
resources:
requests:
memory: 50Mi
cpu: 10m
- name: snapshotter-kube-rbac-proxy
securityContext:
readOnlyRootFilesystem: true
args:
- --secure-listen-address=0.0.0.0:9205
- --upstream=http://127.0.0.1:8205/
- --tls-cert-file=/etc/tls/private/tls.crt
- --tls-private-key-file=/etc/tls/private/tls.key
- --tls-cipher-suites=${TLS_CIPHER_SUITES}
- --tls-min-version=${TLS_MIN_VERSION}
- --logtostderr=true
image: ${KUBE_RBAC_PROXY_IMAGE}
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9205
name: snapshotter-m
protocol: TCP
resources:
requests:
memory: 20Mi
cpu: 10m
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- mountPath: /etc/tls/private
name: metrics-serving-cert
- name: csi-liveness-probe
securityContext:
readOnlyRootFilesystem: true
image: ${LIVENESS_PROBE_IMAGE}
imagePullPolicy: IfNotPresent
args:
- --csi-address=/csi/csi.sock
- --probe-timeout=3s
- --health-port=10301
- --v=${LOG_LEVEL}
terminationMessagePolicy: FallbackToLogsOnError
volumeMounts:
- name: socket-dir
mountPath: /csi
resources:
requests:
memory: 50Mi
cpu: 10m
volumes:
- name: socket-dir
emptyDir: {}
- name: cloud-sa-volume
secret:
secretName: gcp-pd-cloud-credentials
- name: metrics-serving-cert
secret:
secretName: gcp-pd-csi-driver-controller-metrics-serving-cert
# This service account token can be used to provide identity outside the cluster.
# For example, this token can be used to authenticate with GCP using workload identity.
- name: bound-sa-token
projected:
sources:
- serviceAccountToken:
path: token
audience: openshift
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: gcp-pd-controller-hostnetwork-binding
subjects:
- kind: ServiceAccount
name: gcp-pd-csi-driver-controller-sa
namespace: openshift-cluster-csi-drivers
roleRef:
kind: ClusterRole
name: gcp-pd-hostnetwork-role
apiGroup: rbac.authorization.k8s.io
11 changes: 11 additions & 0 deletions assets/overlays/gcp-pd/generated/standalone/controller_pdb.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: gcp-pd-csi-driver-controller-pdb
namespace: openshift-cluster-csi-drivers
spec:
maxUnavailable: 1
selector:
matchLabels:
app: gcp-pd-csi-driver-controller
unhealthyPodEvictionPolicy: AlwaysAllow
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: gcp-pd-csi-driver-controller-sa
namespace: openshift-cluster-csi-drivers
Loading