From ef6604f144a5ae2a14aa49f2052fe0da59d99503 Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Wed, 18 Feb 2026 10:22:02 +0300 Subject: [PATCH 1/8] new cve scan Signed-off-by: Maxim Konovalenko --- cve_scan/action.yml | 406 +++++++++++++------------------------------- 1 file changed, 114 insertions(+), 292 deletions(-) diff --git a/cve_scan/action.yml b/cve_scan/action.yml index 934f0b7..5882d74 100644 --- a/cve_scan/action.yml +++ b/cve_scan/action.yml @@ -1,328 +1,150 @@ name: 'Trivy CVE Scan' description: 'Build Deckhouse module' inputs: - tag_type: - description: 'Module tag type' - required: true - tag: - description: 'Module image tag' - required: true - module_name: - description: 'Module name' - required: true - dd_url: - description: 'URL to defectDojo' - required: true - dd_token: - description: 'Token of defectDojo to upload reports' - required: true prod_registry: - description: 'Must be deckhouse prod registry, used to get trivy databases and release images' + description: 'Prod registry host (e.g., registry.deckhouse.io)' required: true prod_registry_user: - description: 'Username to log in to deckhouse prod registry' + description: 'Username for prod registry authentication' required: true prod_registry_password: - description: 'Password to log in to deckhouse prod registry' + description: 'Password for prod registry authentication' required: true dev_registry: - description: 'Must be deckhouse dev registry, used to get dev images' + description: 'Dev-registry host (e.g., dev-registry.deckhouse.io)' required: true dev_registry_user: - description: 'Username to log in to deckhouse dev registry' + description: 'Username for dev-registry authentication' required: true dev_registry_password: - description: 'Password to log in to deckhouse dev registry' + description: 'Password for dev-registry authentication' + required: true + codeowners_repo_token: + description: 'GitLab token for downloading CODEOWNERS configmap from private repository' required: true deckhouse_private_repo: - description: 'URL to private repo to get Trivy from' + description: 'Deckhouse private repository' required: true + dd_url: + description: 'DefectDojo API URL' + required: true + dd_token: + description: 'DefectDojo API token' + required: true + source_tag: + description: 'Tag to scan (e.g., main, v1.74.3, pr123, release-1.73)' + required: true + case: + description: 'Scan type: deckhouse | external_modules | CSE' + required: true + cve_test_repo_git: + description: 'cve_scan.sh repo' + required: true + cve_ssh_private_key: + description: 'cve_scan.sh repo key' + required: true + external_module_name: + description: 'External module name (required when case=external_modules)' + required: false + default: '' scan_several_lastest_releases: - description: 'true/false. Whether to scan last several releases or not. For scheduled pipelines override will not work as value is always true' + description: 'Scan multiple latest releases (true/false)' required: false + default: 'false' latest_releases_amount: - description: 'Number of latest releases to scan. Default is: 3' - required: false - severity: - description: 'Vulnerabilities severity to scan. Default is: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL' + description: 'Number of latest releases to scan when scan_several_lastest_releases=true' required: false + default: '3' module_prod_registry_custom_path: - description: 'Module custom path in prod registry. Example: flant/modules' + description: 'Custom path for external modules in production registry' required: false + default: 'deckhouse/fe/modules' module_dev_registry_custom_path: - description: 'Module custom path in dev registry. Example: flant/modules' + description: 'Custom path for external modules in development registry' + required: false + default: 'sys/deckhouse-oss/modules' + release_in_dev: + description: 'If true, release tag will be searched in dev registry instead of prod' + required: false + default: 'false' + digest_from_werf: + description: 'Path to werf images tags file (for CSE external modules)' + required: false + default: 'images_tags_werf' + scan_users: + description: 'Enable user validation scan for CSE (true/false)' required: false + default: 'false' + workdir: + description: 'Working directory for temporary files' + required: false + default: 'cve-scan' + trivy_reports_log_output: + description: 'Trivy log output level (0=off, 1=CVE only, 2=CVE+License)' + required: false + default: '2' runs: using: "composite" steps: + - name: Start ssh-agent + uses: webfactory/ssh-agent@v0.9.0 + with: + ssh-private-key: ${{ inputs.cve_ssh_private_key }} + + - name: Get host from repo URL + id: get-host + shell: bash + run: | + HOST=$(echo "${{ inputs.cve_test_repo_git }}" | sed -E 's/.*@([^:]+).*/\1/') + echo "host=$HOST" >> $GITHUB_OUTPUT + + - name: Add ssh_known_hosts + shell: bash + run: | + HOST="${{ steps.get-host.outputs.host }}" + mkdir -p ~/.ssh + ssh-keyscan -H "$HOST" >> ~/.ssh/known_hosts 2>/dev/null + ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null || true + + - name: Clone repository and copy specific files + shell: bash + run: | + git clone --depth 1 ${{ inputs.cve_test_repo_git }} /tmp/cve-scripts + cp /tmp/cve-scripts/*.sh /tmp/cve-scripts/*.py . + chmod +x *.sh *.py + - name: Run Trivy CVE Scan shell: bash env: TRIVY_BIN_VERSION: "v0.67.2" TRIVY_REPO_ID: "2181" - TRIVY_DB_URL: "${{inputs.prod_registry}}/deckhouse/ee/security/trivy-db:2" - TRIVY_JAVA_DB_URL: "${{inputs.prod_registry}}/deckhouse/ee/security/trivy-java-db:1" - DECKHOUSE_PRIVATE_REPO: ${{inputs.deckhouse_private_repo}} - IMAGES_DIGESTS_PATH: "/images_digests.json" - TAG: "${{inputs.tag}}" - TAG_TYPE: "${{inputs.tag_type}}" - MODULE_NAME: "${{inputs.module_name}}" - DD_URL: "${{inputs.dd_url}}" - DD_TOKEN: "${{inputs.dd_token}}" - TRIVY_POLICY_URL: "${{inputs.prod_registry}}/deckhouse/ee/security/trivy-bdu:1" - SCAN_SEVERAL_LASTEST_RELEASES: "${{inputs.scan_several_lastest_releases}}" - LATEST_RELEASES_AMOUNT: "${{inputs.latest_releases_amount || '3'}}" - SEVERITY: "${{inputs.severity || 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'}}" - MODULE_PROD_REGISTRY_PATH: "${{inputs.module_prod_registry_custom_path || 'deckhouse/fe/modules'}}" - MODULE_DEV_REGISTRY_PATH: "${{inputs.module_dev_registry_custom_path || 'sys/deckhouse-oss/modules'}}" + TRIVY_DB_URL: "${{ inputs.prod_registry }}/deckhouse/ee/security/trivy-db:2" + TRIVY_JAVA_DB_URL: "${{ inputs.prod_registry }}/deckhouse/ee/security/trivy-java-db:1" + TRIVY_POLICY_URL: "${{ inputs.prod_registry }}/deckhouse/ee/security/trivy-bdu:1" + TRIVY_REPORTS_LOG_OUTPUT: "${{ inputs.trivy_reports_log_output }}" + PROD_REGISTRY: "${{ inputs.prod_registry }}" + PROD_REGISTRY_USER: "${{ inputs.prod_registry_user }}" + PROD_REGISTRY_PASSWORD: "${{ inputs.prod_registry_password }}" + DEV_REGISTRY: "${{ inputs.dev_registry }}" + DEV_REGISTRY_USER: "${{ inputs.dev_registry_user }}" + DEV_REGISTRY_PASSWORD: "${{ inputs.dev_registry_password }}" + SOURCE_TAG: "${{ inputs.source_tag }}" + CASE: "${{ inputs.case }}" + EXTERNAL_MODULE_NAME: "${{ inputs.external_module_name }}" + RELEASE_IN_DEV: "${{ inputs.release_in_dev }}" + SCAN_USERS: "${{ inputs.scan_users }}" + SCAN_SEVERAL_LATEST_RELEASES: "${{ inputs.scan_several_lastest_releases }}" + LATEST_RELEASES_AMOUNT: "${{ inputs.latest_releases_amount }}" + MODULE_PROD_REGISTRY_CUSTOM_PATH: "${{ inputs.module_prod_registry_custom_path }}" + MODULE_DEV_REGISTRY_CUSTOM_PATH: "${{ inputs.module_dev_registry_custom_path }}" + DIGEST_FROM_WERF: "${{ inputs.digest_from_werf }}" + DD_URL: "${{ inputs.dd_url }}" + DD_TOKEN: "${{ inputs.dd_token }}" + CODEOWNERS_REPO_TOKEN: "${{ inputs.codeowners_repo_token }}" + DECKHOUSE_PRIVATE_REPO: "${{ inputs.deckhouse_private_repo }}" + CONFIGMAP_PROJECT_ID: "4352" + WORKDIR: "${{ github.workspace }}/${{ inputs.workdir }}" run: | - echo "Creating workdir" - workdir="trivy_scan" - # remove workdir in case it was not removed on previous run - rm -rf "${workdir}" - mkdir "${workdir}" - echo - echo "=======================================================" - echo - echo "Preparing DOCKER_CONFIG and log in to registries" - mkdir -p "${workdir}/docker" - export DOCKER_CONFIG="${workdir}/docker" - echo "${{inputs.prod_registry_password}}" | docker login --username="${{inputs.prod_registry_user}}" --password-stdin ${{inputs.prod_registry}} - echo "${{inputs.dev_registry_password}}" | docker login --username="${{inputs.dev_registry_user}}" --password-stdin ${{inputs.dev_registry}} - echo - echo "=======================================================" - echo - echo "Get Trivy" - echo "Trivy version: ${TRIVY_BIN_VERSION}" - mkdir -p "${workdir}/bin/trivy-${TRIVY_BIN_VERSION}" - curl -L -s --fail-with-body https://${DECKHOUSE_PRIVATE_REPO}/api/v4/projects/${TRIVY_REPO_ID}/packages/generic/trivy-${TRIVY_BIN_VERSION}/${TRIVY_BIN_VERSION}/trivy -o ${workdir}/bin/trivy-${TRIVY_BIN_VERSION}/trivy - chmod u+x ${workdir}/bin/trivy-${TRIVY_BIN_VERSION}/trivy - ln -s ${PWD}/${workdir}/bin/trivy-${TRIVY_BIN_VERSION}/trivy ${workdir}/bin/trivy - - echo "Updating Trivy Data Bases" - mkdir -p "${workdir}/bin/trivy_cache" - ${workdir}/bin/trivy image --timeout 15m --username "${{inputs.prod_registry_user}}" --password "${{inputs.prod_registry_password}}" --download-db-only --db-repository "${TRIVY_DB_URL}" --cache-dir "${workdir}/bin/trivy_cache" - ${workdir}/bin/trivy image --timeout 15m --username "${{inputs.prod_registry_user}}" --password "${{inputs.prod_registry_password}}" --download-java-db-only --java-db-repository "${TRIVY_JAVA_DB_URL}" --cache-dir "${workdir}/bin/trivy_cache" - echo - echo "=======================================================" - echo - # Defining functions - - trivy_scan() { - ${workdir}/bin/trivy i --timeout 15m --vex oci --show-suppressed --config-check "${TRIVY_POLICY_URL}" --cache-dir "${workdir}/bin/trivy_cache" --skip-db-update --skip-java-db-update --exit-code 0 --severity "${SEVERITY}" --ignorefile "${module_workdir}/.trivyignore" --format ${1} ${2} ${3} --quiet ${4} --username "${trivy_registry_user}" --password "${trivy_registry_pass}" --image-src remote - } - - send_report() { - dd_scan_type="${1}" - dd_report_file_path="${2}" - dd_module_name="${3}" - dd_image_name="${4}" - dd_engagement_name="[$(echo "${dd_scan_type}" | tr '[:lower:]' '[:upper:]')] [IMAGES] [${dd_branch}]" - tags_string="\"external_modules\",\"images\",\"${dd_scan_type}\",\"${dd_release_or_dev_tag}\",\"${dd_image_version}\"" - if [[ -n "${dd_short_release_tag}" && -n "${dd_full_release_tag}" ]]; then - tags_string+=",\"${dd_short_release_tag}\",\"${dd_full_release_tag}\"" - fi - echo "" - echo "Uploading trivy ${dd_branch} report for image \"${dd_image_name}\" of \"${dd_module_name}\" module" - echo "" - dd_upload_response=$(curl -sw "%{http_code}" -X POST \ - --retry 10 \ - --retry-delay 20 \ - --retry-all-errors \ - ${DD_URL}/api/v2/reimport-scan/ \ - -H "accept: application/json" \ - -H "Authorization: Token ${DD_TOKEN}" \ - -F "auto_create_context=True" \ - -F "minimum_severity=Info" \ - -F "active=true" \ - -F "verified=true" \ - -F "scan_type=Trivy Scan" \ - -F "close_old_findings=true" \ - -F "do_not_reactivate=false" \ - -F "push_to_jira=false" \ - -F "file=@${dd_report_file_path}" \ - -F "product_type_name=External Modules" \ - -F "product_name=${dd_module_name}" \ - -F "scan_date=${date_iso}" \ - -F "engagement_name=${dd_engagement_name}" \ - -F "service=${dd_module_name} / ${dd_image_name}" \ - -F "group_by=component_name+component_version" \ - -F "deduplication_on_engagement=false" \ - -F "tags=external_module,${dd_scan_type},module:${dd_module_name},image:${dd_image_name},branch:${dd_branch},${dd_short_release_tag},${dd_full_release_tag},${dd_default_branch_tag},${dd_release_or_dev_tag}" \ - -F "test_title=[${dd_module_name}]: ${dd_image_name}:${dd_image_version}" \ - -F "version=${dd_image_version}" \ - -F "build_id=${IMAGE_HASH}" \ - -F "commit_hash=${CI_COMMIT_SHA}" \ - -F "branch_tag=${module_tag}" \ - -F "apply_tags_to_findings=true") - - dd_return_code="${dd_upload_response: -3}" - dd_return_body="${dd_upload_response:0: -3}" - if [ ${dd_return_code} -eq 201 ]; then - dd_engagement_id=$(echo ${dd_return_body} | jq ".engagement_id" ) - echo "dd_engagement_id: ${dd_engagement_id}" - echo "Update with tags: ${tags_string}" - # Updating engagement - dd_eng_patch_response=$(curl -sw "%{http_code}" -X "PATCH" \ - --retry 10 \ - --retry-delay 20 \ - --retry-all-errors \ - "${DD_URL}/api/v2/engagements/${dd_engagement_id}/" \ - -H "accept: application/json" \ - -H "Authorization: Token ${DD_TOKEN}" \ - -H "Content-Type: application/json" \ - -d "{ - \"tags\": ["${tags_string}"], - \"version\": \"${dd_image_version}\", - \"branch_tag\": \"${dd_branch}\" - }") - if [ ${dd_eng_patch_response: -3} -eq 200 ]; then - echo "Engagemet \"${dd_engagement_name}\" updated successfully" - else - echo "!!!WARNING!!!" - echo "Engagemet \"${dd_engagement_name}\" WAS NOT UPDATED" - echo "HTTP_CODE: ${dd_eng_patch_response: -3}" - echo "DD_RESPONSE: ${dd_eng_patch_response:0: -3}" - fi - else - echo "!!!WARNING!!!" - echo "Report for image \"${dd_image_name}\" of \"${dd_module_name}\" module WAS NOT UPLOADED" - echo "HTTP_CODE: ${dd_return_code}" - echo "DD_RESPONSE: ${dd_return_body}" - fi - } - if [ "${{ github.event_name }}" == "schedule" ]; then - SCAN_SEVERAL_LASTEST_RELEASES="true" - fi - - echo "Setting up registry path for module" - PROD_REGISTRY_MODULE_BASEDIR="${{inputs.prod_registry}}/${MODULE_PROD_REGISTRY_PATH}" - DEV_REGISTRY_MODULE_BASEDIR="${{inputs.dev_registry}}/${MODULE_DEV_REGISTRY_PATH}" - - echo "Getting tags to scan" - module_tags=("${TAG}") - # Check if provided tag for manual run is for release - if [ "${{ github.event_name }}" != "pull_request" ]; then - if [ "${TAG}" != "${{ github.event.repository.default_branch }}" ]; then - if [ "${TAG_TYPE}" == "release" ]; then - # if some specific release is defined - scan only it - if echo "${TAG}"|grep -qE "^[0-9]+\.[0-9]+$"; then - module_tags=($(crane ls "${PROD_REGISTRY_MODULE_BASEDIR}/${MODULE_NAME}" | grep "^v${TAG}\.[0-9]*$" | sort -V -r | head -n 1)) - else - echo "ERROR: Please specify required release in the following format: [0-9]+\.[0-9]+" - exit 1 - fi - elif [ "${TAG_TYPE}" == "dev" ]; then - if [ $(crane ls "${DEV_REGISTRY_MODULE_BASEDIR}/${MODULE_NAME}" | grep "^${TAG}$" | wc -l) -eq 1 ]; then - module_tags=("${TAG}") - else - echo "ERROR: Provided tag \"${TAG}\" is not found in dev registry" - exit 1 - fi - else - echo "ERROR: TAG TYPE is not defined!" - exit 1 - fi - fi - fi - if [ "${SCAN_SEVERAL_LASTEST_RELEASES}" == "true" ]; then - # Get release tags by regexp, sort by sevmer desc, cut to get minor version, uniq and get 3 latest - releases=($(crane ls "${PROD_REGISTRY_MODULE_BASEDIR}/${MODULE_NAME}" | grep "^v[0-9]*\.[0-9]*\.[0-9]*" | sort -V -r)) - latest_minor_releases=($(printf '%s\n' "${releases[@]}"| cut -d "." -f -2 | uniq | head -n ${LATEST_RELEASES_AMOUNT})) - for r in "${latest_minor_releases[@]}"; do - module_tags+=($(printf '%s\n' "${releases[@]}" | grep "${r}" | sort -V -r|head -n 1)) - done - fi - - echo "CVE Scan will be applied to the following tags of ${MODULE_NAME}" - echo "${module_tags[*]}" - # Scan in loop for provided list of tags - for module_tag in ${module_tags[*]}; do - dd_default_branch_tag="" - dd_short_release_tag="" - dd_full_release_tag="" - dd_release_or_dev_tag="dev" - dd_image_version="${module_tag}" - dd_branch="${module_tag}" - date_iso=$(date -I) - module_image="${DEV_REGISTRY_MODULE_BASEDIR}/${MODULE_NAME}" - trivy_registry_user="${{inputs.dev_registry_user}}" - trivy_registry_pass="${{inputs.dev_registry_password}}" - if [ "${module_tag}" == "${{ github.event.repository.default_branch }}" ]; then - dd_default_branch_tag="default_branch" - fi - # If we are scanning release images - we need to redefine image path to prod registry - if echo "${module_tag}" | grep -q "^v[0-9]*\.[0-9]*\.[0-9]*" && [[ "${{ github.event_name }}" != "pull_request" ]]; then - module_image="${PROD_REGISTRY_MODULE_BASEDIR}/${MODULE_NAME}" - trivy_registry_user="${{inputs.prod_registry_user}}" - trivy_registry_pass="${{inputs.prod_registry_password}}" - dd_short_release_tag="release:$(echo ${module_tag} | cut -d '.' -f -2 | sed 's/^v//')" - dd_full_release_tag="image_release_tag:${module_tag}" - dd_release_or_dev_tag="release" - dd_image_version="$(echo ${dd_short_release_tag} | sed 's/^release\://')" - fi - module_workdir="${workdir}/${MODULE_NAME}_${module_tag}" - module_reports="${module_workdir}/reports" - mkdir -p "${module_reports}" - touch ${module_workdir}/.trivyignore - echo "Run Trivy scan" - echo "Image to check: ${module_image}:${module_tag}" - echo "Severity: ${SEVERITY}" - echo "----------------------------------------------" - echo "" - echo "Getting module image" - crane export "${module_image}:${module_tag}" "${MODULE_NAME}.tar" - tar xf "${MODULE_NAME}.tar" -C "${module_workdir}/" - echo "Preparing images list to scan" - digests=$(cat "${module_workdir}${IMAGES_DIGESTS_PATH}") - # Main module images to scan - digests=$(echo "${digests}"|jq --arg i "${MODULE_NAME}" --arg s "${module_tag}" '. += { ($i): ($s) }') - echo "Images to scan:" - echo "${digests}" - while read -r line; do - IMAGE_NAME=$(jq -rc '.key' <<< "${line}") - if [[ "${IMAGE_NAME}" == "trivy" ]]; then - continue - fi - # Set flag if additional image to use tag instead of hash - additional_image_detected=false - if [ "${IMAGE_NAME}" == "${MODULE_NAME}" ]; then - additional_image_detected=true - fi - echo "----------------------------------------------" - echo "👾 Scaning image \"${IMAGE_NAME}\" of module \"${MODULE_NAME}\" for tag \"${module_tag}\"" - echo "" - IMAGE_HASH="$(jq -rc '.value' <<< "$line")" - - if [ "$additional_image_detected" == true ]; then - if [ "${TRIVY_REPORTS_LOG_OUTPUT}" != "false" ]; then - # CVE Scan - trivy_scan "table" "--scanners vuln" "" "${module_image}:${module_tag}" - # License scan - trivy_scan "table" "--scanners license --license-full" "" "${module_image}:${module_tag}" - fi - # CVE Scan - trivy_scan "json" "--scanners vuln" "--output ${module_reports}/ext_${MODULE_NAME}_${IMAGE_NAME}_report.json" "${module_image}:${module_tag}" - # License scan - trivy_scan "json" "--scanners license --license-full" "--output ${module_reports}/ext_${MODULE_NAME}_${IMAGE_NAME}_report_license.json" "${module_image}:${module_tag}" - else - if [ "${TRIVY_REPORTS_LOG_OUTPUT}" != "false" ]; then - # CVE Scan - trivy_scan "table" "--scanners vuln" "" "${module_image}@${IMAGE_HASH}" - # License scan - trivy_scan "table" "--scanners license --license-full" "" "${module_image}@${IMAGE_HASH}" - fi - # CVE Scan - trivy_scan "json" "--scanners vuln" "--output ${module_reports}/ext_${MODULE_NAME}_${IMAGE_NAME}_report.json" "${module_image}@${IMAGE_HASH}" - # License scan - trivy_scan "json" "--scanners license --license-full" "--output ${module_reports}/ext_${MODULE_NAME}_${IMAGE_NAME}_report_license.json" "${module_image}@${IMAGE_HASH}" - fi - echo " Done" - - send_report "CVE" "${module_reports}/ext_${MODULE_NAME}_${IMAGE_NAME}_report.json" "${MODULE_NAME}" "${IMAGE_NAME}" - send_report "License" "${module_reports}/ext_${MODULE_NAME}_${IMAGE_NAME}_report_license.json" "${MODULE_NAME}" "${IMAGE_NAME}" - done < <(jq -rc 'to_entries[]' <<< "${digests}") - done - rm -r ${workdir} + ./cve_scan.sh From 5243aa9eeddff1a4e82063061cd1e798b45a5d92 Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Wed, 18 Feb 2026 23:34:26 +0300 Subject: [PATCH 2/8] fix Signed-off-by: Maxim Konovalenko --- cve_scan/action.yml | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/cve_scan/action.yml b/cve_scan/action.yml index 5882d74..ea3c7dd 100644 --- a/cve_scan/action.yml +++ b/cve_scan/action.yml @@ -90,29 +90,21 @@ runs: - name: Start ssh-agent uses: webfactory/ssh-agent@v0.9.0 with: - ssh-private-key: ${{ inputs.cve_ssh_private_key }} + ssh-private-key: ${{ inputs.cve_ssh_private_key }} # только ключ, не URL - - name: Get host from repo URL - id: get-host + - name: Add host to known_hosts shell: bash run: | HOST=$(echo "${{ inputs.cve_test_repo_git }}" | sed -E 's/.*@([^:]+).*/\1/') - echo "host=$HOST" >> $GITHUB_OUTPUT - - - name: Add ssh_known_hosts - shell: bash - run: | - HOST="${{ steps.get-host.outputs.host }}" mkdir -p ~/.ssh ssh-keyscan -H "$HOST" >> ~/.ssh/known_hosts 2>/dev/null - ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null || true - - name: Clone repository and copy specific files + - name: Clone repository shell: bash run: | + rm -rf /tmp/cve-scan git clone --depth 1 ${{ inputs.cve_test_repo_git }} /tmp/cve-scripts - cp /tmp/cve-scripts/*.sh /tmp/cve-scripts/*.py . - chmod +x *.sh *.py + cp /tmp/cve-scripts/* ./ - name: Run Trivy CVE Scan shell: bash From 98465f4fe878b4d1896a4f43b9399b06e4a6abca Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Wed, 18 Feb 2026 23:34:43 +0300 Subject: [PATCH 3/8] fix Signed-off-by: Maxim Konovalenko --- cve_scan/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve_scan/action.yml b/cve_scan/action.yml index ea3c7dd..f89ad7e 100644 --- a/cve_scan/action.yml +++ b/cve_scan/action.yml @@ -90,7 +90,7 @@ runs: - name: Start ssh-agent uses: webfactory/ssh-agent@v0.9.0 with: - ssh-private-key: ${{ inputs.cve_ssh_private_key }} # только ключ, не URL + ssh-private-key: ${{ inputs.cve_ssh_private_key }} - name: Add host to known_hosts shell: bash From b31386700c44e12d6673a58eff6ff29837834f9d Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Wed, 18 Feb 2026 23:36:07 +0300 Subject: [PATCH 4/8] fix Signed-off-by: Maxim Konovalenko --- cve_scan/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cve_scan/action.yml b/cve_scan/action.yml index f89ad7e..5123deb 100644 --- a/cve_scan/action.yml +++ b/cve_scan/action.yml @@ -102,7 +102,7 @@ runs: - name: Clone repository shell: bash run: | - rm -rf /tmp/cve-scan + rm -rf /tmp/cve-scripts git clone --depth 1 ${{ inputs.cve_test_repo_git }} /tmp/cve-scripts cp /tmp/cve-scripts/* ./ From 27afc3e84f42aede89531224e75d6e6f44b2846e Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Wed, 18 Feb 2026 23:51:57 +0300 Subject: [PATCH 5/8] fix Signed-off-by: Maxim Konovalenko --- cve_scan/action.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cve_scan/action.yml b/cve_scan/action.yml index 5123deb..8bce9b0 100644 --- a/cve_scan/action.yml +++ b/cve_scan/action.yml @@ -111,6 +111,8 @@ runs: env: TRIVY_BIN_VERSION: "v0.67.2" TRIVY_REPO_ID: "2181" + TRIVY_PROD_REGISTRY: "registry.deckhouse.io" + TRIVY_DEV_REGISTRY: "dev-registry.deckhouse.io" TRIVY_DB_URL: "${{ inputs.prod_registry }}/deckhouse/ee/security/trivy-db:2" TRIVY_JAVA_DB_URL: "${{ inputs.prod_registry }}/deckhouse/ee/security/trivy-java-db:1" TRIVY_POLICY_URL: "${{ inputs.prod_registry }}/deckhouse/ee/security/trivy-bdu:1" From 7db5f7394f8fd4ea7f5f7023a43b679f22d0b2a1 Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Thu, 19 Feb 2026 11:00:43 +0300 Subject: [PATCH 6/8] ci Signed-off-by: Maxim Konovalenko --- .examples/cve_scan.yml | 83 ++++++++++++++++++++++-------------------- 1 file changed, 44 insertions(+), 39 deletions(-) diff --git a/.examples/cve_scan.yml b/.examples/cve_scan.yml index 83855e9..a4304b8 100644 --- a/.examples/cve_scan.yml +++ b/.examples/cve_scan.yml @@ -10,14 +10,7 @@ on: - main workflow_dispatch: inputs: - tag_type: - type: choice - description: Tag type - required: false - options: - - release - - dev - tag_name: + source_tag: description: "release version in semver minor format (example: 1.68) or specified tag from dev registry" required: false scan_several_lastest_releases: @@ -26,8 +19,11 @@ on: latest_releases_amount: description: 'Optional. Number of latest releases to scan. Default is: 3' required: false - severity: - description: 'Optional. Vulnerabilities severity to scan. Default is: UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL' + trivy_reports_log_output: + description: 'Optional. Output Trivy reports to the CI/CD log. 0 - do not output, 1 - CVE/FS only, 2 - CVE + License. Default: 1' + required: false + external_module_name: + description: 'The name of the module whose tag will be scanned' required: false jobs: @@ -37,40 +33,49 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: deckhouse/modules-actions/cve_scan@v5 + - uses: deckhouse/modules-actions/cve_scan@main with: - tag: pr${{ github.event.number }} - module_name: ${{ vars.MODULE_NAME }} - dd_url: ${{ secrets.DEFECTDOJO_HOST }} - dd_token: ${{ secrets.DEFECTDOJO_API_TOKEN }} - prod_registry: ${{ secrets.PROD_READ_REGISTRY }} - prod_registry_user: ${{ secrets.PROD_READ_REGISTRY_LOGIN }} - prod_registry_password: ${{ secrets.PROD_READ_REGISTRY_PASSWORD }} - dev_registry: ${{ secrets.DEV_REGISTRY }} - dev_registry_user: ${{ secrets.DEV_REGISTRY_LOGIN }} - dev_registry_password: ${{ secrets.DEV_REGISTRY_PASSWORD }} - deckhouse_private_repo: ${{ secrets.DECKHOUSE_PRIVATE_REPO }} - severity: "HIGH,CRITICAL" + case: "deckhouse" + source_tag: "${{ github.event.inputs.source_tag }}" + trivy_reports_log_output: "${{ github.event.inputs.trivy_reports_log_output }}" + scan_several_lastest_releases: "${{ github.event.inputs.scan_several_lastest_releases }}" + latest_releases_amount: "${{ github.event.inputs.latest_releases_amount }}" + prod_registry: "registry.deckhouse.io" + prod_registry_user: "${{ secrets.DECKHOUSE_REGISTRY_READ_USER }}" + prod_registry_password: "${{ secrets.DECKHOUSE_REGISTRY_READ_PASSWORD }}" + dev_registry: "dev-registry.deckhouse.io" + dev_registry_user: "${{ secrets.DECKHOUSE_DEV_REGISTRY_USER}}" + dev_registry_password: "${{ secrets.DECKHOUSE_DEV_REGISTRY_PASSWORD }}" + codeowners_repo_token: "${{ secrets.CODEOWNERS_REPO_TOKEN }}" + deckhouse_private_repo: "${{ secrets.DECKHOUSE_PRIVATE_REPO }}" + dd_url: "${{ secrets.DD_URL }}" + dd_token: "${{ secrets.DD_TOKEN }}" + cve_test_repo_git: "${{ secrets.CVE_TEST_REPO_GIT }}" + cve_ssh_private_key: "${{ secrets.CVE_SSH_PRIVATE_KEY }}" cve_scan: if: github.event_name != 'pull_request' name: Regular CVE scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: deckhouse/modules-actions/cve_scan@v5 + - uses: deckhouse/modules-actions/cve_scan@main with: - tag: ${{ github.event.inputs.tag_name || github.event.repository.default_branch }} - tag_type: ${{ github.event.inputs.tag_type }} - module_name: ${{ vars.MODULE_NAME }} - dd_url: ${{ secrets.DEFECTDOJO_HOST }} - dd_token: ${{ secrets.DEFECTDOJO_API_TOKEN }} - prod_registry: ${{ secrets.PROD_READ_REGISTRY }} - prod_registry_user: ${{ secrets.PROD_READ_REGISTRY_LOGIN }} - prod_registry_password: ${{ secrets.PROD_READ_REGISTRY_PASSWORD }} - dev_registry: ${{ secrets.DEV_REGISTRY }} - dev_registry_user: ${{ secrets.DEV_REGISTRY_LOGIN }} - dev_registry_password: ${{ secrets.DEV_REGISTRY_PASSWORD }} - deckhouse_private_repo: ${{ secrets.DECKHOUSE_PRIVATE_REPO }} - scan_several_lastest_releases: ${{ github.event.inputs.scan_several_lastest_releases }} - latest_releases_amount: ${{ github.event.inputs.latest_releases_amount || '3' }} - severity: ${{ github.event.inputs.severity }} + case: "External Modules" + external_module_name: "${{ github.event.inputs.external_module_name }}" + source_tag: "${{ github.event.inputs.source_tag }}" + release_in_dev: "${{ github.event.inputs.release_in_dev }}" + trivy_reports_log_output: "${{ github.event.inputs.trivy_reports_log_output }}" + scan_several_lastest_releases: "${{ github.event.inputs.scan_several_lastest_releases }}" + latest_releases_amount: "${{ github.event.inputs.latest_releases_amount }}" + prod_registry: "registry.deckhouse.io" + prod_registry_user: "${{ secrets.DECKHOUSE_REGISTRY_READ_USER }}" + prod_registry_password: "${{ secrets.DECKHOUSE_REGISTRY_READ_PASSWORD }}" + dev_registry: "dev-registry.deckhouse.io" + dev_registry_user: "${{ secrets.DECKHOUSE_DEV_REGISTRY_USER}}" + dev_registry_password: "${{ secrets.DECKHOUSE_DEV_REGISTRY_PASSWORD }}" + codeowners_repo_token: "${{ secrets.CODEOWNERS_REPO_TOKEN }}" + deckhouse_private_repo: "${{ secrets.DECKHOUSE_PRIVATE_REPO }}" + dd_url: "${{ secrets.DD_URL }}" + dd_token: "${{ secrets.DD_TOKEN }}" + cve_test_repo_git: "${{ secrets.CVE_TEST_REPO_GIT }}" + cve_ssh_private_key: "${{ secrets.CVE_SSH_PRIVATE_KEY }}" From c4fcf40e56bd2b4675e45a9ec4ea9ef7e54ad58a Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Thu, 19 Feb 2026 11:41:33 +0300 Subject: [PATCH 7/8] ci Signed-off-by: Maxim Konovalenko --- cve_scan/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cve_scan/action.yml b/cve_scan/action.yml index 8bce9b0..d42524d 100644 --- a/cve_scan/action.yml +++ b/cve_scan/action.yml @@ -50,7 +50,7 @@ inputs: scan_several_lastest_releases: description: 'Scan multiple latest releases (true/false)' required: false - default: 'false' + default: 'False' latest_releases_amount: description: 'Number of latest releases to scan when scan_several_lastest_releases=true' required: false @@ -66,7 +66,7 @@ inputs: release_in_dev: description: 'If true, release tag will be searched in dev registry instead of prod' required: false - default: 'false' + default: 'False' digest_from_werf: description: 'Path to werf images tags file (for CSE external modules)' required: false @@ -74,7 +74,7 @@ inputs: scan_users: description: 'Enable user validation scan for CSE (true/false)' required: false - default: 'false' + default: 'False' workdir: description: 'Working directory for temporary files' required: false @@ -82,7 +82,7 @@ inputs: trivy_reports_log_output: description: 'Trivy log output level (0=off, 1=CVE only, 2=CVE+License)' required: false - default: '2' + default: '1' runs: using: "composite" From 0715addef03686f6f28fdd69bdcd5be7ac51a996 Mon Sep 17 00:00:00 2001 From: Maxim Konovalenko Date: Tue, 24 Feb 2026 09:04:07 +0300 Subject: [PATCH 8/8] fix var Signed-off-by: Maxim Konovalenko --- cve_scan/action.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cve_scan/action.yml b/cve_scan/action.yml index d42524d..da204c5 100644 --- a/cve_scan/action.yml +++ b/cve_scan/action.yml @@ -20,7 +20,7 @@ inputs: description: 'Password for dev-registry authentication' required: true codeowners_repo_token: - description: 'GitLab token for downloading CODEOWNERS configmap from private repository' + description: 'Fox token for downloading CODEOWNERS configmap' required: true deckhouse_private_repo: description: 'Deckhouse private repository' @@ -38,21 +38,21 @@ inputs: description: 'Scan type: deckhouse | external_modules | CSE' required: true cve_test_repo_git: - description: 'cve_scan.sh repo' + description: 'cve_scan repo' required: true cve_ssh_private_key: - description: 'cve_scan.sh repo key' + description: 'cve_scan repo key' required: true external_module_name: - description: 'External module name (required when case=external_modules)' + description: 'External module name (required when case=External Modules)' required: false default: '' - scan_several_lastest_releases: - description: 'Scan multiple latest releases (true/false)' + scan_several_latest_releases: + description: 'Scan multiple latest releases (True/False)' required: false default: 'False' latest_releases_amount: - description: 'Number of latest releases to scan when scan_several_lastest_releases=true' + description: 'Number of latest releases to scan when scan_several_latest_releases=true' required: false default: '3' module_prod_registry_custom_path: @@ -72,7 +72,7 @@ inputs: required: false default: 'images_tags_werf' scan_users: - description: 'Enable user validation scan for CSE (true/false)' + description: 'Enable user validation scan for CSE (True/False)' required: false default: 'False' workdir: @@ -128,7 +128,7 @@ runs: EXTERNAL_MODULE_NAME: "${{ inputs.external_module_name }}" RELEASE_IN_DEV: "${{ inputs.release_in_dev }}" SCAN_USERS: "${{ inputs.scan_users }}" - SCAN_SEVERAL_LATEST_RELEASES: "${{ inputs.scan_several_lastest_releases }}" + SCAN_SEVERAL_LATEST_RELEASES: "${{ inputs.scan_several_latest_releases }}" LATEST_RELEASES_AMOUNT: "${{ inputs.latest_releases_amount }}" MODULE_PROD_REGISTRY_CUSTOM_PATH: "${{ inputs.module_prod_registry_custom_path }}" MODULE_DEV_REGISTRY_CUSTOM_PATH: "${{ inputs.module_dev_registry_custom_path }}"