From 9b3963e4319ffaa43bdd375b0d91f23ea87f7bb8 Mon Sep 17 00:00:00 2001 From: Sangamesh Vijaykumar Date: Tue, 13 Oct 2026 15:29:53 +0530 Subject: [PATCH 1/6] feat: Add FAA scan action for SSC and FoD modules and integrate it into CI workflows --- .../com/fortify/cli/fod/actions/zip/ci.yaml | 32 ++++- .../fortify/cli/fod/actions/zip/faa-scan.yaml | 94 +++++++++++++++ .../com/fortify/cli/ssc/actions/zip/ci.yaml | 31 ++++- .../fortify/cli/ssc/actions/zip/faa-scan.yaml | 110 ++++++++++++++++++ 4 files changed, 262 insertions(+), 5 deletions(-) create mode 100644 fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml create mode 100644 fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml index e02feb6f9b5..076bd6054a7 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml @@ -65,6 +65,13 @@ steps: #fcliCmdSkipFromEnvReason('WAIT', false) ?:#fcliCmdSkipFromEnvReason('SAST_WAIT', false) } + faa.skipReason: > # Disabled by default; requires DO_FAA_SCAN=true to be enabled + ${ + #fcliCmdSkipFromEnvReason('FAA_SCAN', true) + } + global.faaScan.fprFile: faa_input_${#action.runID().replace('-','_')}.fpr + global.faaScan.fprDownloaded: false + # Post-scan tasks will be skipped if wait is skipped or if no scans were completed # successfully. Post-scan skip reason will be reset to null once the wait task for # any scan completed successfully. @@ -134,7 +141,30 @@ steps: - ${SAST_SCAN.dependencySkipReason} # Skip if SAST_SCAN was skipped or failed on.success: - var.set: { postScan.skipReason: } # Reset postScan.skipReason to allow post-scan tasks to run - + + DOWNLOAD_SAST_FPR: + cmd: > + ${#fcliCmd('DOWNLOAD_SAST_FPR', 'fod sast-scan download-latest')} + -f="${global.faaScan.fprFile}" + --rel="${global.ci.rel}" + skip.if-reason: + - ${SAST_WAIT.dependencySkipReason} # Skip if SAST_WAIT was skipped or failed + - ${faa.skipReason} # Skip if FAA scan is disabled + on.success: + - var.set: { global.faaScan.fprDownloaded: true } + status.check: false + + FAA_SCAN: + cmd: > + ${#actionCmd('FAA_SCAN', 'fod', 'faa-scan')} + "--source-dir=${global.ci.sourceDir}" + "--release=${global.ci.rel}" + "--faa-path=${#env('FORTIFY_AGENTIC_ANALYZER_HOME')}" + ${global.faaScan.fprDownloaded ? ' --fpr=' + global.faaScan.fprFile : ''} + ${#isNotBlank(#env('FAA_SCAN_OUTPUT_PATH')) ? '--output=' + #env('FAA_SCAN_OUTPUT_PATH') : ''} + skip.if-reason: + - ${faa.skipReason} # Skip if FAA scan is disabled + AVIATOR_REMEDIATIONS: cmd: ${#actionCmd('AVIATOR_REMEDIATIONS', 'fod', global.ci.fod_aviatorRemediationsAction)} "--rel=${global.ci.rel}" "--source-dir=${global.ci.sourceDir}" "--progress=none" skip.if-reason: diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml new file mode 100644 index 00000000000..00f1ca81360 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml @@ -0,0 +1,94 @@ +# yaml-language-server: $schema=https://fortify.github.io/fcli/schemas/action/fcli-action-schema-dev-2.x.json + +author: Fortify +usage: + header: (PREVIEW) Run Fortify Agentic Analyzer Scan + description: | + This action can be used to run a Fortify Agentic Analyzer (FAA) scan of the project + and optionally import the results to FoD as a SARIF report. + + Optionally, you can provide the FPR file from a prior SAST scan. When provided, + FAA uses this context to avoid reporting duplicate issues that were already found + by the SAST scan, resulting in higher quality analysis results. + +config: + output: immediate + rest.target.default: fod + run.fcli.status.log.default: true # By default, we log all exit statuses + run.fcli.status.check.default: true + mcp: exclude # FAA is a specialized tool requiring specific setup + +# NOTE: When updating any options, ci action may also need to be updated +cli.options: + sourceDir: + names: --source-dir, -d + description: >- + Source directory on which to run Fortify Agentic Analyzer scan. + Defaults to current working directory if not specified. + required: true + fprFile: + names: --fpr, -f + description: >- + Optional path to the FPR file from a prior SAST scan. When provided, FAA uses this + context to avoid reporting duplicate issues already identified by SAST, resulting in + enhanced analysis quality. If not provided, FAA will perform a standalone analysis. + required: false + release: + names: --release, --rel + description: >- + Optional FoD release to which the FAA scan results (SARIF) must be imported. If not specified, FAA scan will run and write results to the output file, but SARIF will not be imported to FoD. Release must already exist in FoD if specified. + required: false + output: + names: --output, -o + description: >- + Output SARIF file path where FAA scan results will be written. + Defaults to fortifyaa.sarif in the current working directory. + required: false + default: fortifyaa.sarif + faaPath: + names: --faa-path, -p + description: | + Path to a pre-installed Fortify Agentic Analyzer (FAA) installation. + FAA must be pre-installed on the system before running this action; + this action only registers the existing installation with fcli. + Defaults to the FORTIFY_AGENTIC_ANALYZER_HOME environment variable. + Required: User must have FAA already installed and FORTIFY_AGENTIC_ANALYZER_HOME set. + required: true + extraScanOpts: + names: --extra-scan-opts + description: >- + Extra options to be passed to the 'fortifyaa -scan' command. + required: false + +steps: + - var.set: + # Used for passing extra options from ci action without bothering about escaping + extraScanOpts: ${#join(" ", {cli.extraScanOpts, global.faaScan?.extraOpts})} + + - run.fcli: + SETUP_TOOLS: fcli tool env init "--tools=fortifyaa:${cli.faaPath}" + RUN_FAA_SCAN: + cmd: > + fcli tool fortifyaa run -- + -clean + -scan "${cli.sourceDir}" + ${#isNotBlank(cli.fprFile) ? '--fpr "' + cli.fprFile + '"' : ''} + -o "${cli.output}" + ${extraScanOpts} + stdout: collect + stderr: collect + on.success: + - out.write: + stdout: ${RUN_FAA_SCAN.stdout} + stderr: ${RUN_FAA_SCAN.stderr} + on.fail: + - out.write: + stdout: ${RUN_FAA_SCAN.stdout} + stderr: ${RUN_FAA_SCAN.stderr} + - throw: FAA Scan failed with errors. + IMPORT_SARIF: + cmd: > + fcli fod sast-scan import-sarif + --rel "${cli.release}" + -f "${cli.output}" + status.check: false diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml index 972be879137..3b16f9c454a 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml @@ -78,13 +78,20 @@ steps: ${ #extraOpts('DEBRICKED_SCAN') } + faa.skipReason: > # Disabled by default; requires DO_FAA_SCAN=true to be enabled + ${ + #fcliCmdSkipFromEnvReason('FAA_SCAN', true) + } + global.faaScan.fprFile: faa_input_${#action.runID().replace('-','_')}.fpr + global.faaScan.fprDownloaded: false + aviator.skipReason: > # Enabled if AVIATOR_TOKEN & AVIATOR_URL specified, unless explicitly disabled ${ #fcliCmdSkipFromEnvReason('AVIATOR_AUDIT', false) ?:#skipBlankEnvReason('AVIATOR_TOKEN') ?:#skipBlankEnvReason('AVIATOR_URL') } - aviator.loginOpts: --url=AVIATOR_URL + aviator.loginOpts: --url=${#env('AVIATOR_URL')} aviator.app: ${#env('AVIATOR_APP')?:'::av::application.name'} wait.skipReason: >- # Enabled by default, unless explicitly disabled through DO_WAIT or DO_SAST_WAIT (deprecated) ${ @@ -199,12 +206,28 @@ steps: skip.if-reason: - ${SAST_WAIT.dependencySkipReason} # Skip if SAST_WAIT was skipped or failed - ${#isDebugEnabled()?'':'--debug flag not specified'} # Skip if debugging is disabled + DOWNLOAD_SAST_FPR: - cmd: "${#fcliCmd('DOWNLOAD_SAST_FPR', 'sc-sast scan download -t fpr')} ::sc_sast_scan::" + cmd: "${#fcliCmd('DOWNLOAD_SAST_FPR', 'sc-sast scan download -t fpr -f')} ${global.faaScan.fprFile} ::sc_sast_scan::" skip.if-reason: - ${SAST_WAIT.dependencySkipReason} # Skip if SAST_WAIT was skipped or failed - - ${#isDebugEnabled()?'':'--debug flag not specified'} # Skip if debugging is disabled - + - ${faa.skipReason} # Skip if FAA scan is disabled + on.success: + - var.set: { global.faaScan.fprDownloaded: true } + status.check: false + + FAA_SCAN: + cmd: > + ${#actionCmd('FAA_SCAN', 'ssc', 'faa-scan')} + "--source-dir=${global.ci.sourceDir}" + "--app-version=${global.ci.av}" + "--faa-path=${#env('FORTIFY_AGENTIC_ANALYZER_HOME')}" + ${global.faaScan.fprDownloaded ? ' --fpr-file=' + global.faaScan.fprFile : ''} + ${#isNotBlank(#env('FAA_SCAN_OUTPUT_PATH')) ? '--output=' + #env('FAA_SCAN_OUTPUT_PATH') : ''} + "--skip-wait=${#env('FAA_SKIP_WAIT')?:'true'}" + skip.if-reason: + - ${faa.skipReason} + AVIATOR_AUDIT: cmd: ${#fcliCmd('AVIATOR_AUDIT', 'aviator ssc audit')} --aviator-session ${sessionName} --av "${global.ci.av}" --app "${aviator.app}" --store aviator_audit skip.if-reason: diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml new file mode 100644 index 00000000000..552c013edfd --- /dev/null +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml @@ -0,0 +1,110 @@ +# yaml-language-server: $schema=https://fortify.github.io/fcli/schemas/action/fcli-action-schema-dev-2.x.json + +author: Fortify +usage: + header: (PREVIEW) Run Fortify Agentic Analyzer Scan + description: | + This action can be used to run a Fortify Agentic Analyzer (FAA) scan of the project + and optionally upload the results to SSC as a SARIF report. + + Optionally, you can provide the FPR file from a prior SAST scan. When provided, + FAA uses this context to avoid reporting duplicate issues that were already found + by the SAST scan, resulting in higher quality analysis results. + +config: + output: immediate + rest.target.default: ssc + run.fcli.status.log.default: true # By default, we log all exit statuses + run.fcli.status.check.default: true + mcp: exclude # FAA is a specialized tool requiring specific setup + +# NOTE: When updating any options, ci action may also need to be updated +cli.options: + sourceDir: + names: --source-dir, -d + description: >- + Source directory on which to run Fortify Agentic Analyzer scan. + Defaults to current working directory if not specified. + required: true + fprFile: + names: --fpr, -f + description: >- + Optional path to the FPR file from a prior SAST scan. When provided, FAA uses this + context to avoid reporting duplicate issues already identified by SAST, resulting in + enhanced analysis quality. If not provided, FAA will perform a standalone analysis. + required: false + appVersion: + names: --app-version, --av + description: >- + Optional SSC application version to which the FAA scan results (SARIF) must be uploaded. If not specified, FAA scan will run and write results to the output file, but SARIF will not be uploaded to SSC. Application version must already exist in SSC if specified. + required: false + output: + names: --output, -o + description: >- + Output SARIF file path where FAA scan results will be written. + Defaults to fortifyaa.sarif in the current working directory. + required: false + default: fortifyaa.sarif + faaPath: + names: --faa-path, -p + description: | + Path to a pre-installed Fortify Agentic Analyzer (FAA) installation. + FAA must be pre-installed on the system before running this action; + this action only registers the existing installation with fcli. + Defaults to the FORTIFY_AGENTIC_ANALYZER_HOME environment variable. + Required: User must have FAA already installed and FORTIFY_AGENTIC_ANALYZER_HOME set. + required: true + extraScanOpts: + names: --extra-scan-opts + description: >- + Extra options to be passed to the 'fortifyaa -scan' command. + required: false + skipWait: + names: --skip-wait + description: >- + By default, the action will wait for the SARIF artifact upload to complete. Use this option to skip + waiting for the upload to complete. + required: false + type: boolean + default: true + +steps: + - var.set: + # Used for passing extra options from ci action without bothering about escaping + extraScanOpts: ${#join(" ", {cli.extraScanOpts, global.faaScan?.extraOpts})} + global.faaScanUpload.fcliVarName: faa_scan_${#action.runID().replace('-','_')} + global.faaScanUpload.waitForCmd: 'fcli ssc artifact wait-for ::${global.faaScanUpload.fcliVarName}::' + + - run.fcli: + SETUP_TOOLS: fcli tool env init "--tools=fortifyaa:${cli.faaPath}" + RUN_FAA_SCAN: + cmd: > + fcli tool fortifyaa run -- + -clean + -scan "${cli.sourceDir}" + ${#isNotBlank(cli.fprFile) ? '--fpr "' + cli.fprFile + '"' : ''} + -o "${cli.output}" + ${extraScanOpts} + stdout: collect + stderr: collect + on.success: + - out.write: + stdout: ${RUN_FAA_SCAN.stdout} + stderr: ${RUN_FAA_SCAN.stderr} + on.fail: + - out.write: + stdout: ${RUN_FAA_SCAN.stdout} + stderr: ${RUN_FAA_SCAN.stderr} + - throw: FAA Scan failed with errors. + UPLOAD_SARIF: + cmd: > + fcli ssc artifact upload + --av "${cli.appVersion}" + --engine-type Fortify_AA + -f "${cli.output}" + --store "${global.faaScanUpload.fcliVarName}" + status.check: false + + - if: ${!cli.skipWait} + run.fcli: + WAIT: ${global.faaScanUpload.waitForCmd} From 5eef2ad1329d607d472bf1335509274a1f2a82a3 Mon Sep 17 00:00:00 2001 From: Sangamesh Vijaykumar Date: Tue, 13 Oct 2026 16:26:16 +0530 Subject: [PATCH 2/6] chore: fix option name --- .../src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml index 3b16f9c454a..808ea5b5742 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml @@ -222,7 +222,7 @@ steps: "--source-dir=${global.ci.sourceDir}" "--app-version=${global.ci.av}" "--faa-path=${#env('FORTIFY_AGENTIC_ANALYZER_HOME')}" - ${global.faaScan.fprDownloaded ? ' --fpr-file=' + global.faaScan.fprFile : ''} + ${global.faaScan.fprDownloaded ? ' --fpr=' + global.faaScan.fprFile : ''} ${#isNotBlank(#env('FAA_SCAN_OUTPUT_PATH')) ? '--output=' + #env('FAA_SCAN_OUTPUT_PATH') : ''} "--skip-wait=${#env('FAA_SKIP_WAIT')?:'true'}" skip.if-reason: From 33cb3a73d353ea778dbd0817c4a8fa245af0892b Mon Sep 17 00:00:00 2001 From: Sangamesh Vijaykumar Date: Wed, 14 Oct 2026 14:30:54 +0530 Subject: [PATCH 3/6] Update ci env vars help doc and fix faa-scan action options --- .../cli/app/actions/build-time/ci-doc.yaml | 29 +++++++++++--- .../com/fortify/cli/fod/actions/zip/ci.yaml | 2 - .../fortify/cli/fod/actions/zip/faa-scan.yaml | 39 ++++++++++++------- .../com/fortify/cli/ssc/actions/zip/ci.yaml | 3 -- .../fortify/cli/ssc/actions/zip/faa-scan.yaml | 35 ++++++++++------- .../cli/tool/i18n/ToolMessages.properties | 4 +- 6 files changed, 72 insertions(+), 40 deletions(-) diff --git a/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml b/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml index d962bd35d9a..f47de7cd01e 100644 --- a/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml +++ b/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml @@ -215,7 +215,7 @@ formatters: \n* Debug logging for Scancentral Client is disabled; pass --debug on the fcli invocation to enable debug logging. - title: Scan Execution overview: >- - Configure SAST scan execution and waiting behavior for ${productNames.fod}. + Configure SAST, FAA scan execution and waiting behavior for ${productNames.fod}. vars: - names: DO_SAST_SCAN\nSAST_SCAN_EXTRA_OPTS desc: >- @@ -230,6 +230,15 @@ formatters: `false` to just kick off any configured scans without waiting for completion. Note that doing so will skip any post-scan tasks. The `SAST_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli fod sast-scan wait-for: command. + - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME\nFAA_SCAN_FPR_FILE\nFAA_SCAN_OUTPUT_PATH + desc: >- + The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan. + The `DO_FAA_SCAN` environment variable can be set to `false` to disable the FAA scan. + The `FAA_SCAN_EXTRA_OPTS` environment variable can be used to provide additional options to + the `fortifyaa -scan` command. + The `FAA_HOME` environment variable can be used to specify the path to a pre-installed FAA installation. + The `FAA_SCAN_FPR_FILE` environment variable can be used to specify the FPR file from a prior SAST scan. + The `FAA_SCAN_OUTPUT_PATH` environment variable can be used to specify the output path for the FAA scan results. - title: Post-Scan Actions overview: > Configure post-scan tasks including release summaries, policy checks, pull request comments, and @@ -353,7 +362,7 @@ formatters: \n* Debug logging for Scancentral Client is disabled; pass --debug on the fcli invocation to enable debug logging. - title: Scan Execution overview: >- - Configure SAST, DAST, and Debricked scan execution and waiting behavior for ${productNames.ssc}. + Configure SAST, DAST, Fortify Agentic Analyzer (FAA) and Debricked scan execution and waiting behavior for ${productNames.ssc}. vars: - names: DO_SAST_SCAN\nSAST_SCAN_EXTRA_OPTS desc: >- @@ -377,7 +386,16 @@ formatters: use a custom scan name instead. The `DAST_SCAN_EXTRA_OPTS` environment variable can be used to provide additional options to the fcliCmd:fcli sc-dast scan start: command. Note that these environment variables only control the submission of the scan request; see the information below - for details on waiting for the scan to complete. + for details on waiting for the scan to complete. + - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME\nFAA_SCAN_FPR_FILE\nFAA_SCAN_OUTPUT_PATH + desc: >- + The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan. + The `DO_FAA_SCAN` environment variable can be set to `false` to disable the FAA scan. + The `FAA_SCAN_EXTRA_OPTS` environment variable can be used to provide additional options to + the `fortifyaa -scan` command. + The `FAA_HOME` environment variable can be used to specify the path to a pre-installed FAA installation. + The `FAA_SCAN_FPR_FILE` environment variable can be used to specify the FPR file from a prior SAST scan. + The `FAA_SCAN_OUTPUT_PATH` environment variable can be used to specify the output path for the FAA scan results. - names: DO_DEBRICKED_SCAN\nDEBRICKED_SCAN_EXTRA_OPTS\nDEBRICKED_ACCESS_TOKEN\nDEBRICKED_VERSION\nDEBRICKED_HOME desc: >- The fcli `ci` action supports running a Debricked Software Composition Analysis (SCA) scan, which @@ -392,14 +410,15 @@ formatters: \n * `latest` to use the latest available Debricked CLI version \n * `auto` (default) to use a pre-installed version if available, otherwise installs latest \n* If neither `DEBRICKED_VERSION` nor `DEBRICKED_HOME` are set, defaults to `auto` behavior. - - names: DO_WAIT\nDO_SAST_WAIT\nSAST_WAIT_EXTRA_OPTS\nDO_DAST_WAIT\nDAST_WAIT_EXTRA_OPTS\nDEBRICKED_WAIT_EXTRA_OPTS + - names: DO_WAIT\nDO_SAST_WAIT\nSAST_WAIT_EXTRA_OPTS\nDO_DAST_WAIT\nDAST_WAIT_EXTRA_OPTS\nDO_FAA_WAIT\nFAA_WAIT_EXTRA_OPTS\nDEBRICKED_WAIT_EXTRA_OPTS desc: >- By default, the fcli `ci` action will wait for all started scans to complete; set `DO_WAIT` to `false` to just kick off any configured scans without waiting for completion. Note that doing so will skip any post-scan tasks. The `SAST_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli sc-sast scan wait-for: command, and similarly, the `DAST_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli sc-dast scan wait-for: command, - and the `DEBRICKED_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the + the `FAA_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the + fcliCmd:fcli fortifyaa scan wait-for: command, and the `DEBRICKED_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli ssc artifact wait-for: command.\n\nUnlike other scan types, waiting for DAST scans is disabled by default (as DAST scans are often long-running and only run on demand); set `DO_DAST_WAIT` to `true` to wait for DAST scan completion.\n\nDAST scans can take considerably longer than SAST scans, potentially diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml index 076bd6054a7..d0dedf26f4f 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml @@ -159,9 +159,7 @@ steps: ${#actionCmd('FAA_SCAN', 'fod', 'faa-scan')} "--source-dir=${global.ci.sourceDir}" "--release=${global.ci.rel}" - "--faa-path=${#env('FORTIFY_AGENTIC_ANALYZER_HOME')}" ${global.faaScan.fprDownloaded ? ' --fpr=' + global.faaScan.fprFile : ''} - ${#isNotBlank(#env('FAA_SCAN_OUTPUT_PATH')) ? '--output=' + #env('FAA_SCAN_OUTPUT_PATH') : ''} skip.if-reason: - ${faa.skipReason} # Skip if FAA scan is disabled diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml index 00f1ca81360..520d8463788 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml @@ -24,36 +24,41 @@ cli.options: names: --source-dir, -d description: >- Source directory on which to run Fortify Agentic Analyzer scan. - Defaults to current working directory if not specified. - required: true - fprFile: + Defaults to environment variable `SOURCE_DIR` if not specified. + default: ${#env('SOURCE_DIR')} + required: false + sastFprFile: names: --fpr, -f description: >- Optional path to the FPR file from a prior SAST scan. When provided, FAA uses this context to avoid reporting duplicate issues already identified by SAST, resulting in enhanced analysis quality. If not provided, FAA will perform a standalone analysis. required: false + default: ${#env('FAA_SCAN_FPR_FILE')} release: names: --release, --rel description: >- Optional FoD release to which the FAA scan results (SARIF) must be imported. If not specified, FAA scan will run and write results to the output file, but SARIF will not be imported to FoD. Release must already exist in FoD if specified. required: false - output: + default: ${#env('FOD_RELEASE')} + faaOutput: names: --output, -o description: >- Output SARIF file path where FAA scan results will be written. - Defaults to fortifyaa.sarif in the current working directory. + Defaults to the environment variable `FAA_SCAN_OUTPUT_PATH` if not specified. + If the environment variable is not set, defaults to fortifyaa.sarif in the current working directory. required: false - default: fortifyaa.sarif + default: ${#ifBlank(#env('FAA_SCAN_OUTPUT_PATH'), 'fortifyaa.sarif')} faaPath: names: --faa-path, -p - description: | + description: >- Path to a pre-installed Fortify Agentic Analyzer (FAA) installation. FAA must be pre-installed on the system before running this action; this action only registers the existing installation with fcli. - Defaults to the FORTIFY_AGENTIC_ANALYZER_HOME environment variable. - Required: User must have FAA already installed and FORTIFY_AGENTIC_ANALYZER_HOME set. - required: true + Defaults to the FAA_HOME environment variable. + Required: User must have FAA already installed and FAA_HOME set. + required: false + default: ${#env('FAA_HOME')} extraScanOpts: names: --extra-scan-opts description: >- @@ -64,16 +69,20 @@ steps: - var.set: # Used for passing extra options from ci action without bothering about escaping extraScanOpts: ${#join(" ", {cli.extraScanOpts, global.faaScan?.extraOpts})} + fprArg: >- + ${#isNotBlank(cli.sastFprFile) ? '--fpr "' + cli.sastFprFile + '"' : ''} - run.fcli: - SETUP_TOOLS: fcli tool env init "--tools=fortifyaa:${cli.faaPath}" + SETUP_TOOLS: + cmd: >- + fcli tool env init "--tools=fortifyaa${#isNotBlank(cli.faaPath) ? ':' + cli.faaPath : ''}" RUN_FAA_SCAN: cmd: > - fcli tool fortifyaa run -- + fcli tool fortifyaa run -- -clean -scan "${cli.sourceDir}" - ${#isNotBlank(cli.fprFile) ? '--fpr "' + cli.fprFile + '"' : ''} - -o "${cli.output}" + ${fprArg} + -o "${cli.faaOutput}" ${extraScanOpts} stdout: collect stderr: collect @@ -90,5 +99,5 @@ steps: cmd: > fcli fod sast-scan import-sarif --rel "${cli.release}" - -f "${cli.output}" + -f "${cli.faaOutput}" status.check: false diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml index 808ea5b5742..e78f659ec68 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml @@ -221,10 +221,7 @@ steps: ${#actionCmd('FAA_SCAN', 'ssc', 'faa-scan')} "--source-dir=${global.ci.sourceDir}" "--app-version=${global.ci.av}" - "--faa-path=${#env('FORTIFY_AGENTIC_ANALYZER_HOME')}" ${global.faaScan.fprDownloaded ? ' --fpr=' + global.faaScan.fprFile : ''} - ${#isNotBlank(#env('FAA_SCAN_OUTPUT_PATH')) ? '--output=' + #env('FAA_SCAN_OUTPUT_PATH') : ''} - "--skip-wait=${#env('FAA_SKIP_WAIT')?:'true'}" skip.if-reason: - ${faa.skipReason} diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml index 552c013edfd..f9a1f3221e2 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml @@ -24,36 +24,41 @@ cli.options: names: --source-dir, -d description: >- Source directory on which to run Fortify Agentic Analyzer scan. - Defaults to current working directory if not specified. - required: true - fprFile: + Defaults to environment variable `SOURCE_DIR` if not specified. + default: ${#env('SOURCE_DIR')} + required: false + sastFprFile: names: --fpr, -f description: >- Optional path to the FPR file from a prior SAST scan. When provided, FAA uses this context to avoid reporting duplicate issues already identified by SAST, resulting in enhanced analysis quality. If not provided, FAA will perform a standalone analysis. required: false + default: ${#env('FAA_SCAN_FPR_FILE')} appVersion: names: --app-version, --av description: >- Optional SSC application version to which the FAA scan results (SARIF) must be uploaded. If not specified, FAA scan will run and write results to the output file, but SARIF will not be uploaded to SSC. Application version must already exist in SSC if specified. required: false - output: + default: ${#env('APP_VERSION')} + faaOutput: names: --output, -o description: >- Output SARIF file path where FAA scan results will be written. - Defaults to fortifyaa.sarif in the current working directory. + Defaults to the environment variable `FAA_SCAN_OUTPUT_PATH` if not specified. + If the environment variable is not set, defaults to fortifyaa.sarif in the current working directory. required: false - default: fortifyaa.sarif + default: ${#ifBlank(#env('FAA_SCAN_OUTPUT_PATH'), 'fortifyaa.sarif')} faaPath: names: --faa-path, -p description: | Path to a pre-installed Fortify Agentic Analyzer (FAA) installation. FAA must be pre-installed on the system before running this action; this action only registers the existing installation with fcli. - Defaults to the FORTIFY_AGENTIC_ANALYZER_HOME environment variable. - Required: User must have FAA already installed and FORTIFY_AGENTIC_ANALYZER_HOME set. - required: true + Defaults to the FAA_HOME environment variable. + Required: User must have FAA already installed and FAA_HOME set. + required: false + default: ${#env('FAA_HOME')} extraScanOpts: names: --extra-scan-opts description: >- @@ -72,18 +77,22 @@ steps: - var.set: # Used for passing extra options from ci action without bothering about escaping extraScanOpts: ${#join(" ", {cli.extraScanOpts, global.faaScan?.extraOpts})} + fprArg: >- + ${#isNotBlank(cli.sastFprFile) ? '--fpr "' + cli.sastFprFile + '"' : ''} global.faaScanUpload.fcliVarName: faa_scan_${#action.runID().replace('-','_')} global.faaScanUpload.waitForCmd: 'fcli ssc artifact wait-for ::${global.faaScanUpload.fcliVarName}::' - run.fcli: - SETUP_TOOLS: fcli tool env init "--tools=fortifyaa:${cli.faaPath}" + SETUP_TOOLS: + cmd: >- + fcli tool env init "--tools=fortifyaa${#isNotBlank(cli.faaPath) ? ':' + cli.faaPath : ''}" RUN_FAA_SCAN: cmd: > fcli tool fortifyaa run -- -clean -scan "${cli.sourceDir}" - ${#isNotBlank(cli.fprFile) ? '--fpr "' + cli.fprFile + '"' : ''} - -o "${cli.output}" + ${fprArg} + -o "${cli.faaOutput}" ${extraScanOpts} stdout: collect stderr: collect @@ -101,7 +110,7 @@ steps: fcli ssc artifact upload --av "${cli.appVersion}" --engine-type Fortify_AA - -f "${cli.output}" + -f "${cli.faaOutput}" --store "${global.faaScanUpload.fcliVarName}" status.check: false diff --git a/fcli-core/fcli-tool/src/main/resources/com/fortify/cli/tool/i18n/ToolMessages.properties b/fcli-core/fcli-tool/src/main/resources/com/fortify/cli/tool/i18n/ToolMessages.properties index 66b239c3686..07c5d366309 100644 --- a/fcli-core/fcli-tool/src/main/resources/com/fortify/cli/tool/i18n/ToolMessages.properties +++ b/fcli-core/fcli-tool/src/main/resources/com/fortify/cli/tool/i18n/ToolMessages.properties @@ -496,9 +496,9 @@ fcli.tool.fortifyaa.register.usage.header = Register an external Fortify Agentic fcli.tool.fortifyaa.register.usage.description.0 = ${fcli.tool.register.generic-description} fcli.tool.fortifyaa.register.usage.description.1 = Examples:\n\ \ --path /opt/fortify/tools/fortifyaa\n\ - \ --path $FORTIFY_AGENTIC_ANALYZER_HOME\n\ + \ --path $FAA_HOME\n\ \ --path $PATH\n\ - \ --path $FORTIFY_AGENTIC_ANALYZER_HOME:$PATH\n + \ --path $FAA_HOME:$PATH\n fcli.tool.fortifyaa.run.usage.header = Run Fortify Agentic Analyzer. fcli.tool.fortifyaa.run.usage.description = This command allows for running Fortify Agentic Analyzer as already installed in the user's machine. It is recommended to use double dashes to separate \ From a79956148b763570446f7e082bc5a4e7437f427c Mon Sep 17 00:00:00 2001 From: Sangamesh Vijaykumar Date: Mon, 19 Oct 2026 10:23:34 +0530 Subject: [PATCH 4/6] ci(doc): Update help documentation --- .../cli/app/actions/build-time/ci-doc.yaml | 18 ++++++++---------- .../fortify/cli/fod/actions/zip/faa-scan.yaml | 3 +-- .../fortify/cli/ssc/actions/zip/faa-scan.yaml | 3 +-- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml b/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml index f47de7cd01e..1ca360bad17 100644 --- a/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml +++ b/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml @@ -230,15 +230,14 @@ formatters: `false` to just kick off any configured scans without waiting for completion. Note that doing so will skip any post-scan tasks. The `SAST_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli fod sast-scan wait-for: command. - - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME\nFAA_SCAN_FPR_FILE\nFAA_SCAN_OUTPUT_PATH + - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME desc: >- The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan. - The `DO_FAA_SCAN` environment variable can be set to `false` to disable the FAA scan. + The `DO_FAA_SCAN` environment variable can be set to `true` to enable the FAA scan. The `FAA_SCAN_EXTRA_OPTS` environment variable can be used to provide additional options to the `fortifyaa -scan` command. - The `FAA_HOME` environment variable can be used to specify the path to a pre-installed FAA installation. - The `FAA_SCAN_FPR_FILE` environment variable can be used to specify the FPR file from a prior SAST scan. - The `FAA_SCAN_OUTPUT_PATH` environment variable can be used to specify the output path for the FAA scan results. + If `FAA_HOME` is specified, the pre-installed FAA at that location will be registered and used. If not set, + `fcli tool env init --tools=fortifyaa` will attempt to auto-detect and register any available FAA installation. - title: Post-Scan Actions overview: > Configure post-scan tasks including release summaries, policy checks, pull request comments, and @@ -387,15 +386,14 @@ formatters: to provide additional options to the fcliCmd:fcli sc-dast scan start: command. Note that these environment variables only control the submission of the scan request; see the information below for details on waiting for the scan to complete. - - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME\nFAA_SCAN_FPR_FILE\nFAA_SCAN_OUTPUT_PATH + - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME desc: >- The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan. - The `DO_FAA_SCAN` environment variable can be set to `false` to disable the FAA scan. + The `DO_FAA_SCAN` environment variable can be set to `true` to enable the FAA scan. The `FAA_SCAN_EXTRA_OPTS` environment variable can be used to provide additional options to the `fortifyaa -scan` command. - The `FAA_HOME` environment variable can be used to specify the path to a pre-installed FAA installation. - The `FAA_SCAN_FPR_FILE` environment variable can be used to specify the FPR file from a prior SAST scan. - The `FAA_SCAN_OUTPUT_PATH` environment variable can be used to specify the output path for the FAA scan results. + If `FAA_HOME` is specified, the pre-installed FAA at that location will be registered and used. If not set, + `fcli tool env init --tools=fortifyaa` will attempt to auto-detect and register any available FAA installation. - names: DO_DEBRICKED_SCAN\nDEBRICKED_SCAN_EXTRA_OPTS\nDEBRICKED_ACCESS_TOKEN\nDEBRICKED_VERSION\nDEBRICKED_HOME desc: >- The fcli `ci` action supports running a Debricked Software Composition Analysis (SCA) scan, which diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml index 520d8463788..25e8bf3f93d 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml @@ -34,7 +34,6 @@ cli.options: context to avoid reporting duplicate issues already identified by SAST, resulting in enhanced analysis quality. If not provided, FAA will perform a standalone analysis. required: false - default: ${#env('FAA_SCAN_FPR_FILE')} release: names: --release, --rel description: >- @@ -48,7 +47,7 @@ cli.options: Defaults to the environment variable `FAA_SCAN_OUTPUT_PATH` if not specified. If the environment variable is not set, defaults to fortifyaa.sarif in the current working directory. required: false - default: ${#ifBlank(#env('FAA_SCAN_OUTPUT_PATH'), 'fortifyaa.sarif')} + default: fortifyaa-scan.sarif faaPath: names: --faa-path, -p description: >- diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml index f9a1f3221e2..9d35a0f7acb 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml @@ -34,7 +34,6 @@ cli.options: context to avoid reporting duplicate issues already identified by SAST, resulting in enhanced analysis quality. If not provided, FAA will perform a standalone analysis. required: false - default: ${#env('FAA_SCAN_FPR_FILE')} appVersion: names: --app-version, --av description: >- @@ -48,7 +47,7 @@ cli.options: Defaults to the environment variable `FAA_SCAN_OUTPUT_PATH` if not specified. If the environment variable is not set, defaults to fortifyaa.sarif in the current working directory. required: false - default: ${#ifBlank(#env('FAA_SCAN_OUTPUT_PATH'), 'fortifyaa.sarif')} + default: fortifyaa-scan.sarif faaPath: names: --faa-path, -p description: | From d38fc299fc2dee2daf5b2995b9cd46ae6c41a473 Mon Sep 17 00:00:00 2001 From: Sangamesh Vijaykumar Date: Wed, 21 Oct 2026 20:32:28 +0530 Subject: [PATCH 5/6] feat: Integrate faa-scan action in to ci actions of both SSC and FoD. --- .../com/fortify/cli/fod/actions/zip/ci.yaml | 17 +--- .../fortify/cli/fod/actions/zip/faa-scan.yaml | 51 ++++++++++++ .../com/fortify/cli/ssc/actions/zip/ci.yaml | 14 +--- .../fortify/cli/ssc/actions/zip/faa-scan.yaml | 78 +++++++++++++++++++ 4 files changed, 133 insertions(+), 27 deletions(-) diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml index d0dedf26f4f..d43f0eedd39 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml @@ -69,8 +69,6 @@ steps: ${ #fcliCmdSkipFromEnvReason('FAA_SCAN', true) } - global.faaScan.fprFile: faa_input_${#action.runID().replace('-','_')}.fpr - global.faaScan.fprDownloaded: false # Post-scan tasks will be skipped if wait is skipped or if no scans were completed # successfully. Post-scan skip reason will be reset to null once the wait task for @@ -142,24 +140,13 @@ steps: on.success: - var.set: { postScan.skipReason: } # Reset postScan.skipReason to allow post-scan tasks to run - DOWNLOAD_SAST_FPR: - cmd: > - ${#fcliCmd('DOWNLOAD_SAST_FPR', 'fod sast-scan download-latest')} - -f="${global.faaScan.fprFile}" - --rel="${global.ci.rel}" - skip.if-reason: - - ${SAST_WAIT.dependencySkipReason} # Skip if SAST_WAIT was skipped or failed - - ${faa.skipReason} # Skip if FAA scan is disabled - on.success: - - var.set: { global.faaScan.fprDownloaded: true } - status.check: false - + # Pass SAST scan ID if SAST scan was started; otherwise, disable SAST FPR download FAA_SCAN: cmd: > ${#actionCmd('FAA_SCAN', 'fod', 'faa-scan')} "--source-dir=${global.ci.sourceDir}" "--release=${global.ci.rel}" - ${global.faaScan.fprDownloaded ? ' --fpr=' + global.faaScan.fprFile : ''} + ${#isBlank(SAST_SCAN.dependencySkipReason) ? '"--sast-scan-id=::fod_sast_scan::"' : '"--skip-sast-download=true"'} skip.if-reason: - ${faa.skipReason} # Skip if FAA scan is disabled diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml index 25e8bf3f93d..9c81c90c32f 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml @@ -10,6 +10,14 @@ usage: Optionally, you can provide the FPR file from a prior SAST scan. When provided, FAA uses this context to avoid reporting duplicate issues that were already found by the SAST scan, resulting in higher quality analysis results. + + If --fpr is not specified, SAST results are downloaded automatically: + - When --sast-scan-id is specified, the action waits for the FoD SAST scan to + complete and downloads the FPR for that scan. + - Otherwise, when --release is specified, the action downloads the latest SAST + scan FPR for that release. + If no SAST results are available or the download fails, FAA runs without SAST + results. Use --skip-sast-download to disable automatic download. config: output: immediate @@ -40,6 +48,21 @@ cli.options: Optional FoD release to which the FAA scan results (SARIF) must be imported. If not specified, FAA scan will run and write results to the output file, but SARIF will not be imported to FoD. Release must already exist in FoD if specified. required: false default: ${#env('FOD_RELEASE')} + sastScanId: + names: --sast-scan-id + description: >- + Optional FoD SAST scan ID, usually passed by the ci action. When specified and --fpr + is not, this action waits for the scan to complete, downloads the FPR for this scan, + and passes it to FAA. + required: false + skipSastDownload: + names: --skip-sast-download + description: >- + Skip automatic SAST FPR download. FAA runs without SAST results unless --fpr is + specified. + required: false + type: boolean + default: false faaOutput: names: --output, -o description: >- @@ -70,6 +93,34 @@ steps: extraScanOpts: ${#join(" ", {cli.extraScanOpts, global.faaScan?.extraOpts})} fprArg: >- ${#isNotBlank(cli.sastFprFile) ? '--fpr "' + cli.sastFprFile + '"' : ''} + sastFprFile: faa_input_${#action.runID().replace('-','_')}.fpr + + # Download SAST results for the FoD SAST scan started by the ci action + - if: >- + ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isNotBlank(cli.sastScanId)} + run.fcli: + SAST_WAIT: + cmd: fcli fod sast-scan wait-for "${cli.sastScanId}" + status.check: false + DOWNLOAD_SAST_FPR: + cmd: fcli fod sast-scan download "${cli.sastScanId}" -f "${sastFprFile}" + skip.if-reason: + - ${SAST_WAIT.dependencySkipReason} + status.check: false + on.success: + - var.set: + fprArg: '--fpr "${sastFprFile}"' + + # Download latest SAST results for the release when running standalone + - if: >- + ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isBlank(cli.sastScanId) && #isNotBlank(cli.release)} + run.fcli: + DOWNLOAD_LATEST_SAST_FPR: + cmd: fcli fod sast-scan download-latest --rel "${cli.release}" -f "${sastFprFile}" + status.check: false + on.success: + - var.set: + fprArg: '--fpr "${sastFprFile}"' - run.fcli: SETUP_TOOLS: diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml index e78f659ec68..b5b82f2aa70 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml @@ -82,8 +82,6 @@ steps: ${ #fcliCmdSkipFromEnvReason('FAA_SCAN', true) } - global.faaScan.fprFile: faa_input_${#action.runID().replace('-','_')}.fpr - global.faaScan.fprDownloaded: false aviator.skipReason: > # Enabled if AVIATOR_TOKEN & AVIATOR_URL specified, unless explicitly disabled ${ @@ -207,21 +205,13 @@ steps: - ${SAST_WAIT.dependencySkipReason} # Skip if SAST_WAIT was skipped or failed - ${#isDebugEnabled()?'':'--debug flag not specified'} # Skip if debugging is disabled - DOWNLOAD_SAST_FPR: - cmd: "${#fcliCmd('DOWNLOAD_SAST_FPR', 'sc-sast scan download -t fpr -f')} ${global.faaScan.fprFile} ::sc_sast_scan::" - skip.if-reason: - - ${SAST_WAIT.dependencySkipReason} # Skip if SAST_WAIT was skipped or failed - - ${faa.skipReason} # Skip if FAA scan is disabled - on.success: - - var.set: { global.faaScan.fprDownloaded: true } - status.check: false - + # Pass SAST job token if SAST scan was started; otherwise, disable SAST FPR download FAA_SCAN: cmd: > ${#actionCmd('FAA_SCAN', 'ssc', 'faa-scan')} "--source-dir=${global.ci.sourceDir}" "--app-version=${global.ci.av}" - ${global.faaScan.fprDownloaded ? ' --fpr=' + global.faaScan.fprFile : ''} + ${#isBlank(SAST_SCAN.dependencySkipReason) ? '"--sast-job-token=::sc_sast_scan::"' : '"--skip-sast-download=true"'} skip.if-reason: - ${faa.skipReason} diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml index 9d35a0f7acb..8c12fc2f83b 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml @@ -10,6 +10,14 @@ usage: Optionally, you can provide the FPR file from a prior SAST scan. When provided, FAA uses this context to avoid reporting duplicate issues that were already found by the SAST scan, resulting in higher quality analysis results. + + If --fpr is not specified, SAST results are downloaded automatically: + - When --sast-job-token is specified, the action waits for the ScanCentral SAST job + results to be processed and downloads the FPR for that job. + - Otherwise, when --app-version is specified, the action downloads the latest + processed SAST artifact for that application version. + If no SAST results are available or the download fails, FAA runs without SAST + results. Use --skip-sast-download to disable automatic download. config: output: immediate @@ -40,6 +48,21 @@ cli.options: Optional SSC application version to which the FAA scan results (SARIF) must be uploaded. If not specified, FAA scan will run and write results to the output file, but SARIF will not be uploaded to SSC. Application version must already exist in SSC if specified. required: false default: ${#env('APP_VERSION')} + sastJobToken: + names: --sast-job-token + description: >- + Optional ScanCentral SAST job token, usually passed by the ci action. When specified + and --fpr is not, this action waits for the job results to be processed, downloads + the FPR for this job, and passes it to FAA. + required: false + skipSastDownload: + names: --skip-sast-download + description: >- + Skip automatic SAST FPR download. FAA runs without SAST results unless --fpr is + specified. + required: false + type: boolean + default: false faaOutput: names: --output, -o description: >- @@ -80,6 +103,61 @@ steps: ${#isNotBlank(cli.sastFprFile) ? '--fpr "' + cli.sastFprFile + '"' : ''} global.faaScanUpload.fcliVarName: faa_scan_${#action.runID().replace('-','_')} global.faaScanUpload.waitForCmd: 'fcli ssc artifact wait-for ::${global.faaScanUpload.fcliVarName}::' + sastFprFile: faa_input_${#action.runID().replace('-','_')}.fpr + sastArtifactId: null + + # Download SAST results for the ScanCentral SAST job started by the ci action + - if: >- + ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isNotBlank(cli.sastJobToken)} + run.fcli: + SAST_WAIT: + cmd: fcli sc-sast scan wait-for "${cli.sastJobToken}" + status.check: false + DOWNLOAD_SAST_FPR: + cmd: fcli sc-sast scan download "${cli.sastJobToken}" -t fpr -f "${sastFprFile}" + skip.if-reason: + - ${SAST_WAIT.dependencySkipReason} + status.check: false + on.success: + - var.set: + fprArg: '--fpr "${sastFprFile}"' + + # Download latest processed SAST results for the application version when running standalone + - if: >- + ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isBlank(cli.sastJobToken) && #isNotBlank(cli.appVersion)} + do: + - var.set: + sastAv: ${#ssc.appVersion(cli.appVersion)} + - rest.call: + sastArtifacts: + uri: /api/v1/projectVersions/${sastAv.id}/artifacts + type: paged + query: + embed: scans + orderby: uploadDate DESC + records.for-each: + record.var-name: artifact + breakIf: ${sastArtifactId!=null} + do: + - if: >- + ${artifact.status=='PROCESS_COMPLETE' && artifact._embed.scans?.^[type=='SCA']!=null} + var.set: + sastArtifactId: ${artifact.id} + - if: ${sastArtifactId==null} + log.info: No processed SAST artifact found; running FAA without SAST results + on.fail: + - log.warn: + msg: Unable to determine latest SAST artifact; running FAA without SAST results + cause: ${lastException} + + - if: ${sastArtifactId!=null} + run.fcli: + DOWNLOAD_LATEST_SAST_FPR: + cmd: fcli ssc artifact download "${sastArtifactId}" -f "${sastFprFile}" + status.check: false + on.success: + - var.set: + fprArg: '--fpr "${sastFprFile}"' - run.fcli: SETUP_TOOLS: From c3db6ec77a55ffd7f5c5da1c0f941c88aa11dbb0 Mon Sep 17 00:00:00 2001 From: Sangamesh Vijaykumar Date: Wed, 28 Oct 2026 13:23:17 +0530 Subject: [PATCH 6/6] fix: Move SAST results download step from CI action to faa-scan action --- .../cli/generic_action/actions/zip/ci.yaml | 18 ++- .../cli/app/actions/build-time/ci-doc.yaml | 48 ++++--- .../com/fortify/cli/fod/actions/zip/ci.yaml | 23 ++-- .../fortify/cli/fod/actions/zip/faa-scan.yaml | 98 +++++---------- .../com/fortify/cli/ssc/actions/zip/ci.yaml | 38 ++++-- .../fortify/cli/ssc/actions/zip/faa-scan.yaml | 119 ++++++------------ 6 files changed, 154 insertions(+), 190 deletions(-) diff --git a/fcli-core/fcli-action/src/main/resources/com/fortify/cli/generic_action/actions/zip/ci.yaml b/fcli-core/fcli-action/src/main/resources/com/fortify/cli/generic_action/actions/zip/ci.yaml index c1d2fd0d97d..ff8a21e7d0c 100644 --- a/fcli-core/fcli-action/src/main/resources/com/fortify/cli/generic_action/actions/zip/ci.yaml +++ b/fcli-core/fcli-action/src/main/resources/com/fortify/cli/generic_action/actions/zip/ci.yaml @@ -4,15 +4,23 @@ author: Fortify usage: header: Run CI pipeline description: | - This action can be used to run a full, standardized CI pipeline that performs the - following activities: + This action runs a standardized CI pipeline against either FoD or SSC, depending on + whether `FOD_URL` or `SSC_URL` is set. Depending on the configured scan types and + options, the pipeline performs the following activities: * Create & configure SSC application version / FoD release if needed * Install ScanCentral Client for packaging * Package source code using ScanCentral Client * Submit SAST scan request - * Wait for SAST scan completion - * Perform post-scan activities, like checking security policy outcome, exporting results, ... + * Optionally submit DAST scan request using pre-existing SC-DAST scan settings (SSC only) + * Optionally run Debricked software composition analysis (SCA) and publish results (SSC only) + * Wait for scan completion as configured + * Optionally run a Fortify Agentic Analyzer (FAA) scan, using the latest available SAST + results as context, and import (FoD) or upload (SSC) the FAA results as a SARIF report + * Optionally run an Aviator audit (SSC) or enable Aviator audits in the release + settings (FoD), and optionally apply Aviator remediations + * Perform configured post-scan activities, such as policy checks, summaries, + pull request comments, and result exports Configuration for this fcli action is done through environment variables; the sections below list the environment variables supported by this action. @@ -112,4 +120,4 @@ steps: - run.fcli: ci: ${#actionCmd(ciEnvPrefix, module, 'ci')} "--${module}-session=${sessionName}" - \ No newline at end of file + diff --git a/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml b/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml index 1ca360bad17..cf9d94a6148 100644 --- a/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml +++ b/fcli-core/fcli-app/src/main/resources/com/fortify/cli/app/actions/build-time/ci-doc.yaml @@ -230,14 +230,20 @@ formatters: `false` to just kick off any configured scans without waiting for completion. Note that doing so will skip any post-scan tasks. The `SAST_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli fod sast-scan wait-for: command. - - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME + - names: DO_FAA_SCAN\nFAA_HOME\nFAA_SCAN_EXTRA_OPTS desc: >- - The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan. - The `DO_FAA_SCAN` environment variable can be set to `true` to enable the FAA scan. - The `FAA_SCAN_EXTRA_OPTS` environment variable can be used to provide additional options to - the `fortifyaa -scan` command. - If `FAA_HOME` is specified, the pre-installed FAA at that location will be registered and used. If not set, - `fcli tool env init --tools=fortifyaa` will attempt to auto-detect and register any available FAA installation. + The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan, which is disabled by default. + Set `DO_FAA_SCAN` to `true` to enable the FAA scan, which is run through the fcli-provided actionRef:_:faa-scan + action. FAA must be pre-installed; + the FAA installation is taken from `FAA_HOME` if set, otherwise FAA is looked up in the system `PATH`. + \n\nThe latest available SAST scan results for the release are downloaded and passed to FAA for context-aware + analysis, allowing FAA to avoid reporting issues already found by SAST. As the `ci` action runs the FAA scan + after waiting for SAST scan completion (unless waiting is disabled), this usually includes the results from + the SAST scan started by the current pipeline. If no SAST results are available, FAA runs without SAST context. + FAA results are imported into ${productNames.fod} as a SARIF report; the `ci` action doesn't wait for this import + to be processed. + \n\nThe `FAA_SCAN_EXTRA_OPTS` environment variable can be used to pass extra options to the FAA scan action; + to pass extra options to the FAA scanner itself, use `FAA_SCAN_EXTRA_OPTS=--extra-scan-opts=""`. - title: Post-Scan Actions overview: > Configure post-scan tasks including release summaries, policy checks, pull request comments, and @@ -386,14 +392,20 @@ formatters: to provide additional options to the fcliCmd:fcli sc-dast scan start: command. Note that these environment variables only control the submission of the scan request; see the information below for details on waiting for the scan to complete. - - names: DO_FAA_SCAN\nFAA_SCAN_EXTRA_OPTS\nFAA_HOME + - names: DO_FAA_SCAN\nFAA_HOME\nFAA_SCAN_EXTRA_OPTS desc: >- - The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan. - The `DO_FAA_SCAN` environment variable can be set to `true` to enable the FAA scan. - The `FAA_SCAN_EXTRA_OPTS` environment variable can be used to provide additional options to - the `fortifyaa -scan` command. - If `FAA_HOME` is specified, the pre-installed FAA at that location will be registered and used. If not set, - `fcli tool env init --tools=fortifyaa` will attempt to auto-detect and register any available FAA installation. + The fcli `ci` action supports running a Fortify Agentic Analyzer (FAA) scan, which is disabled by default. + Set `DO_FAA_SCAN` to `true` to enable the FAA scan, which is run through the fcli-provided actionRef:_:faa-scan + action. FAA must be pre-installed; + the FAA installation is taken from `FAA_HOME` if set, otherwise FAA is looked up in the system `PATH`. + \n\nThe latest SAST scan results that have been fully processed by ${productNames.ssc} are downloaded and passed + to FAA for context-aware analysis, allowing FAA to avoid reporting issues already found by SAST. Note that if the + SAST scan started by the current pipeline hasn't been fully processed yet (for example because waiting is disabled + or the SAST scan failed), results from an earlier SAST scan will be used. If no processed SAST results are + available, FAA runs without SAST context. FAA results are uploaded to ${productNames.ssc} as a SARIF report, + and the FAA scan action waits for the uploaded report to be processed unless waiting is disabled through `DO_WAIT`. + \n\nThe `FAA_SCAN_EXTRA_OPTS` environment variable can be used to pass extra options to the FAA scan action; + to pass extra options to the FAA scanner itself, use `FAA_SCAN_EXTRA_OPTS=--extra-scan-opts=""`. - names: DO_DEBRICKED_SCAN\nDEBRICKED_SCAN_EXTRA_OPTS\nDEBRICKED_ACCESS_TOKEN\nDEBRICKED_VERSION\nDEBRICKED_HOME desc: >- The fcli `ci` action supports running a Debricked Software Composition Analysis (SCA) scan, which @@ -408,16 +420,16 @@ formatters: \n * `latest` to use the latest available Debricked CLI version \n * `auto` (default) to use a pre-installed version if available, otherwise installs latest \n* If neither `DEBRICKED_VERSION` nor `DEBRICKED_HOME` are set, defaults to `auto` behavior. - - names: DO_WAIT\nDO_SAST_WAIT\nSAST_WAIT_EXTRA_OPTS\nDO_DAST_WAIT\nDAST_WAIT_EXTRA_OPTS\nDO_FAA_WAIT\nFAA_WAIT_EXTRA_OPTS\nDEBRICKED_WAIT_EXTRA_OPTS + - names: DO_WAIT\nDO_SAST_WAIT\nSAST_WAIT_EXTRA_OPTS\nDO_DAST_WAIT\nDAST_WAIT_EXTRA_OPTS\nDEBRICKED_WAIT_EXTRA_OPTS desc: >- By default, the fcli `ci` action will wait for all started scans to complete; set `DO_WAIT` to `false` to just kick off any configured scans without waiting for completion. Note that doing so will skip any post-scan tasks. The `SAST_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli sc-sast scan wait-for: command, and similarly, the `DAST_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the fcliCmd:fcli sc-dast scan wait-for: command, - the `FAA_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the - fcliCmd:fcli fortifyaa scan wait-for: command, and the `DEBRICKED_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the - fcliCmd:fcli ssc artifact wait-for: command.\n\nUnlike other scan types, waiting for DAST scans is disabled + and the `DEBRICKED_WAIT_EXTRA_OPTS` environment variable can be used to pass extra options to the + fcliCmd:fcli ssc artifact wait-for: command. Waiting for processing of uploaded FAA results is handled + by the FAA scan action itself.\n\nUnlike other scan types, waiting for DAST scans is disabled by default (as DAST scans are often long-running and only run on demand); set `DO_DAST_WAIT` to `true` to wait for DAST scan completion.\n\nDAST scans can take considerably longer than SAST scans, potentially exceeding CI/CD job time limits (for example on GitHub Actions or GitLab CI); if the default wait timeout diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml index d43f0eedd39..2c13edacc24 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/ci.yaml @@ -3,17 +3,24 @@ author: Fortify usage: header: Run FoD CI pipeline description: | - This action can be used to run a full, standardized CI pipeline that performs the - following activities: + This action runs a FoD CI pipeline with the following activities, depending on + the configured options: * Create & configure FoD application release if needed * Package source code * Submit SAST scan request - * Wait for SAST scan completion - * Perform post-scan activities, like checking policy outcome, exporting results, ... + * Wait for SAST scan completion as configured + * Optionally run Fortify Agentic Analyzer (FAA) and import SARIF results to FoD + * Optionally perform Aviator remediation + * Perform configured post-scan activities, such as policy checks, summaries, + pull request comments, and result exports Configuration for this fcli action is done through environment variables; the sections below list the environment variables supported by this action. + + NOTE: Standard CI integrations use the top-level 'fcli action run ci' action. + When invoking this FoD action directly with FAA integration enabled, manually + configure the environment variables required by the FAA license check. ${#include('/ci-action-bootstrap'+(isAsciiDoc?'.adoc':'.txt'))} @@ -65,9 +72,9 @@ steps: #fcliCmdSkipFromEnvReason('WAIT', false) ?:#fcliCmdSkipFromEnvReason('SAST_WAIT', false) } - faa.skipReason: > # Disabled by default; requires DO_FAA_SCAN=true to be enabled + faa.skipReason: > # Disabled by default; requires DO_FAA_SCAN=true (or FAA_SCAN_ACTION/FAA_SCAN_EXTRA_OPTS) to be enabled ${ - #fcliCmdSkipFromEnvReason('FAA_SCAN', true) + #actionCmdSkipFromEnvReason('FAA_SCAN', true) } # Post-scan tasks will be skipped if wait is skipped or if no scans were completed @@ -140,13 +147,13 @@ steps: on.success: - var.set: { postScan.skipReason: } # Reset postScan.skipReason to allow post-scan tasks to run - # Pass SAST scan ID if SAST scan was started; otherwise, disable SAST FPR download + # Run FAA scan; SAST context is taken from the latest SAST scan results for the release (if any). + # FoD SARIF imports can't be waited for, so FAA results may not yet be reflected by post-scan tasks. FAA_SCAN: cmd: > ${#actionCmd('FAA_SCAN', 'fod', 'faa-scan')} "--source-dir=${global.ci.sourceDir}" "--release=${global.ci.rel}" - ${#isBlank(SAST_SCAN.dependencySkipReason) ? '"--sast-scan-id=::fod_sast_scan::"' : '"--skip-sast-download=true"'} skip.if-reason: - ${faa.skipReason} # Skip if FAA scan is disabled diff --git a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml index 9c81c90c32f..9460485b7dc 100644 --- a/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-fod/src/main/resources/com/fortify/cli/fod/actions/zip/faa-scan.yaml @@ -4,71 +4,47 @@ author: Fortify usage: header: (PREVIEW) Run Fortify Agentic Analyzer Scan description: | - This action can be used to run a Fortify Agentic Analyzer (FAA) scan of the project - and optionally import the results to FoD as a SARIF report. + This action runs a Fortify Agentic Analyzer (FAA) scan on the project source code + and imports the results to FoD as a SARIF report. - Optionally, you can provide the FPR file from a prior SAST scan. When provided, - FAA uses this context to avoid reporting duplicate issues that were already found - by the SAST scan, resulting in higher quality analysis results. + The action automatically downloads the latest SAST scan results for the specified + release. FAA uses this context to avoid reporting duplicate issues that were already + found by SAST, resulting in higher quality analysis results. If no SAST results are + available, FAA runs without SAST context. - If --fpr is not specified, SAST results are downloaded automatically: - - When --sast-scan-id is specified, the action waits for the FoD SAST scan to - complete and downloads the FPR for that scan. - - Otherwise, when --release is specified, the action downloads the latest SAST - scan FPR for that release. - If no SAST results are available or the download fails, FAA runs without SAST - results. Use --skip-sast-download to disable automatic download. + NOTE: SAST context is taken from the latest SAST scan results available in FoD at the + time this action runs. If a more recent SAST scan hasn't completed yet, results from an + earlier SAST scan will be used. The fcli 'ci' action waits for SAST scan completion + (unless waiting is disabled) before running this action. The imported SARIF results are + processed asynchronously by FoD; this action doesn't wait for import completion. config: output: immediate rest.target.default: fod - run.fcli.status.log.default: true # By default, we log all exit statuses + run.fcli.status.log.default: true run.fcli.status.check.default: true mcp: exclude # FAA is a specialized tool requiring specific setup -# NOTE: When updating any options, ci action may also need to be updated cli.options: sourceDir: names: --source-dir, -d description: >- Source directory on which to run Fortify Agentic Analyzer scan. Defaults to environment variable `SOURCE_DIR` if not specified. - default: ${#env('SOURCE_DIR')} - required: false - sastFprFile: - names: --fpr, -f - description: >- - Optional path to the FPR file from a prior SAST scan. When provided, FAA uses this - context to avoid reporting duplicate issues already identified by SAST, resulting in - enhanced analysis quality. If not provided, FAA will perform a standalone analysis. required: false + default: ${#env('SOURCE_DIR')} release: names: --release, --rel description: >- - Optional FoD release to which the FAA scan results (SARIF) must be imported. If not specified, FAA scan will run and write results to the output file, but SARIF will not be imported to FoD. Release must already exist in FoD if specified. - required: false + FoD release for which to download SAST results and import FAA scan results. + Release must already exist in FoD. + required: true default: ${#env('FOD_RELEASE')} - sastScanId: - names: --sast-scan-id - description: >- - Optional FoD SAST scan ID, usually passed by the ci action. When specified and --fpr - is not, this action waits for the scan to complete, downloads the FPR for this scan, - and passes it to FAA. - required: false - skipSastDownload: - names: --skip-sast-download - description: >- - Skip automatic SAST FPR download. FAA runs without SAST results unless --fpr is - specified. - required: false - type: boolean - default: false faaOutput: names: --output, -o description: >- Output SARIF file path where FAA scan results will be written. - Defaults to the environment variable `FAA_SCAN_OUTPUT_PATH` if not specified. - If the environment variable is not set, defaults to fortifyaa.sarif in the current working directory. + Defaults to fortifyaa-scan.sarif in the current working directory. required: false default: fortifyaa-scan.sarif faaPath: @@ -78,7 +54,7 @@ cli.options: FAA must be pre-installed on the system before running this action; this action only registers the existing installation with fcli. Defaults to the FAA_HOME environment variable. - Required: User must have FAA already installed and FAA_HOME set. + If not specified and FAA_HOME is not set, the system PATH will be searched. required: false default: ${#env('FAA_HOME')} extraScanOpts: @@ -91,41 +67,30 @@ steps: - var.set: # Used for passing extra options from ci action without bothering about escaping extraScanOpts: ${#join(" ", {cli.extraScanOpts, global.faaScan?.extraOpts})} - fprArg: >- - ${#isNotBlank(cli.sastFprFile) ? '--fpr "' + cli.sastFprFile + '"' : ''} sastFprFile: faa_input_${#action.runID().replace('-','_')}.fpr + fprArg: '' - # Download SAST results for the FoD SAST scan started by the ci action - - if: >- - ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isNotBlank(cli.sastScanId)} - run.fcli: - SAST_WAIT: - cmd: fcli fod sast-scan wait-for "${cli.sastScanId}" - status.check: false - DOWNLOAD_SAST_FPR: - cmd: fcli fod sast-scan download "${cli.sastScanId}" -f "${sastFprFile}" - skip.if-reason: - - ${SAST_WAIT.dependencySkipReason} - status.check: false - on.success: - - var.set: - fprArg: '--fpr "${sastFprFile}"' + # Register FAA with self-test to fail early if FAA is not found or not properly configured + - run.fcli: + SETUP_TOOLS: + cmd: >- + fcli tool env init "--tools=fortifyaa${#isNotBlank(cli.faaPath) ? ':' + cli.faaPath : ''}" - # Download latest SAST results for the release when running standalone - - if: >- - ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isBlank(cli.sastScanId) && #isNotBlank(cli.release)} - run.fcli: + # Download latest SAST results for the release + - run.fcli: DOWNLOAD_LATEST_SAST_FPR: cmd: fcli fod sast-scan download-latest --rel "${cli.release}" -f "${sastFprFile}" status.check: false on.success: - var.set: fprArg: '--fpr "${sastFprFile}"' + on.fail: + - log.warn: + msg: Unable to download latest SAST FPR for release '${cli.release}'; FAA scan will run without SAST context. + cause: ${lastException} + # Run FAA scan with SAST FPR context if available, otherwise run without SAST context - run.fcli: - SETUP_TOOLS: - cmd: >- - fcli tool env init "--tools=fortifyaa${#isNotBlank(cli.faaPath) ? ':' + cli.faaPath : ''}" RUN_FAA_SCAN: cmd: > fcli tool fortifyaa run -- @@ -150,4 +115,3 @@ steps: fcli fod sast-scan import-sarif --rel "${cli.release}" -f "${cli.faaOutput}" - status.check: false diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml index b5b82f2aa70..c5ed95d8cad 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/ci.yaml @@ -4,18 +4,26 @@ author: Fortify usage: header: Run SSC CI pipeline description: | - This action can be used to run a full, standardized CI pipeline that performs the - following activities: - + This action runs an SSC CI pipeline with the following activities, depending on + the configured scan types and options: + * Create & configure SSC application version if needed * Package source code - * Submit SAST scan request - * Submit DAST scan request, using pre-existing SC-DAST scan settings - * Wait for SAST/DAST scan completion - * Perform post-scan activities, like checking policy outcome, exporting results, ... + * Submit SAST scan requests + * Optionally submit DAST scan requests using pre-existing SC-DAST scan settings + * Optionally run Debricked software composition analysis (SCA) and publish results + * Wait for scan completion as configured + * Optionally run Fortify Agentic Analyzer (FAA) and upload SARIF results to SSC + * Optionally perform Aviator auditing and remediation + * Perform configured post-scan activities, such as policy checks, summaries, + pull request comments, and result exports Configuration for this fcli action is done through environment variables; the sections below list the environment variables supported by this action. + + NOTE: Standard CI integrations use the top-level 'fcli action run ci' action. + When invoking this SSC action directly with FAA integration enabled, manually + configure the environment variables required by the FAA license check. ${#include('/ci-action-bootstrap'+(isAsciiDoc?'.adoc':'.txt'))} @@ -78,9 +86,9 @@ steps: ${ #extraOpts('DEBRICKED_SCAN') } - faa.skipReason: > # Disabled by default; requires DO_FAA_SCAN=true to be enabled + faa.skipReason: > # Disabled by default; requires DO_FAA_SCAN=true (or FAA_SCAN_ACTION/FAA_SCAN_EXTRA_OPTS) to be enabled ${ - #fcliCmdSkipFromEnvReason('FAA_SCAN', true) + #actionCmdSkipFromEnvReason('FAA_SCAN', true) } aviator.skipReason: > # Enabled if AVIATOR_TOKEN & AVIATOR_URL specified, unless explicitly disabled @@ -205,16 +213,20 @@ steps: - ${SAST_WAIT.dependencySkipReason} # Skip if SAST_WAIT was skipped or failed - ${#isDebugEnabled()?'':'--debug flag not specified'} # Skip if debugging is disabled - # Pass SAST job token if SAST scan was started; otherwise, disable SAST FPR download + # Run FAA scan; the faa-scan action handles SAST context download, SARIF upload and + # waiting for artifact processing (skipped if waiting is disabled for the ci action). FAA_SCAN: cmd: > ${#actionCmd('FAA_SCAN', 'ssc', 'faa-scan')} "--source-dir=${global.ci.sourceDir}" "--app-version=${global.ci.av}" - ${#isBlank(SAST_SCAN.dependencySkipReason) ? '"--sast-job-token=::sc_sast_scan::"' : '"--skip-sast-download=true"'} + ${#isBlank(wait.skipReason) ? '' : '--skip-wait=true'} skip.if-reason: - - ${faa.skipReason} - + - ${faa.skipReason} # Skip if FAA scan is disabled + on.success: + - if: ${#isBlank(wait.skipReason)} + var.set: { postScan.skipReason: } # Reset postScan.skipReason to allow post-scan tasks to run + AVIATOR_AUDIT: cmd: ${#fcliCmd('AVIATOR_AUDIT', 'aviator ssc audit')} --aviator-session ${sessionName} --av "${global.ci.av}" --app "${aviator.app}" --store aviator_audit skip.if-reason: diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml index 8c12fc2f83b..d72f08871c1 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/actions/zip/faa-scan.yaml @@ -4,29 +4,26 @@ author: Fortify usage: header: (PREVIEW) Run Fortify Agentic Analyzer Scan description: | - This action can be used to run a Fortify Agentic Analyzer (FAA) scan of the project - and optionally upload the results to SSC as a SARIF report. + This action runs a Fortify Agentic Analyzer (FAA) scan on the project source code + and uploads the results to SSC as a SARIF report. - Optionally, you can provide the FPR file from a prior SAST scan. When provided, - FAA uses this context to avoid reporting duplicate issues that were already found - by the SAST scan, resulting in higher quality analysis results. + The action automatically downloads the latest processed SAST scan results for the + specified application version. FAA uses this context to avoid reporting duplicate + issues that were already found by SAST, resulting in higher quality analysis results. + If no processed SAST results are available, FAA runs without SAST context. - If --fpr is not specified, SAST results are downloaded automatically: - - When --sast-job-token is specified, the action waits for the ScanCentral SAST job - results to be processed and downloads the FPR for that job. - - Otherwise, when --app-version is specified, the action downloads the latest - processed SAST artifact for that application version. - If no SAST results are available or the download fails, FAA runs without SAST - results. Use --skip-sast-download to disable automatic download. + NOTE: SAST context is taken from the latest SAST artifact that has been fully processed + by SSC at the time this action runs. If a more recent SAST scan hasn't been processed + yet, results from an earlier SAST scan will be used. The fcli 'ci' action waits for SAST + scan completion (unless waiting is disabled) before running this action. config: output: immediate rest.target.default: ssc - run.fcli.status.log.default: true # By default, we log all exit statuses + run.fcli.status.log.default: true run.fcli.status.check.default: true mcp: exclude # FAA is a specialized tool requiring specific setup -# NOTE: When updating any options, ci action may also need to be updated cli.options: sourceDir: names: --source-dir, -d @@ -35,97 +32,61 @@ cli.options: Defaults to environment variable `SOURCE_DIR` if not specified. default: ${#env('SOURCE_DIR')} required: false - sastFprFile: - names: --fpr, -f - description: >- - Optional path to the FPR file from a prior SAST scan. When provided, FAA uses this - context to avoid reporting duplicate issues already identified by SAST, resulting in - enhanced analysis quality. If not provided, FAA will perform a standalone analysis. - required: false appVersion: names: --app-version, --av description: >- - Optional SSC application version to which the FAA scan results (SARIF) must be uploaded. If not specified, FAA scan will run and write results to the output file, but SARIF will not be uploaded to SSC. Application version must already exist in SSC if specified. - required: false + SSC application version for which to download SAST results and upload FAA scan results. + Application version must already exist in SSC. + required: true default: ${#env('APP_VERSION')} - sastJobToken: - names: --sast-job-token - description: >- - Optional ScanCentral SAST job token, usually passed by the ci action. When specified - and --fpr is not, this action waits for the job results to be processed, downloads - the FPR for this job, and passes it to FAA. - required: false - skipSastDownload: - names: --skip-sast-download - description: >- - Skip automatic SAST FPR download. FAA runs without SAST results unless --fpr is - specified. - required: false - type: boolean - default: false faaOutput: names: --output, -o description: >- Output SARIF file path where FAA scan results will be written. - Defaults to the environment variable `FAA_SCAN_OUTPUT_PATH` if not specified. - If the environment variable is not set, defaults to fortifyaa.sarif in the current working directory. + Defaults to fortifyaa-scan.sarif in the current working directory. required: false default: fortifyaa-scan.sarif faaPath: names: --faa-path, -p - description: | + description: >- Path to a pre-installed Fortify Agentic Analyzer (FAA) installation. FAA must be pre-installed on the system before running this action; this action only registers the existing installation with fcli. Defaults to the FAA_HOME environment variable. - Required: User must have FAA already installed and FAA_HOME set. + If not specified and FAA_HOME is not set, the system PATH will be searched. required: false default: ${#env('FAA_HOME')} extraScanOpts: names: --extra-scan-opts description: >- Extra options to be passed to the 'fortifyaa -scan' command. - required: false + required: false skipWait: names: --skip-wait description: >- - By default, the action will wait for the SARIF artifact upload to complete. Use this option to skip - waiting for the upload to complete. + By default, the action will wait for the uploaded SARIF artifact to be processed by SSC. Use this + option to skip waiting for artifact processing to complete. required: false type: boolean - default: true steps: - var.set: # Used for passing extra options from ci action without bothering about escaping extraScanOpts: ${#join(" ", {cli.extraScanOpts, global.faaScan?.extraOpts})} - fprArg: >- - ${#isNotBlank(cli.sastFprFile) ? '--fpr "' + cli.sastFprFile + '"' : ''} - global.faaScanUpload.fcliVarName: faa_scan_${#action.runID().replace('-','_')} - global.faaScanUpload.waitForCmd: 'fcli ssc artifact wait-for ::${global.faaScanUpload.fcliVarName}::' sastFprFile: faa_input_${#action.runID().replace('-','_')}.fpr + fprArg: '' sastArtifactId: null + # fcli variable storing the uploaded artifact, used for waiting for artifact processing + faaArtifactVarName: faa_scan_${#action.runID().replace('-','_')} - # Download SAST results for the ScanCentral SAST job started by the ci action - - if: >- - ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isNotBlank(cli.sastJobToken)} - run.fcli: - SAST_WAIT: - cmd: fcli sc-sast scan wait-for "${cli.sastJobToken}" - status.check: false - DOWNLOAD_SAST_FPR: - cmd: fcli sc-sast scan download "${cli.sastJobToken}" -t fpr -f "${sastFprFile}" - skip.if-reason: - - ${SAST_WAIT.dependencySkipReason} - status.check: false - on.success: - - var.set: - fprArg: '--fpr "${sastFprFile}"' + # Register FAA with self-test to fail early if FAA is not found or not properly configured + - run.fcli: + SETUP_TOOLS: + cmd: >- + fcli tool env init "--tools=fortifyaa${#isNotBlank(cli.faaPath) ? ':' + cli.faaPath : ''}" - # Download latest processed SAST results for the application version when running standalone - - if: >- - ${!cli.skipSastDownload && #isBlank(cli.sastFprFile) && #isBlank(cli.sastJobToken) && #isNotBlank(cli.appVersion)} - do: + # Determine latest processed SAST artifact for the application version (optional) + - do: - var.set: sastAv: ${#ssc.appVersion(cli.appVersion)} - rest.call: @@ -144,25 +105,26 @@ steps: var.set: sastArtifactId: ${artifact.id} - if: ${sastArtifactId==null} - log.info: No processed SAST artifact found; running FAA without SAST results + log.info: No processed SAST artifact found for application version '${cli.appVersion}'; FAA scan will run without SAST context. on.fail: - log.warn: - msg: Unable to determine latest SAST artifact; running FAA without SAST results + msg: Unable to query SAST artifacts for application version '${cli.appVersion}'; FAA scan will run without SAST context. cause: ${lastException} - if: ${sastArtifactId!=null} run.fcli: - DOWNLOAD_LATEST_SAST_FPR: + DOWNLOAD_SAST_FPR: cmd: fcli ssc artifact download "${sastArtifactId}" -f "${sastFprFile}" - status.check: false on.success: - var.set: fprArg: '--fpr "${sastFprFile}"' + on.fail: + - log.warn: + msg: Failed to download SAST FPR artifact; FAA scan will run without SAST context. + cause: ${lastException} + # Run FAA scan with SAST FPR context if SAST results are available, otherwise run without SAST context - run.fcli: - SETUP_TOOLS: - cmd: >- - fcli tool env init "--tools=fortifyaa${#isNotBlank(cli.faaPath) ? ':' + cli.faaPath : ''}" RUN_FAA_SCAN: cmd: > fcli tool fortifyaa run -- @@ -188,9 +150,8 @@ steps: --av "${cli.appVersion}" --engine-type Fortify_AA -f "${cli.faaOutput}" - --store "${global.faaScanUpload.fcliVarName}" - status.check: false + --store "${faaArtifactVarName}" - if: ${!cli.skipWait} run.fcli: - WAIT: ${global.faaScanUpload.waitForCmd} + WAIT: "fcli ssc artifact wait-for ::${faaArtifactVarName}::"