Checkmarx One CLI (cx) for Jenkins agents on OpenShift: arbitrary UID, /certs CA trust
71
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 checksumsbash, git, jq, curl, tini/certs without a rebuild (TLS-inspecting proxies)sleep infinity) that pipeline sh steps exec intoThe 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.
| Tag | Meaning |
|---|---|
2.3.57 | cx 2.3.57 (matches the tenant). Use this in pipelines. |
YYYYMMDD-HHMMSS | Immutable build of the above, for pinning a digest-equivalent |
latest | Most recent build |
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.
| Method | Environment variables |
|---|---|
| API key (recommended) | CX_APIKEY. The key encodes the tenant and region, so nothing else is needed. |
| OAuth client | CX_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.
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 checkoutcheckmarx (this image) idles on sleep infinity and runs the scancontainer('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:
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.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.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.
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.
| Symptom | Cause / 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 authority | A TLS-inspecting proxy. Mount its root CA at /certs (see above). |
Error writing config file ... permission denied | The 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 set | USER was unset in a derived image; keep USER=cx. |
Token decoding error: token is malformed | CX_APIKEY is not a Checkmarx One API key (empty, truncated, or an OAuth secret). |
*** in --debug logs | cx masks credential values wherever they appear, so a short client id masks matching substrings too. |
.\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.
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.
Content type
Image
Digest
sha256:552b935c6…
Size
67.2 MB
Last updated
19 days ago
docker pull n8500x/checkmarx-cli