Skip to content

Commit

Permalink
Merge branch 'master' into lr-sync-appstatus
Browse files Browse the repository at this point in the history
  • Loading branch information
lrochette authored Feb 6, 2024
2 parents a8a651c + 9addaf7 commit faec34f
Show file tree
Hide file tree
Showing 6 changed files with 341 additions and 0 deletions.
5 changes: 5 additions & 0 deletions incubating/kubescape/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Changelog

## [1.0.0] - 2024-01-22

Original version
8 changes: 8 additions & 0 deletions incubating/kubescape/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM quay.io/kubescape/kubescape-cli:v3.0.1

# Kubescape uses root privileges for writing the results to a file
USER root

COPY entrypoint.sh /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
11 changes: 11 additions & 0 deletions incubating/kubescape/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# kubescape CLI

Docker image which invokes security script using kubescape CLI

### Prerequisites:

Codefresh Subscription (Dedicated Infrastructure/Hybrid) - https://codefresh.io/

### Documentation:

kubescape CLI: https://github.com/kubescape/kubescape/blob/master/docs/getting-started.md
171 changes: 171 additions & 0 deletions incubating/kubescape/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#!/busybox/sh

# Checks if `string` contains `substring`.
#
# Arguments:
# String to check.
#
# Returns:
# 0 if `string` contains `substring`, otherwise 1.
contains() {
case "$1" in
*$2*) return 0 ;;
*) return 1 ;;
esac
}

set -e

# Kubescape uses the client name to make a request for checking for updates
export KS_CLIENT="codefresh"

if [ -n "${FRAMEWORKS}" ] && [ -n "${CONTROLS}" ]; then
echo "Framework and Control are specified. Please specify either one of them"
exit 1
fi

if [ -z "${FRAMEWORKS}" ] && [ -z "${CONTROLS}" ] && [ -z "${IMAGE}" ]; then
echo "Neither Framework, Control nor image are specified. Please specify one of them"
exit 1
fi


if [ -n "${FRAMEWORKS}" ] && [ -n "${IMAGE}" ] || [ -n "${CONTROLS}" ] && [ -n "${IMAGE}" ] ; then
errmsg="Image and Framework / Control are specified. Kubescape does not support scanning both at the moment."
errmsg="${errmsg} Please specify either one of them or neither."
echo "${errmsg}"
exit 1
fi

if [ -n "${IMAGE}" ] && [ "${FIXFILES}" = "true" ]; then
errmsg="The run requests both an image scan and file fix suggestions. Kubescape does not support fixing image scan results at the moment."
errmsg="${errmsg} Please specify either one of them or neither."
echo "${errmsg}"
exit 1
fi

# Split the controls by comma and concatenate with quotes around each control
if [ -n "${CONTROLS}" ]; then
controls=""
set -f
IFS=','
set -- "${CONTROLS}"
set +f
unset IFS
for control in "$@"; do
control=$(echo "${control}" | xargs) # Remove leading/trailing whitespaces
controls="${controls}\"${control}\","
done
controls=$(echo "${controls%?}")
fi

frameworks_cmd=$([ -n "${FRAMEWORKS}" ] && echo "framework ${FRAMEWORKS}" || echo "")
controls_cmd=$([ -n "${CONTROLS}" ] && echo control "${controls}" || echo "")

scan_input=$([ -n "${FILES}" ] && echo "${FILES}" || echo .)

output_formats="${FORMAT}"
have_json_format="false"
if [ -n "${output_formats}" ] && contains "${output_formats}" "json"; then
have_json_format="true"
fi

verbose=""
if [ -n "${VERBOSE}" ] && [ "${VERBOSE}" != "false" ]; then
verbose="--verbose"
fi

exceptions=""
if [ -n "$EXCEPTIONS" ]; then
exceptions="--exceptions ${EXCEPTIONS}"
fi

controls_config=""
if [ -n "$CONTROLSCONFIG" ]; then
controls_config="--controls-config ${CONTROLSCONFIG}"
fi

should_fix_files="false"
if [ "${FIXFILES}" = "true" ]; then
should_fix_files="true"
fi

# If a user requested Kubescape to fix their files, but forgot to ask for JSON
# output, do it for them
if [ "${should_fix_files}" = "true" ] && [ "${have_json_format}" != "true" ]; then
output_formats="${output_formats},json"
fi

output_file=$([ -n "${OUTPUTFILE}" ] && echo "${OUTPUTFILE}" || echo "results")

account_opt=$([ -n "${ACCOUNT}" ] && echo --account "${ACCOUNT}" || echo "")
access_key_opt=$([ -n "${ACCESSKEY}" ] && echo --access-key "${ACCESSKEY}" || echo "")
server_opt=$([ -n "${SERVER}" ] && echo --server "${SERVER}" || echo "")

# If account ID is empty, we load artifacts from the local path, otherwise we
# load from the cloud (this will enable custom framework support)
artifacts_path="/home/ks/.kubescape"
artifacts_opt=$([ -n "${ACCOUNT}" ] && echo "" || echo --use-artifacts-from "${artifacts_path}")

if [ -n "${FAILEDTHRESHOLD}" ] && [ -n "${COMPLIANCETHRESHOLD}" ]; then
echo "Both failedThreshold and complianceThreshold are specified. Please specify either one of them or neither"
exit 1
fi

fail_threshold_opt=$([ -n "${FAILEDTHRESHOLD}" ] && echo --fail-threshold "${FAILEDTHRESHOLD}" || echo "")
compliance_threshold_opt=$([ -n "${COMPLIANCETHRESHOLD}" ] && echo --compliance-threshold "${COMPLIANCETHRESHOLD}" || echo "")

# When a user requests to fix files, the action should not fail because the
# results exceed severity. This is subject to change in the future.
severity_threshold_opt=$(
[ -n "${SEVERITYTHRESHOLD}" ] &&
[ "${should_fix_files}" = "false" ] &&
echo --severity-threshold "${SEVERITYTHRESHOLD}" ||
echo ""
)

# Handle image scanning request
image_subcmd=""
echo "image is <${IMAGE}>"
if [ -n "${IMAGE}" ]; then

# By default, assume we are not authenticated. This means we can pull public
# images from the container runtime daemon
image_arg="${IMAGE}"

severity_threshold_opt=$(
[ -n "${SEVERITYTHRESHOLD}" ] &&
echo --severity-threshold "${SEVERITYTHRESHOLD}" ||
echo ""
)

auth_opts=""
if [ -n "${REGISTRYUSERNAME}" ] && [ -n "${REGISTRYPASSWORD}" ]; then
auth_opts="--username=${REGISTRYUSERNAME} --password=${REGISTRYPASSWORD}"

# When trying to authenticate, we cannot assume that the runner has access
# to an *authenticated* container runtime daemon, so we should always try
# to pull images from the registry
image_arg="registry://${image_arg}"
else
echo "NOTICE: Received no registry credentials, pulling without authentication."
printf "Hint: If you provide credentials, make sure you include both the username and password.\n\n"
fi

# Build the image scanning subcommand with options
image_subcmd="image ${auth_opts}"
# Override the scan input
scan_input="${image_arg}"
echo "Scan subcommand: ${image_subcmd}"
fi

# TODO: include artifacts_opt once https://github.com/kubescape/kubescape/issues/1040 is resolved
scan_command="kubescape scan ${image_subcmd} ${frameworks_cmd} ${controls_cmd} ${scan_input} ${account_opt} ${access_key_opt} ${server_opt} ${fail_threshold_opt} ${compliance_threshold_opt} ${severity_threshold_opt} --format ${output_formats} --output ${output_file} ${verbose} ${exceptions} ${controls_config}"

echo "${scan_command}"
eval "${scan_command}"

if [ "$should_fix_files" = "true" ]; then
fix_command="kubescape fix --no-confirm ${output_file}.json"
eval "${fix_command}"
fi
Binary file added incubating/kubescape/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
146 changes: 146 additions & 0 deletions incubating/kubescape/step.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
kind: step-type
version: '1.0'
metadata:
name: kubescape
version: 3.0.1
title: Run a kubescape security scan
isPublic: true
description: Scan a cluster with the kubescape security service.
sources:
- 'https://github.com/codefresh-io/steps/tree/master/incubating/kubescape'
stage: incubating
maintainers:
- name: Laurent Rochette
email: [email protected]
- name: Matthias Bertschy
email: [email protected]
categories:
- security
official: true
tags: []
icon:
type: image
size:
large:
url: >-
https://cdn.jsdelivr.net/gh/codefresh-io/steps/incubating/kubescape/icon.png
examples:
- description: example-1
workflow:
kubescape:
type: kubescape:3.0.1
arguments:
VERBOSE: on
OUTPUTFILE: results
FRAMEWORKS: MITRE
ACCESSKEY: ${{KEY}}
ACCOUNT: ${{ACCOUNT_ID}}
FORMAT: sarif

spec:
arguments: |-
{
"definitions": {},
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"additionalProperties": false,
"patterns": [],
"required": [],
"properties": {
"FILES": {
"type": "string",
"description": "YAML files or Helm charts to scan for misconfigurations. The files need to be provided with the complete path from the root of the repository. Default is '.' which scans the whole repository"
},
"OUTPUTFILE": {
"type": "string",
"description": "Name of the output file where the scan result will be stored without the extension. Default is 'result'"
},
"FRAMEWORKS": {
"type": "string",
"description": "Security framework(s) to scan the files against. Multiple frameworks can be specified separated by a comma with no spaces. Example - nsa,devopsbest. Run kubescape list frameworks in the Kubescape CLI to get a list of all frameworks. Either frameworks have to be specified or controls."
},
"CONTROLS": {
"type": "string",
"description": "Security control(s) to scan the files against. Multiple controls can be specified separated by a comma with no spaces. Example - Configured liveness probe,Pods in default namespace. Run kubescape list controls in the Kubescape CLI to get a list of all controls. You can use either the complete control name or the control ID such as C-0001 to specify the control you want use. You must specify either the control(s) or the framework(s) you want used in the scan."
},
"ACCOUNT": {
"type": "string",
"description": "account ID for integrating with a third-party server"
},
"ACCESSKEY": {
"type": "string",
"description": "access-key for integrating with a third-party server"
},
"SERVER": {
"type": "string",
"description": "URL for integrating with a third-party server"
},
"FAILEDTHRESHOLD": {
"type": "string",
"description": "Failure threshold is the percent above which the command fails and returns exit code 1. Default is 0 i.e, action fails if any control fails"
},
"SEVERITYTHRESHOLD": {
"type": "string",
"description": "Severity threshold is the severity of a failed control at or above which the command terminates with an exit code 1. Default is 'high', i.e. the action fails if any High severity control fails"
},
"COMPLIANCETHRESHOLD": {
"type": "string",
"description": "Compliance threshold is the percent bellow which the command fails and returns exit code 1 (example: if set to 100 the command will fail if any control fails)"
},
"VERBOSE": {
"type": "string",
"description": "on|off - Display all of the input resources and not only failed resources. Default is 'off'"
},
"EXCEPTIONS": {
"type": "string",
"description": "The JSON file containing at least one resource and one policy. Refer exceptions docs for more info. Objects with exceptions will be presented as exclude and not fail."
},
"FORMAT": {
"type": "string",
"description": "Output format. Can take one or more formats, comma separated",
"default": "junit"
},
"CONTROLSCONFIG": {
"type": "string",
"description": "The file containing controls configuration. Use 'kubescape download controls-inputs' to download the configured controls-inputs."
},
"FIXFILES": {
"type": "string",
"default": "false",
"description": "Whether Kubescape will automatically fix files or not. If enabled, Kubescape will make fixes to the input files. You can then use these fixes to open Pull Requests from your CI/CD pipeline."
},
"IMAGE": {
"type": "string",
"description": "The image you wish to scan. Launches an image scan, which cannot run together with configuration scans."
},
"REGISTRYUSERNAME": {
"type": "string",
"description": "Username to a private registry that hosts the scanned image."
},
"REGISTRYPASSWORD": {
"type": "string",
"description": "Password to a private registry that hosts the scanned image."
},
"KS_IMAGE": {
"type": "string",
"default": "quay.io/codefreshplugins/kubescape",
"description": "Kubescape image to use"
},
"KS_IMAGE_VERSION": {
"type": "string",
"default": "3.0.1",
"description": "Version of the kubescape image to use"
}
}
}
stepsTemplate: |-
kubescan:
image: '[[.Arguments.KS_IMAGE]]:[[.Arguments.KS_IMAGE_VERSION]]'
title: kubescape scan
environment:
[[ range $key, $val := .Arguments ]]
- '[[ $key ]]=[[ $val ]]'
[[- end ]]
delimiters:
left: '[['
right: ']]'

0 comments on commit faec34f

Please sign in to comment.