Skip to content

Commit

Permalink
feat: Add ability to run and import Debricked scans into SSC (closes #41
Browse files Browse the repository at this point in the history
)
  • Loading branch information
rsenden committed Jun 4, 2024
1 parent b02d1d7 commit 803c661
Show file tree
Hide file tree
Showing 28 changed files with 246 additions and 136 deletions.
49 changes: 40 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ This action assumes the standard software packages as provided by GitHub-hosted
**`sast-scan`** - OPTIONAL
When set to true, the action will run a SAST scan on either Fortify on Demand (if the `FOD_URL` environment variable has been specified), or on ScanCentral SAST (if the `SSC_URL` environment variable has been specified). This includes packaging the source code, running the scan, and optionally reporting SAST scan results back into GitHub.

If not specified or when set to false, no SAST scan will be performed. For now, this means that the action will complete without doing any work. Future versions of this action may provide additional inputs, for example allowing you to run a dynamic application security testing (DAST) scan instead of a SAST scan.
If not specified or when set to false, no SAST scan will be performed. For now, this means that the action will complete without doing any work. Future versions of this action may provide additional inputs, for example allowing you to run a dynamic application security testing (DAST) scan instead of a SAST scan, or to run a Debricked-only scan (see below).

**`debricked-sca-scan`** - OPTIONAL
(Not applicable to Fortify on Demand) When set to true, the action will run a Debricked Software Composition Analysis (SCA) scan. This is only effective when `sast-scan` is also set to `true` and the `SSC_URL` environment variable has been specified, in which case both a ScanCentral SAST scan and Debricked scan will be performed and published to SSC.

### Action environment variable inputs

Expand Down Expand Up @@ -158,10 +161,6 @@ This environment variable allows for overriding the default tool definitions, po
<!-- START-INCLUDE:env-sc-sast-scan.md -->



<!-- START-INCLUDE:env-sc-sast-login.md -->


<!-- START-INCLUDE:env-ssc-connection.md -->

**`SSC_URL`** - REQUIRED
Expand All @@ -176,6 +175,18 @@ Required when authenticating with SSC user credentials.
<!-- END-INCLUDE:env-ssc-connection.md -->



<!-- START-INCLUDE:env-ssc-login.md -->

**`EXTRA_SSC_LOGIN_OPTS`** - OPTIONAL
Extra SSC login options, for example for disabling SSL checks or changing connection time-outs; see [`fcli ssc session login` documentation](https://fortify.github.io/fcli/v2.3.0//manpage/fcli-ssc-session-login.html).

<!-- END-INCLUDE:env-ssc-login.md -->



<!-- START-INCLUDE:env-sc-sast-login.md -->

**`SC_SAST_TOKEN`** - REQUIRED
Required: ScanCentral SAST Client Authentication Token for authenticating with ScanCentral SAST Controller.

Expand All @@ -185,6 +196,12 @@ Extra ScanCentral SAST login options, for example for disabling SSL checks or ch
<!-- END-INCLUDE:env-sc-sast-login.md -->


**`DO_DEBRICKED_SCAN`** - OPTIONAL
If set to `true`, this action will run both ScanCentral SAST and Debricked Software Composition Analysis (SCA) scans and publish both results to SSC. This is equivalent to setting the `debricked-sca-scan` input on the top-level `fortify/github-action` action.

**`DEBRICKED_TOKEN`** - REQUIRED*
Required when performing a Debricked Software Composition Analysis scan; see the [Generate access token](https://docs.debricked.com/product/administration/generate-access-token) section in the Debricked documentation for details on how to generate this token.


<!-- START-INCLUDE:env-ssc-appversion.md -->

Expand Down Expand Up @@ -742,10 +759,6 @@ This action assumes the standard software packages as provided by GitHub-hosted
<!-- START-INCLUDE:env-sc-sast-scan.md -->



<!-- START-INCLUDE:env-sc-sast-login.md -->


<!-- START-INCLUDE:env-ssc-connection.md -->

**`SSC_URL`** - REQUIRED
Expand All @@ -760,6 +773,18 @@ Required when authenticating with SSC user credentials.
<!-- END-INCLUDE:env-ssc-connection.md -->



<!-- START-INCLUDE:env-ssc-login.md -->

**`EXTRA_SSC_LOGIN_OPTS`** - OPTIONAL
Extra SSC login options, for example for disabling SSL checks or changing connection time-outs; see [`fcli ssc session login` documentation](https://fortify.github.io/fcli/v2.3.0//manpage/fcli-ssc-session-login.html).

<!-- END-INCLUDE:env-ssc-login.md -->



<!-- START-INCLUDE:env-sc-sast-login.md -->

**`SC_SAST_TOKEN`** - REQUIRED
Required: ScanCentral SAST Client Authentication Token for authenticating with ScanCentral SAST Controller.

Expand All @@ -769,6 +794,12 @@ Extra ScanCentral SAST login options, for example for disabling SSL checks or ch
<!-- END-INCLUDE:env-sc-sast-login.md -->


**`DO_DEBRICKED_SCAN`** - OPTIONAL
If set to `true`, this action will run both ScanCentral SAST and Debricked Software Composition Analysis (SCA) scans and publish both results to SSC. This is equivalent to setting the `debricked-sca-scan` input on the top-level `fortify/github-action` action.

**`DEBRICKED_TOKEN`** - REQUIRED*
Required when performing a Debricked Software Composition Analysis scan; see the [Generate access token](https://docs.debricked.com/product/administration/generate-access-token) section in the Debricked documentation for details on how to generate this token.


<!-- START-INCLUDE:env-ssc-appversion.md -->

Expand Down
10 changes: 8 additions & 2 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@ inputs:
description: 'Run a SAST scan, takes either true or false (default)'
default: 'false'
required: false
debricked-sca-scan:
description: 'Run a Debricked Software Composition Analysis, takes either true or false (default)'
default: 'false'
required: false
runs:
using: composite
steps:
- uses: fortify/github-action/[email protected]
if: inputs['sast-scan']=='true' && env.FOD_URL
if: inputs['sast-scan']=='true' && env.FOD_URL
- uses: fortify/github-action/[email protected]
if: inputs['sast-scan']=='true' && env.SSC_URL
if: inputs['sast-scan']=='true' && env.SSC_URL
env:
DO_DEBRICKED_SCAN: inputs['debricked-sca-scan']

branding:
icon: 'shield'
Expand Down
2 changes: 0 additions & 2 deletions doc-resources/env-sc-sast-login.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{{include:env-ssc-connection.md}}

**`SC_SAST_TOKEN`** - REQUIRED
Required: ScanCentral SAST Client Authentication Token for authenticating with ScanCentral SAST Controller.

Expand Down
9 changes: 9 additions & 0 deletions doc-resources/env-sc-sast-scan.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
{{include:env-ssc-connection.md}}

{{include:env-ssc-login.md}}

{{include:env-sc-sast-login.md}}

**`DO_DEBRICKED_SCAN`** - OPTIONAL
If set to `true`, this action will run both ScanCentral SAST and Debricked Software Composition Analysis (SCA) scans and publish both results to SSC. This is equivalent to setting the `debricked-sca-scan` input on the top-level `fortify/github-action` action.

**`DEBRICKED_TOKEN`** - REQUIRED*
Required when performing a Debricked Software Composition Analysis scan; see the [Generate access token](https://docs.debricked.com/product/administration/generate-access-token) section in the Debricked documentation for details on how to generate this token.

{{include:env-ssc-appversion.md}}

{{include:env-package.md}}
Expand Down
2 changes: 0 additions & 2 deletions doc-resources/env-ssc-login.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
{{include:env-ssc-connection.md}}

**`EXTRA_SSC_LOGIN_OPTS`** - OPTIONAL
Extra SSC login options, for example for disabling SSL checks or changing connection time-outs; see [`fcli ssc session login` documentation]({{var:fcli-doc-base-url}}/manpage/fcli-ssc-session-login.html).
5 changes: 4 additions & 1 deletion doc-resources/repo-readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ The primary `fortify/github-action` action currently allows for running SAST sca
**`sast-scan`** - OPTIONAL
When set to true, the action will run a SAST scan on either Fortify on Demand (if the `FOD_URL` environment variable has been specified), or on ScanCentral SAST (if the `SSC_URL` environment variable has been specified). This includes packaging the source code, running the scan, and optionally reporting SAST scan results back into GitHub.

If not specified or when set to false, no SAST scan will be performed. For now, this means that the action will complete without doing any work. Future versions of this action may provide additional inputs, for example allowing you to run a dynamic application security testing (DAST) scan instead of a SAST scan.
If not specified or when set to false, no SAST scan will be performed. For now, this means that the action will complete without doing any work. Future versions of this action may provide additional inputs, for example allowing you to run a dynamic application security testing (DAST) scan instead of a SAST scan, or to run a Debricked-only scan (see below).

**`debricked-sca-scan`** - OPTIONAL
(Not applicable to Fortify on Demand) When set to true, the action will run a Debricked Software Composition Analysis (SCA) scan. This is only effective when `sast-scan` is also set to `true` and the `SSC_URL` environment variable has been specified, in which case both a ScanCentral SAST scan and Debricked scan will be performed and published to SSC.

### Action environment variable inputs

Expand Down
5 changes: 2 additions & 3 deletions internal/fod-login/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ runs:
- uses: fortify/github-action/internal/[email protected]
if: ${{ !env._FOD_LOGGED_IN }}
with:
cwd: ${{ github.action_path }}
script: ./fod-login.sh
post: ./fod-logout.sh
script: fod-login.sh
post: fod-logout.sh

branding:
icon: 'shield'
Expand Down
34 changes: 34 additions & 0 deletions internal/run-script/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# fortify/github-action/internal/run-script

This action can run any of the scripts located in the `scripts` directory of this action, including the ability to run post-job scripts, for example to handle session logout.

```yaml
- uses: fortify/github-action/internal/run-script@v1
with:
script: <script name>
post: <post-job script name>
```
Originally, the idea was to have these scripts located in each individual action directory, for example having `ssc-login.sh` and `ssc-logout.sh` scripts located in the `internal/ssc-login` directory. However, this proved to be difficult/impossible:

- As scripts need to be run using `bash` (also on Windows), we need to convert `${{github.action_path}}` (which may include drive letter and backslashes on Windows) to `bash` format; an example of how this can be done is shown in `action.yml`.
- GitHub lazily evaluates action inputs when running the post-job actions, but doesn't re-run any steps used to generate those inputs.

So, suppose we'd generate a `BASH_ACTION_PATH` environment variable that contains `${{github.action_path}}` in `bash` format, we'd expect to be able to use something like:

```yaml
- uses: fortify/github-action/internal/run-script/[email protected]
with:
script: ${{ env.BASH_ACTION_PATH }}/ssc-login.sh
post: ${{ env.BASH_ACTION_PATH }}/ssc-logout.sh
```

This works fine for `script:`, but the `post:` script would use whatever the value of `BASH_ACTION_PATH` is during post-job execution. So, if we'd run both `ssc-login` and `sc-sast-login` actions, the post-job action would try to run `..../internal/sc-sast-login/ssc-logout.sh`, which would fail because of the incorrect directory name.

Several work-arounds were tried, but failed. Only way that this would likely work is to have the calling action pass something like a static action id, which would then be used by this action to set a `POST_<id>_SCRIPT=${{inputs.POST}}` environment variable. During post-job execution, we wouldn't look at any actual inputs, but instead just execute the script identified in the `POST_<id>_SCRIPT` environment variable.

Apart from hosting the scripts together with the action that executes them, another advantage of such an id is that we can also provide out-of-the-box support for run-once actions, like the various `login` actions; this is currently handled by setting an environment variable in the `*-login.sh` and `*-logout.sh` scripts. As we may also have scripts that may need to be run multiple times, we should control this through a `run-once: true|false` input.

Disadvantage, apart from slightly more complex implementation, is that each caller of this `run-script` action would also need to provide the value of `${{ github.action_path }}` as an input to this action, in order to have this action determine appropriate script location.


31 changes: 19 additions & 12 deletions internal/run-script/action.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Run a script with optional post-job cleanup

description: 'Action to execute a bash script, optionally executing another script on job completion.'
author: Fortify

inputs:
script:
Expand All @@ -9,15 +9,22 @@ inputs:
post:
description: 'Script to run on job completion'
required: false
cwd:
description: 'Script working directory'
required: false
key:
description: 'Name of the state variable used to detect the post step.'
required: false
default: POST

runs:
using: 'node20'
main: 'main.js'
post: 'main.js'
using: composite
steps:
# Define directory where scripts are located. This MUST be a static path which doesn't
# change during job execution, otherwise post-job scripts will fail. As such, all scripts
# must be in the same directory; we can't use github.action_path from the calling action.
# See README.md for details.
- run: echo "_RUN_SCRIPTS_DIR=$(pwd)/scripts" >> $GITHUB_ENV
shell: bash
working-directory: ${{ github.action_path }}
- uses: fortify/github-action/internal/run-script/[email protected]
with:
dir: ${{ env._RUN_SCRIPTS_DIR }}
script: ${{ inputs.script }}
post: ${{ inputs.post }}

branding:
icon: 'shield'
color: 'blue'
19 changes: 19 additions & 0 deletions internal/run-script/js/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: JavaScript action to run a script with optional post-job cleanup

description: 'Action to execute a bash script, optionally executing another script on job completion. This action should not be used directly, but through internal/run-script.'

inputs:
script:
description: 'Script to run'
required: true
post:
description: 'Script to run on job completion'
required: false
dir:
description: 'Directory where scripts are located, set automatically by internal/run-script action'
required: true

runs:
using: 'node20'
main: 'main.js'
post: 'post.js'
3 changes: 3 additions & 0 deletions internal/run-script/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const util = require("./util");

util.run(process.env.INPUT_SCRIPT);
File renamed without changes.
3 changes: 3 additions & 0 deletions internal/run-script/js/post.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const util = require("./util");

util.run(process.env.INPUT_POST);
12 changes: 12 additions & 0 deletions internal/run-script/js/util.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const { spawn } = require("child_process");

exports.run = function(script) {
if ( script ) {
const scriptDir = process.env.INPUT_DIR;
const subprocess = spawn(`bash -c -o pipefail -v 'export UTIL_DIR=${scriptDir}; ${scriptDir}/${script}'`,
{ stdio: "inherit", shell: true });
subprocess.on("exit", (exitCode) => {
process.exitCode = exitCode;
});
}
}
22 changes: 0 additions & 22 deletions internal/run-script/main.js

This file was deleted.

11 changes: 4 additions & 7 deletions internal/fod-login/fod-logout.sh → internal/run-script/scripts/common.sh
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#!/bin/bash

### Start common code
if [ -n "$RUNNER_DEBUG" ]; then
set -v -x
fi
if [ -z "$FCLI_CMD" ]; then
echo "ERROR: fortify/github-action/setup must be run to set up fcli before running this action"
exit 1;
fi
### End common code

if [[ "${_FOD_LOGGED_IN}" == "true" ]]; then
echo '_FOD_LOGGED_IN=false' >> $GITHUB_ENV
${FCLI_CMD} fod session logout || exit 1
fi
function run {
echo RUN: "$@"
"$@"
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
#!/bin/bash

### Start common code
if [ -n "$RUNNER_DEBUG" ]; then
set -v -x
fi
if [ -z "$FCLI_CMD" ]; then
echo "ERROR: fortify/github-action/setup must be run to set up fcli before running this action"
exit 1;
fi
### End common code
. ${UTIL_DIR}/common.sh

if [ -z "$FOD_URL" ]; then
echo "ERROR: FOD_URL environment variable must be set"; exit 1;
Expand All @@ -21,5 +12,6 @@ else
echo "ERROR: Either FOD_CLIENT_ID and FOD_CLIENT_SECRET, or FOD_TENANT, FOD_USER and FOD_PASSWORD environment variables must be set"
exit 1;
fi
${FCLI_CMD} fod session login --url "${FOD_URL}" "${_FOD_AUTH_OPTS[@]}" ${EXTRA_FOD_LOGIN_OPTS} || exit 1
run ${FCLI_CMD} fod session login --url "${FOD_URL}" "${_FOD_AUTH_OPTS[@]}" ${EXTRA_FOD_LOGIN_OPTS} \
|| exit 1
echo '_FOD_LOGGED_IN=true' >> $GITHUB_ENV
8 changes: 8 additions & 0 deletions internal/run-script/scripts/fod-logout.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
. ${UTIL_DIR}/common.sh

if [[ "${_FOD_LOGGED_IN}" == "true" ]]; then
echo '_FOD_LOGGED_IN=false' >> $GITHUB_ENV
run ${FCLI_CMD} fod session logout \
|| exit 1
fi
Loading

0 comments on commit 803c661

Please sign in to comment.