Sign inSign up

n8500x/checkmarx-cli

By n8500x

•Updated 19 days ago

Checkmarx One CLI (cx) for Jenkins agents on OpenShift: arbitrary UID, /certs CA trust

Image
0

71

n8500x/checkmarx-cli repository overview

⁠n8500x/checkmarx-cli

The Checkmarx One CLI (cx, Checkmarx/ast-cli⁠, Apache-2.0) packaged for running scans from Jenkins Kubernetes-plugin agents on on-prem OpenShift.

  • cx 2.3.57, pinned and SHA-256-verified against the upstream release checksums
  • Alpine 3.24, fully patched at build time (38 packages); bash, git, jq, curl, tini
  • Runs under OpenShift restricted-v2 as an arbitrary UID: no anyuid, no root, no added capabilities
  • Trusts a corporate root CA mounted at /certs without a rebuild (TLS-inspecting proxies)
  • Works as an idle sidecar (sleep infinity) that pipeline sh steps exec into

The scan engines run in your Checkmarx One tenant. This image is the client: it zips the workspace, uploads it, waits for the scan, applies thresholds and writes the reports.

⁠Tags

TagMeaning
2.3.57cx 2.3.57 (matches the tenant). Use this in pipelines.
YYYYMMDD-HHMMSSImmutable build of the above, for pinning a digest-equivalent
latestMost recent build

⁠Quick start (any Docker host)

docker run --rm -v "$PWD:/src" -e CX_APIKEY="$CX_APIKEY" n8500x/checkmarx-cli:2.3.57 \
  scan create --project-name my-app --branch main -s . \
  --scan-types sast,sca,iac-security \
  --report-format summaryConsole,json,sarif \
  --output-path cx-results --threshold "sast-high=1"

Arguments go straight to cx (scan create ..., --help, version, or a leading cx). If the first argument is a program in the image (bash, sh, sleep, jq, ...) it is run instead:

docker run --rm n8500x/checkmarx-cli:2.3.57 version                 # 2.3.57
docker run --rm n8500x/checkmarx-cli:2.3.57 scan create --help
docker run --rm -it n8500x/checkmarx-cli:2.3.57 bash

cx exits non-zero when a --threshold is breached, which is what fails a CI build.

⁠Authentication

MethodEnvironment variables
API key (recommended)CX_APIKEY. The key encodes the tenant and region, so nothing else is needed.
OAuth clientCX_CLIENT_ID, CX_CLIENT_SECRET, CX_BASE_URI, CX_BASE_AUTH_URI, CX_TENANT

Every flag has an environment-variable form (cx utils env lists them), e.g. CX_TIMEOUT, CX_BRANCH. Check credentials without scanning: cx auth validate.

⁠Jenkins on OpenShift

Copy openshift/podtemplate.yaml⁠ and examples/Jenkinsfile⁠ into the application repo. The pod runs two containers on a shared workspace emptyDir:

  • jnlp (n8500x/jenkins-jnlp-agent) does the checkout
  • checkmarx (this image) idles on sleep infinity and runs the scan
container('checkmarx') {
    withCredentials([string(credentialsId: 'cx-one-api-key', variable: 'CX_APIKEY')]) {
        sh '''
          cx scan create --project-name "${JOB_NAME%/*}" --branch "${BRANCH_NAME}" -s . \
            --scan-types sast,sca,iac-security \
            --report-format summaryConsole,json,sarif,summaryHTML \
            --output-path cx-results --output-name cx --agent Jenkins \
            --threshold "sast-high=1;sca-high=1"
        '''
    }
}
archiveArtifacts artifacts: 'cx-results/**', allowEmptyArchive: true

Rules the pod template follows, and why:

  • Use args: ["sleep", "infinity"], not command:. The image's entrypoint registers the OpenShift-assigned UID in /etc/passwd before idling, and cx finds its config directory through that entry. A command: override skips the entrypoint. cx still works then (the image sets USER/HOME for Go's fallback), but git and anything else calling getpwuid() will not.
  • Never set runAsUser. Let the SCC assign the namespace UID. Everything the CLI writes (/home/cx, /home/jenkins, /src) is group-0 writable.
  • /usr/bin holds links to every /bin applet, so a controller-injected PATH that lacks /bin still finds sh.
⁠Air-gapped cluster: mirror the image
skopeo copy docker://docker.io/n8500x/checkmarx-cli:2.3.57 \
  docker://image-registry.openshift-image-registry.svc:5000/<ns>/checkmarx-cli:2.3.57

The cluster still needs outbound HTTPS to your Checkmarx One region (e.g. eu.ast.checkmarx.net and eu.iam.checkmarx.net), directly or through a proxy.

⁠Corporate CA and proxy

CA: SSL_CERT_DIR=/etc/ssl/certs:/certs, so every *.crt/*.pem mounted at /certs is trusted in addition to the system bundle:

oc create configmap corp-root-ca --from-file=corp-root.crt=corp-root.pem
# the pod template mounts it at /certs (optional: true, so a missing ConfigMap is fine)

docker run --rm -v /etc/pki/corp:/certs:ro -e CX_APIKEY ... n8500x/checkmarx-cli:2.3.57 auth validate

Avoid --insecure except to diagnose.

Proxy: set HTTPS_PROXY/NO_PROXY or pass --proxy http://host:port. NTLM and Kerberos proxies are supported via --proxy-auth-type ntlm|kerberos and the --proxy-ntlm-* / --proxy-kerberos-* flags.

⁠Troubleshooting

SymptomCause / fix
Could not reach provided Checkmarx server ...Generic message. Re-run with --debug to see the real cause (DNS, proxy, x509: certificate signed by unknown authority).
x509: certificate signed by unknown authorityA TLS-inspecting proxy. Mount its root CA at /certs (see above).
Error writing config file ... permission deniedThe config directory comes from the passwd entry, not $HOME. Don't override the entrypoint, and don't bake a .checkmarx directory into a derived image.
user: Current requires cgo or $USER setUSER was unset in a derived image; keep USER=cx.
Token decoding error: token is malformedCX_APIKEY is not a Checkmarx One API key (empty, truncated, or an OAuth secret).
*** in --debug logscx masks credential values wherever they appear, so a short client id masks matching substrings too.

⁠Build and test

.\build.ps1            # fetch + verify the cx tarball on the host, build, smoke test as a random UID
.\test.ps1             # 10 offline checks: OpenShift UID, sidecar, PATH shim, /certs CA trust vs a mock TLS endpoint
.\build.ps1 -Push -Overview

The release tarball goes into vendor/ on the host and the Dockerfile verifies its SHA-256, so the build makes no GitHub call. On a TLS-intercepting build host, pass the proxy CA as a BuildKit secret (--secret id=extra_ca,src=corp-root.pem); it is used only for apk and never written to a layer.

Bumping cx: set CX_VERSION plus CX_SHA256_AMD64/CX_SHA256_ARM64 in the Dockerfile from https://github.com/Checkmarx/ast-cli/releases/download/<ver>/ast-cli_<ver>_checksums.txt, and run .\build.ps1 -CxVersion <ver> then .\test.ps1 -CxVersion <ver>. Keep it in step with your tenant.

⁠Licence

cx is Apache-2.0 (licence text at /usr/share/licenses/ast-cli/LICENSE in the image). A Checkmarx One subscription is required to scan.

Tag summary

Content type

Image

Digest

sha256:552b935c6…

Size

67.2 MB

Last updated

19 days ago

docker pull n8500x/checkmarx-cli