Skip to content

Commit eb92e49

Browse files
Add CLAUDE.md for ast-github-action
1 parent e3f1356 commit eb92e49

1 file changed

Lines changed: 363 additions & 0 deletions

File tree

CLAUDE.md

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
# CLAUDE.md — Checkmarx One GitHub Action
2+
3+
> Standardized Claude MD file for [ast-github-action](https://github.com/Checkmarx/ast-github-action)
4+
> Following the Claude MD standardization template defined in epic [AST-146802](https://checkmarx.atlassian.net/browse/AST-146802).
5+
6+
---
7+
8+
## Project Overview
9+
10+
The **Checkmarx One GitHub Action** integrates Checkmarx One security scanning directly into GitHub CI/CD workflows. It wraps the Checkmarx One CLI inside a Docker container action, enabling developers to trigger scans, decorate pull requests with vulnerability findings, and generate results reports — all from a standard GitHub Actions workflow file.
11+
12+
**Key capabilities:**
13+
- Run Checkmarx One scans (SAST, SCA, IaC Security / KICS) as part of any GitHub workflow
14+
- Automatic PR decoration with scan results and vulnerability summaries
15+
- Markdown results report published to the GitHub Actions step summary
16+
- Support for both GitHub Cloud and GitHub Enterprise Server (on-premises)
17+
- Multi-registry authentication for container image scanning
18+
- Automatic scan cancellation when a workflow job is cancelled
19+
- Configurable scan, utility, and results parameters with backward compatibility
20+
21+
**Supported environments:** GitHub Cloud, GitHub Enterprise Server
22+
**Supported runners:** Linux (Docker-based action)
23+
24+
---
25+
26+
## Architecture
27+
28+
The action follows a **Docker container** architecture with a modular shell-script orchestration pattern.
29+
30+
```
31+
┌──────────────────────────────────────────────────────────┐
32+
│ GitHub Actions Runner │
33+
│ ┌─────────────────────────────────────────────────────┐ │
34+
│ │ Docker Container (ast-cli base) │ │
35+
│ │ │ │
36+
│ │ entrypoint.sh (Orchestrator) │ │
37+
│ │ │ │ │
38+
│ │ ├── 1. Environment Detection │ │
39+
│ │ │ (GitHub Cloud vs Enterprise Server) │ │
40+
│ │ │ │ │
41+
│ │ ├── 2. scripts/auth.sh │ │
42+
│ │ │ Multi-registry authentication setup │ │
43+
│ │ │ │ │
44+
│ │ ├── 3. scripts/scan.sh │ │
45+
│ │ │ cx scan create → output.log → scanId │ │
46+
│ │ │ │ │
47+
│ │ ├── 4. scripts/pr_decoration.sh │ │
48+
│ │ │ cx utils pr github (if PR context) │ │
49+
│ │ │ │ │
50+
│ │ └── 5. scripts/results.sh │ │
51+
│ │ cx results show → GITHUB_STEP_SUMMARY │ │
52+
│ │ │ │
53+
│ │ cleanup.sh (post-action, runs on cancellation) │ │
54+
│ │ └── cx scan cancel --scan-id <id> │ │
55+
│ └─────────────────────────────────────────────────────┘ │
56+
│ │ │
57+
│ ▼ │
58+
│ /app/bin/cx (Checkmarx One CLI) │
59+
│ Communicates with Checkmarx One Platform │
60+
└──────────────────────────────────────────────────────────┘
61+
```
62+
63+
**Key architectural decisions:**
64+
- **Docker container action:** All logic runs inside a Docker container based on the official `checkmarx/ast-cli` image, ensuring a consistent and isolated runtime environment.
65+
- **Modular scripts:** Each phase (auth, scan, PR decoration, results) is a separate shell script sourced by the entrypoint, enabling independent maintenance and clear separation of concerns.
66+
- **Environment-aware:** The action detects GitHub Cloud vs. Enterprise Server via `GITHUB_SERVER_URL` and adjusts PR decoration behavior accordingly (auto-adds `--code-repository-url` for on-prem).
67+
- **Parameter layering:** Global parameters (`global_params`) are combined with phase-specific parameters (`scan_params`, `utils_params`, `results_params`) allowing fine-grained control.
68+
- **Backward compatibility:** The deprecated `additional_params` input is still supported and maps to `scan_params` when the latter is not provided.
69+
70+
---
71+
72+
## Repository Structure
73+
74+
```
75+
ast-github-action/
76+
├── action.yml # GitHub Action definition (inputs, outputs, Docker config)
77+
├── Dockerfile # Docker image build (FROM checkmarx/ast-cli:<version>)
78+
├── entrypoint.sh # Main orchestrator script
79+
├── cleanup.sh # Post-action: cancels in-flight scans on job cancellation
80+
├── scripts/
81+
│ ├── auth.sh # Multi-registry authentication (auth.json creation)
82+
│ ├── scan.sh # Scan creation and ID extraction
83+
│ ├── pr_decoration.sh # PR decoration via cx utils pr github
84+
│ └── results.sh # Results report generation (markdown → step summary)
85+
├── sample-yml/ # Example workflow files for users
86+
│ ├── checkmarx-ast-scan-push.yml
87+
│ ├── checkmarx-ast-scan-pull-request.yml
88+
│ ├── checkmarx-ast-scan-push-windows-env.yml
89+
│ └── checkmarx-ast-scan-sarif.yml
90+
├── docs/
91+
│ ├── contributing.md # Contribution guidelines (fork-and-pull workflow)
92+
│ └── code_of_conduct.md # Contributor Covenant 2.0
93+
├── .github/
94+
│ ├── workflows/
95+
│ │ ├── ci.yml # Integration tests (run on every PR)
96+
│ │ ├── release.yml # Release publishing workflow
97+
│ │ ├── checkmarx-one-scan.yml # Self-scan (daily + manual)
98+
│ │ ├── update-docker-image.yml # Automated CLI version bumps
99+
│ │ ├── dependabot-auto-merge.yml
100+
│ │ ├── auto-merge-pr.yml
101+
│ │ ├── issue_automation.yml
102+
│ │ └── release-drafter.yml
103+
│ ├── ISSUE_TEMPLATE/ # Bug report and enhancement request templates
104+
│ ├── PULL_REQUEST_TEMPLATE.md
105+
│ ├── dependabot.yml
106+
│ └── release-drafter.yml
107+
├── images/ # Branding images
108+
├── CODEOWNERS # @greensd4 @AlvoBen
109+
├── LICENSE # Apache 2.0
110+
├── README.md # User-facing documentation
111+
└── logo.png # Action branding logo
112+
```
113+
114+
---
115+
116+
## Technology Stack
117+
118+
| Layer | Technology | Details |
119+
|-------|-----------|---------|
120+
| Language | Bash / Shell | All logic in shell scripts |
121+
| Runtime | Docker | Container-based GitHub Action |
122+
| Base Image | `checkmarx/ast-cli` | v2.3.47 (pinned with SHA256 digest) |
123+
| Platform API | Checkmarx One CLI (`cx`) | Binary at `/app/bin/cx` inside container |
124+
| CI/CD | GitHub Actions | Workflows for CI, release, and automation |
125+
| Configuration | YAML | `action.yml` defines inputs, outputs, and Docker config |
126+
127+
---
128+
129+
## Development Setup
130+
131+
### Prerequisites
132+
133+
1. **Docker** installed locally (for building and testing the container)
134+
2. **Bash** shell environment
135+
3. **Checkmarx One account** with OAuth client credentials (`cx_client_id` + `cx_client_secret`)
136+
4. A **GitHub repository** to test the action against
137+
138+
### Clone
139+
140+
```bash
141+
git clone https://github.com/Checkmarx/ast-github-action.git
142+
cd ast-github-action
143+
```
144+
145+
### Local Testing
146+
147+
Since this is a Docker-based GitHub Action, local testing involves building and running the container:
148+
149+
```bash
150+
# Build the Docker image
151+
docker build -t ast-github-action .
152+
153+
# Run with required environment variables
154+
docker run --rm \
155+
-e CX_BASE_URI="https://your-tenant.checkmarx.net" \
156+
-e CX_TENANT="your-tenant" \
157+
-e CX_CLIENT_ID="your-client-id" \
158+
-e CX_CLIENT_SECRET="your-client-secret" \
159+
-e PROJECT_NAME="test-project" \
160+
-e BRANCH="main" \
161+
-e SOURCE_DIR="." \
162+
-e GITHUB_OUTPUT="/dev/null" \
163+
-e GITHUB_STEP_SUMMARY="/dev/null" \
164+
-v $(pwd):/source \
165+
ast-github-action
166+
```
167+
168+
For full integration testing, push changes to a branch and open a PR — the CI workflow (`.github/workflows/ci.yml`) will run the action against a real Checkmarx One instance using repository secrets.
169+
170+
---
171+
172+
## Coding Standards
173+
174+
- **Shell scripting:** All logic is written in Bash. Follow standard Bash best practices (quote variables, use `set -e` where appropriate, use arrays for parameter lists).
175+
- **Parameter parsing:** Use `eval` for splitting space-separated parameter strings into arrays. Combine global params with phase-specific params before passing to CLI commands.
176+
- **Output handling:** Write GitHub Actions outputs to `$GITHUB_OUTPUT` using the `key=value` format. Write step summaries to `$GITHUB_STEP_SUMMARY`.
177+
- **Logging:** Use `echo` for informational messages. Prefix warnings with a warning emoji. Never log secrets or credentials.
178+
- **Exit codes:** Propagate CLI exit codes via `${PIPESTATUS[0]}`. Non-zero exit codes should cause the action to fail.
179+
- **File naming:** Shell scripts use snake_case (e.g., `pr_decoration.sh`). Workflow files use kebab-case (e.g., `update-docker-image.yml`).
180+
181+
---
182+
183+
## Project Rules
184+
185+
- **All PRs target `main`** unless explicitly coordinated otherwise.
186+
- **Branch naming:**
187+
- Features: `feature/<issue#>-descriptive-name`
188+
- Hotfixes: `hotfix/<issue#>-descriptive-name`
189+
- **PRs must be associated** with an accepted GitHub issue (enhancement or bug).
190+
- **Never commit secrets.** Checkmarx credentials are injected via GitHub Actions secrets or environment variables at runtime — never hardcoded.
191+
- **CLI version** is pinned in the `Dockerfile` (`FROM checkmarx/ast-cli:<version>@sha256:<digest>`). Updates are automated via the `update-docker-image.yml` workflow.
192+
- **Code owners:** @greensd4 and @AlvoBen must approve all PRs.
193+
- **PR size:** Keep PRs focused on a single concern. Fix functionality or address code style, not both.
194+
- **Fork-and-pull workflow:** External contributors fork the repo, create a branch, and submit a PR back.
195+
196+
---
197+
198+
## Testing Strategy
199+
200+
### Test Types
201+
202+
| Type | Where | Runner | Purpose |
203+
|------|-------|--------|---------|
204+
| Integration (CI) | `.github/workflows/ci.yml` | GitHub Actions (ubuntu-latest) | End-to-end tests against a real Checkmarx One instance |
205+
| Self-scan | `.github/workflows/checkmarx-one-scan.yml` | GitHub Actions | Scans this repo's own code daily |
206+
207+
### CI Test Scenarios
208+
209+
The CI workflow (triggered on every PR) runs the following integration tests:
210+
211+
1. **Empty credentials failure** — Verifies the action fails when `cx_client_id` and `cx_client_secret` are empty
212+
2. **Valid scan** — Runs a full scan with `--file-include *.sh,Dockerfile --scan-types kics`, validates scan ID and CLI output are non-empty
213+
3. **Invalid preset name** — Verifies the action fails when an invalid SAST preset name is provided
214+
4. **Source directory** — Validates scanning a specific subdirectory via the `source_dir` input
215+
216+
### Required Secrets for CI
217+
218+
| Secret | Purpose |
219+
|--------|---------|
220+
| `CX_BASE_URI` | Checkmarx One portal URL |
221+
| `CX_TENANT` | Tenant identifier |
222+
| `CX_CLIENT_ID` | OAuth client ID |
223+
| `CX_CLIENT_SECRET` | OAuth client secret |
224+
225+
---
226+
227+
## External Integrations
228+
229+
| Integration | Purpose | How |
230+
|-------------|---------|-----|
231+
| **Checkmarx One Platform** | Run scans, fetch results, PR decoration | Via Checkmarx CLI (`/app/bin/cx`) inside Docker container |
232+
| **GitHub Actions** | CI/CD runtime, workflow triggers, secrets management | Native GitHub Actions integration via `action.yml` |
233+
| **GitHub API** | PR decoration (posting scan results as PR comments) | Via `cx utils pr github` with `GITHUB_TOKEN` |
234+
| **Docker Hub** | Base image hosting (`checkmarx/ast-cli`) | Pulled during Docker build |
235+
| **Container Registries** | Multi-registry auth for image scanning | Configured via `auth.sh` using `REGISTRIES` env var |
236+
237+
---
238+
239+
## Deployment
240+
241+
### Release Process
242+
243+
Releases are managed via `.github/workflows/release.yml` (triggered manually via `workflow_dispatch`):
244+
245+
1. Extract CLI version from the Dockerfile
246+
2. Create a git tag with the release version
247+
3. Publish a GitHub Release with auto-generated changelog (via release-drafter)
248+
4. Notify downstream systems
249+
250+
### CLI Version Updates
251+
252+
The CLI version is updated automatically via `.github/workflows/update-docker-image.yml`:
253+
254+
1. Detects new `checkmarx/ast-cli` releases on Docker Hub
255+
2. Updates the `FROM` line and SHA256 digest in the `Dockerfile`
256+
3. Creates a PR with the update for review
257+
258+
### Distribution
259+
260+
- **GitHub Marketplace:** Published as a GitHub Action on the GitHub Marketplace
261+
- **Direct reference:** Users reference the action via `Checkmarx/ast-github-action@<version>` in their workflows
262+
263+
### Usage (End Users)
264+
265+
```yaml
266+
- name: Checkmarx One Scan
267+
uses: Checkmarx/ast-github-action@main
268+
with:
269+
base_uri: ${{ secrets.CX_BASE_URI }}
270+
cx_tenant: ${{ secrets.CX_TENANT }}
271+
cx_client_id: ${{ secrets.CX_CLIENT_ID }}
272+
cx_client_secret: ${{ secrets.CX_CLIENT_SECRET }}
273+
scan_params: "--scan-types sast,sca,kics"
274+
```
275+
276+
---
277+
278+
## Security & Access
279+
280+
- **OAuth authentication:** Users provide `cx_client_id` and `cx_client_secret` which are passed as environment variables to the Docker container. These must be stored as GitHub Actions secrets.
281+
- **GitHub Token:** The `github_token` input defaults to the automatic `github.token` and is used for PR decoration. It is never logged.
282+
- **No credentials in code:** All secrets are injected at runtime via GitHub Actions secrets and environment variables. Never commit API keys, client IDs, or client secrets.
283+
- **TLS:** All communication with Checkmarx One is HTTPS, enforced by the CLI.
284+
- **Docker isolation:** The action runs in an isolated Docker container, preventing interference with the host runner environment.
285+
- **Registry credentials:** Multi-registry auth credentials are constructed in-memory as `auth.json` and never written to logs.
286+
287+
---
288+
289+
## Action Inputs & Outputs
290+
291+
### Inputs
292+
293+
| Input | Required | Default | Description |
294+
|-------|----------|---------|-------------|
295+
| `base_uri` | Yes | — | Checkmarx One portal URL |
296+
| `cx_tenant` | Yes | — | Tenant identifier |
297+
| `cx_client_id` | Yes | — | OAuth client ID |
298+
| `cx_client_secret` | Yes | — | OAuth client secret |
299+
| `project_name` | No | `github.repository` | Checkmarx project name |
300+
| `branch` | No | `github.head_ref \|\| github.ref` | Branch name for the scan |
301+
| `github_token` | No | `github.token` | GitHub API token for PR decoration |
302+
| `source_dir` | No | `.` | Source directory to scan |
303+
| `global_params` | No | `''` | Parameters applied to all `cx` commands |
304+
| `scan_params` | No | `''` | Parameters for `cx scan create` only |
305+
| `utils_params` | No | `''` | Parameters for `cx utils pr` only |
306+
| `results_params` | No | `''` | Parameters for `cx results show` only |
307+
| `additional_params` | No | `''` | **DEPRECATED** — use `scan_params` instead |
308+
| `repo_name` | No | `github.event.repository.name` | Repository name for PR decoration |
309+
| `namespace` | No | `github.repository_owner` | Organization name for PR comment |
310+
| `pr_number` | No | `github.event.number` | PR number for decoration |
311+
312+
### Outputs
313+
314+
| Output | Description |
315+
|--------|-------------|
316+
| `cxcli` | Full CLI output from the scan |
317+
| `cxScanID` | The scan ID created by Checkmarx One |
318+
319+
---
320+
321+
## Debugging Steps
322+
323+
### Action fails with authentication error
324+
325+
1. Verify `cx_client_id` and `cx_client_secret` are correctly set in GitHub Actions secrets
326+
2. Confirm the OAuth client has the required roles on the Checkmarx One tenant
327+
3. Check that `base_uri` and `cx_tenant` are correct
328+
329+
### Scan completes but no PR decoration
330+
331+
1. Confirm the workflow is triggered by a `pull_request` event (PR number must be available)
332+
2. Check that `github_token` has permissions to write PR comments
333+
3. For GitHub Enterprise Server, verify the action correctly detects on-prem and adds `--code-repository-url`
334+
335+
### Empty scan results / no step summary
336+
337+
1. Verify the scan ID was extracted successfully (check `cxScanID` output)
338+
2. Ensure `results_params` does not conflict with the default `--report-format markdown`
339+
3. Check the GitHub Actions log for CLI error messages
340+
341+
### Action hangs or times out
342+
343+
1. Check if the Checkmarx One platform is accessible from the runner
344+
2. Verify network connectivity (firewalls, proxies) between the GitHub runner and `base_uri`
345+
3. For large repositories, consider using `source_dir` to limit the scan scope or `--file-include`/`--file-exclude` filters
346+
347+
### Testing changes locally
348+
349+
1. Build the Docker image: `docker build -t ast-github-action .`
350+
2. Run with mock environment variables to verify script logic
351+
3. For full integration testing, push to a branch and open a PR to trigger CI
352+
353+
---
354+
355+
## Known Patterns & Conventions
356+
357+
- **Parameter splitting:** All parameter inputs (`global_params`, `scan_params`, etc.) are space-separated strings that get split into Bash arrays using `eval`. Users can pass multiple flags like `--scan-types sast,sca --file-include *.java`.
358+
- **Scan ID extraction:** The scan ID is parsed from the CLI JSON output using `grep` and `cut` — it looks for the `"ID"` field in the JSON response.
359+
- **Output file:** The scan output is tee'd to `./output.log`, which is also used by `cleanup.sh` to extract the scan ID for cancellation.
360+
- **Global params inheritance:** `global_arr` is set once in `scan.sh` and reused by `pr_decoration.sh` and `results.sh` because all scripts are sourced (not executed as subprocesses).
361+
362+
---
363+

0 commit comments

Comments
 (0)