From bfc1292b4468c2a4f834d57982b8db1c7649ee39 Mon Sep 17 00:00:00 2001 From: Siddhi Bhor Date: Tue, 4 Aug 2026 16:14:19 +0530 Subject: [PATCH 1/2] add tls scanner --- ...nshift-external-secrets-operator-main.yaml | 134 ++++++++++++++++++ ...rnal-secrets-operator-main-presubmits.yaml | 88 ++++++++++++ 2 files changed, 222 insertions(+) diff --git a/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml b/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml index cc2fdf907af21..24033ed2702dc 100644 --- a/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml +++ b/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml @@ -3,6 +3,10 @@ base_images: name: "4.22" namespace: ocp tag: base-rhel9 + cli-operator-sdk: + name: cli-operator-sdk + namespace: ocp + tag: v1.39.2 nested-podman: name: nested-podman namespace: ci @@ -11,6 +15,10 @@ base_images: name: "4.19" namespace: origin tag: operator-sdk + tls-scanner-tool: + name: tls-scanner + namespace: tls-scanner + tag: tls-scanner-tool binary_build_commands: make build build_root: from_repository: true @@ -247,6 +255,132 @@ tests: requests: cpu: 100m workflow: generic-claim +- always_run: false + as: tls-scanner + optional: true + steps: + cluster_profile: openshift-org-aws + dependencies: + OO_BUNDLE: external-secrets-operator-bundle + env: + OO_INSTALL_MODE: AllNamespaces + OO_INSTALL_NAMESPACE: external-secrets-operator + OO_SECURITY_CONTEXT: restricted + SCAN_NAMESPACE: external-secrets-operator,external-secrets + SCANNER_CPU: "1" + SCANNER_MEMORY: 1Gi + TLS_13_ENABLE_TLS_ADHERENCE: "true" + TLS_13_TLS_ADHERENCE_POLICY: StrictAllComponents + test: + - ref: tls-13 + - as: deploy-operand + cli: latest + commands: |- + set -o errexit + set -o nounset + set -o pipefail + + echo "Waiting for external-secrets-operator controller-manager..." + oc wait --for=condition=Available -n external-secrets-operator deployment/external-secrets-operator-controller-manager --timeout=5m + + echo "Creating ExternalSecretsConfig CR to trigger operand deployment..." + oc apply -f - </dev/null; then + echo "Namespace external-secrets found" + break + fi + echo "Waiting for namespace (attempt ${i}/60)..." + sleep 5 + done + + echo "Waiting for external-secrets operand deployments..." + oc wait --for=create -n external-secrets deployment/external-secrets --timeout=5m + oc wait --for=create -n external-secrets deployment/external-secrets-webhook --timeout=5m + oc wait --for=create -n external-secrets deployment/external-secrets-cert-controller --timeout=5m + oc wait --for=condition=Available -n external-secrets deployment/external-secrets --timeout=5m + oc wait --for=condition=Available -n external-secrets deployment/external-secrets-webhook --timeout=5m + oc wait --for=condition=Available -n external-secrets deployment/external-secrets-cert-controller --timeout=5m + + echo "Verifying webhook TLS endpoint is live..." + WEBHOOK_SVC=$(oc get validatingwebhookconfigurations -l app=external-secrets -o jsonpath='{.items[0].webhooks[0].clientConfig.service.name}' 2>/dev/null || true) + WEBHOOK_NS=$(oc get validatingwebhookconfigurations -l app=external-secrets -o jsonpath='{.items[0].webhooks[0].clientConfig.service.namespace}' 2>/dev/null || true) + if [[ -n "${WEBHOOK_SVC}" && -n "${WEBHOOK_NS}" ]]; then + WEBHOOK_PORT=$(oc get validatingwebhookconfigurations -l app=external-secrets -o jsonpath='{.items[0].webhooks[0].clientConfig.service.port}' 2>/dev/null || echo "443") + echo "Found webhook service: ${WEBHOOK_NS}/${WEBHOOK_SVC}:${WEBHOOK_PORT}" + oc get svc -n "${WEBHOOK_NS}" "${WEBHOOK_SVC}" || true + oc get endpoints -n "${WEBHOOK_NS}" "${WEBHOOK_SVC}" || true + else + echo "Warning: could not discover ValidatingWebhookConfiguration with label app=external-secrets" + oc get validatingwebhookconfigurations -o name || true + fi + + echo "Creating a test namespace with a SecretStore to exercise the webhook admission path..." + oc create namespace tls-scanner-exercise || true + oc apply -f - </dev/null || echo "Unknown") + if [[ "${STATUS}" == "True" ]]; then + echo "ExternalSecret reconciled successfully — webhook + controller TLS paths exercised" + break + fi + echo "ExternalSecret status: ${STATUS} (attempt ${i}/30)..." + sleep 5 + done + + echo "Listing all TLS-relevant services the scanner will probe:" + echo "--- external-secrets-operator namespace ---" + oc get svc -n external-secrets-operator -o wide 2>/dev/null || true + echo "--- external-secrets namespace ---" + oc get svc -n external-secrets -o wide 2>/dev/null || true + from: src + resources: + requests: + cpu: 100m + - ref: tls-scanner-run + workflow: optional-operators-ci-operator-sdk-aws zz_generated_metadata: branch: main org: openshift diff --git a/ci-operator/jobs/openshift/external-secrets-operator/openshift-external-secrets-operator-main-presubmits.yaml b/ci-operator/jobs/openshift/external-secrets-operator/openshift-external-secrets-operator-main-presubmits.yaml index 1d8cdd6a06b62..5a253bfad89be 100644 --- a/ci-operator/jobs/openshift/external-secrets-operator/openshift-external-secrets-operator-main-presubmits.yaml +++ b/ci-operator/jobs/openshift/external-secrets-operator/openshift-external-secrets-operator-main-presubmits.yaml @@ -475,6 +475,94 @@ presubmits: secret: secretName: result-aggregator trigger: (?m)^/test( | .* )images,?($|\s.*) + - agent: kubernetes + always_run: false + branches: + - ^main$ + - ^main- + cluster: build01 + context: ci/prow/tls-scanner + decorate: true + decoration_config: + sparse_checkout_files: + - .ci-operator.yaml + - images/ci/Dockerfile + - images/ci/Dockerfile.coverage + - images/ci/operand.Dockerfile + labels: + ci-operator.openshift.io/cloud: aws + ci-operator.openshift.io/cloud-cluster-profile: openshift-org-aws + ci.openshift.io/generator: prowgen + job-release: "4.22" + pj-rehearse.openshift.io/can-be-rehearsed: "true" + name: pull-ci-openshift-external-secrets-operator-main-tls-scanner + optional: true + rerun_command: /test tls-scanner + spec: + containers: + - args: + - --gcs-upload-secret=/secrets/gcs/service-account.json + - --image-import-pull-secret=/etc/pull-secret/.dockerconfigjson + - --lease-server-credentials-file=/etc/boskos/credentials + - --report-credentials-file=/etc/report/credentials + - --secret-dir=/secrets/ci-pull-credentials + - --target=tls-scanner + command: + - ci-operator + env: + - name: HTTP_SERVER_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + image: quay-proxy.ci.openshift.org/openshift/ci:ci_ci-operator_latest + imagePullPolicy: Always + name: "" + ports: + - containerPort: 8080 + name: http + resources: + requests: + cpu: 10m + volumeMounts: + - mountPath: /etc/boskos + name: boskos + readOnly: true + - mountPath: /secrets/ci-pull-credentials + name: ci-pull-credentials + readOnly: true + - mountPath: /secrets/gcs + name: gcs-credentials + readOnly: true + - mountPath: /secrets/manifest-tool + name: manifest-tool-local-pusher + readOnly: true + - mountPath: /etc/pull-secret + name: pull-secret + readOnly: true + - mountPath: /etc/report + name: result-aggregator + readOnly: true + serviceAccountName: ci-operator + volumes: + - name: boskos + secret: + items: + - key: credentials + path: credentials + secretName: boskos-credentials + - name: ci-pull-credentials + secret: + secretName: ci-pull-credentials + - name: manifest-tool-local-pusher + secret: + secretName: manifest-tool-local-pusher + - name: pull-secret + secret: + secretName: registry-pull-credentials + - name: result-aggregator + secret: + secretName: result-aggregator + trigger: (?m)^/test( | .* )tls-scanner,?($|\s.*) - agent: kubernetes always_run: true branches: From 561d99f1a1a7f0ccaf167167b9129ea02c09f70e Mon Sep 17 00:00:00 2001 From: Siddhi Bhor Date: Thu, 6 Aug 2026 16:55:36 +0530 Subject: [PATCH 2/2] adds bitwarden sever in tls scanner --- ...nshift-external-secrets-operator-main.yaml | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml b/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml index 24033ed2702dc..97f667e440613 100644 --- a/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml +++ b/ci-operator/config/openshift/external-secrets-operator/openshift-external-secrets-operator-main.yaml @@ -369,12 +369,79 @@ tests: echo "ExternalSecret status: ${STATUS} (attempt ${i}/30)..." sleep 5 done + echo "==> Generating self-signed TLS materials for bitwarden-sdk-server..." + CERT_DIR=$(mktemp -d) + export TLS_SECRET_NAME="bitwarden-tls-cert" + openssl ecparam -genkey -name prime256v1 -noout -out "${CERT_DIR}/ca.key" 2>/dev/null + openssl req -new -x509 -key "${CERT_DIR}/ca.key" -sha256 \ + -subj "/O=external-secrets-e2e/CN=bitwarden-e2e-ca" \ + -days 1 -out "${CERT_DIR}/ca.crt" 2>/dev/null + + cat > "${CERT_DIR}/san.cnf" <<'SANEOF' + [req] + distinguished_name = req_dn + req_extensions = v3_req + prompt = no + [req_dn] + O = external-secrets-e2e + CN = bitwarden-sdk-server + [v3_req] + basicConstraints = CA:FALSE + keyUsage = digitalSignature, keyEncipherment + extendedKeyUsage = serverAuth + subjectAltName = @alt_names + [alt_names] + DNS.1 = bitwarden-sdk-server.external-secrets.svc.cluster.local + DNS.2 = external-secrets-bitwarden-sdk-server.external-secrets.svc.cluster.local + DNS.3 = localhost + IP.1 = 127.0.0.1 + IP.2 = ::1 + SANEOF + + openssl ecparam -genkey -name prime256v1 -noout -out "${CERT_DIR}/tls.key" 2>/dev/null + openssl req -new -key "${CERT_DIR}/tls.key" -config "${CERT_DIR}/san.cnf" -out "${CERT_DIR}/tls.csr" 2>/dev/null + openssl x509 -req -in "${CERT_DIR}/tls.csr" -CA "${CERT_DIR}/ca.crt" -CAkey "${CERT_DIR}/ca.key" \ + -CAcreateserial -out "${CERT_DIR}/tls.crt" -days 1 -sha256 \ + -extensions v3_req -extfile "${CERT_DIR}/san.cnf" 2>/dev/null + + echo "Creating TLS secret '${TLS_SECRET_NAME}' in external-secrets namespace..." + oc delete secret "${TLS_SECRET_NAME}" -n external-secrets --ignore-not-found 2>/dev/null + oc create secret generic "${TLS_SECRET_NAME}" -n external-secrets \ + --from-file=tls.crt="${CERT_DIR}/tls.crt" \ + --from-file=tls.key="${CERT_DIR}/tls.key" \ + --from-file=ca.crt="${CERT_DIR}/ca.crt" + rm -rf "${CERT_DIR}" + + echo "==> Enabling Bitwarden plugin with TLS secretRef..." + oc patch externalsecretsconfig cluster --type=merge -p "{ + \"spec\": { + \"plugins\": { + \"bitwardenSecretManagerProvider\": { + \"mode\": \"Enabled\", + \"secretRef\": { \"name\": \"${TLS_SECRET_NAME}\" } + } + } + } + }" + sleep 10 + echo "ExternalSecretsConfig status after patch:" + oc get externalsecretsconfig cluster -o jsonpath='{.status.conditions[*].type}' 2>/dev/null || true + echo "" + oc get externalsecretsconfig cluster -o yaml 2>/dev/null | grep -A5 'conditions:' || true + oc wait externalsecretsconfig/cluster --for=condition=Available --timeout=180s || { + echo "Warning: ExternalSecretsConfig did not reach Available condition, checking bitwarden deployment directly..." + oc get externalsecretsconfig cluster -o yaml 2>/dev/null | grep -A20 'status:' || true + } + oc rollout status deployment/bitwarden-sdk-server -n external-secrets --timeout=180s echo "Listing all TLS-relevant services the scanner will probe:" echo "--- external-secrets-operator namespace ---" oc get svc -n external-secrets-operator -o wide 2>/dev/null || true echo "--- external-secrets namespace ---" oc get svc -n external-secrets -o wide 2>/dev/null || true + echo "--- bitwarden-sdk-server service ---" + oc get svc -n external-secrets bitwarden-sdk-server -o wide 2>/dev/null || true + oc get endpoints -n external-secrets bitwarden-sdk-server 2>/dev/null || true from: src resources: requests: