diff --git a/.github/workflows/checkmarx-one-scan.yml b/.github/workflows/checkmarx-one-scan.yml
index 0c441b73..b79dea3a 100644
--- a/.github/workflows/checkmarx-one-scan.yml
+++ b/.github/workflows/checkmarx-one-scan.yml
@@ -8,6 +8,10 @@ on:
schedule:
- cron: "00 7 * * *" # Every day at 07:00
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
permissions:
contents: read
@@ -20,6 +24,8 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ with:
+ persist-credentials: false
- name: Checkmarx One CLI Action
uses: checkmarx/ast-github-action@ef93013c95adc60160bc22060875e90800d3ecfc #v.2.3.19
with:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e1f15117..6cac29e0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,11 +2,15 @@ name: AST Java Wrapper CI
on: [ pull_request ]
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
permissions:
contents: read
jobs:
- integration-tests:
+ integration-tests: # zizmor: ignore[anonymous-definition]
permissions:
contents: read
runs-on: cx-public-ubuntu-x64
@@ -16,6 +20,7 @@ jobs:
with:
token: ${{ secrets.GITHUB_TOKEN }}
lfs: true
+ persist-credentials: false
- name: Install Git LFS
run: |
@@ -34,7 +39,28 @@ jobs:
- name: Configure echo mirror for dependency resolution
run: |
- sed -i 's||echocentralhttps://maven.echohq.com|' ~/.m2/settings.xml
+ mkdir -p ~/.m2
+ cat > ~/.m2/settings.xml << EOF
+
+
+
+
+ echo-repo
+ *
+ https://maven.echohq.com
+
+
+
+
+ echo-repo
+
+ ${ECHO_LIBRARIES_ACCESS_KEY}
+
+
+
+ EOF
+ env:
+ ECHO_LIBRARIES_ACCESS_KEY: ${{ secrets.ECHO_LIBRARIES_ACCESS_KEY }}
- name: Check existence of cx-linux binary
run: |
diff --git a/.github/workflows/manual-tag.yml b/.github/workflows/manual-tag.yml
index 57f0d508..aad5bf3f 100644
--- a/.github/workflows/manual-tag.yml
+++ b/.github/workflows/manual-tag.yml
@@ -7,11 +7,16 @@ on:
description: 'Next release tag'
required: true
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
+
permissions:
contents: read
jobs:
tag-creation:
+ name: Tag Creation
permissions:
contents: write # for Git to git push
runs-on: cx-public-ubuntu-x64
@@ -19,17 +24,20 @@ jobs:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
- token: ${{ secrets.GITHUB_TOKEN }}
+ persist-credentials: false
- name: Tag
env:
INPUT_TAG: ${{ github.event.inputs.tag }}
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_TITLE: ${{ github.event.pull_request.title }}
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REPO: ${{ github.repository }}
run: |
echo "$INPUT_TAG"
echo "NEXT_VERSION=$INPUT_TAG" >> $GITHUB_ENV
message="$INPUT_TAG: PR #$PR_NUMBER $PR_TITLE"
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
+ git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${REPO}"
git tag -a "$INPUT_TAG" -m "$message"
git push origin "$INPUT_TAG"
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 5a8b2c9f..40033e07 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -6,20 +6,26 @@ on:
# branches:
# - main
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
+
permissions:
contents: read
jobs:
delete_tag:
+ name: Delete Tag
permissions:
- contents: write
+ contents: write # for gh release delete to remove tags and releases
runs-on: cx-public-ubuntu-x64
steps:
- name: Delete release and tag
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ GH_REPO: ${{ github.repository }}
run: |
- gh release delete "1.0.0-SNAPSHOT" --yes --cleanup-tag --repo ${{ github.repository }} || true
+ gh release delete "1.0.0-SNAPSHOT" --yes --cleanup-tag --repo "${GH_REPO}" || true
nightly:
needs: delete_tag
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 81520b37..797fc193 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -50,15 +50,22 @@ on:
required: true
OSSRH_USERNAME:
required: true
+ ECHO_LIBRARIES_ACCESS_KEY:
+ required: true
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
permissions:
contents: read
jobs:
release:
+ name: Release
permissions:
- id-token: write
- contents: write
+ id-token: write # for Maven Central publishing via OIDC
+ contents: write # for git push tag and creating GitHub release
runs-on: cx-public-ubuntu-x64
outputs:
CLI_VERSION: ${{ steps.extract_cli_version.outputs.CLI_VERSION }}
@@ -67,8 +74,8 @@ jobs:
- name: Checkout
uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
- token: ${{ secrets.GITHUB_TOKEN }}
lfs: true
+ persist-credentials: false
- name: Download CLI
if: inputs.cliTag
@@ -105,11 +112,14 @@ jobs:
id: set_tag_name
env:
INPUT_TAG: ${{ inputs.tag }}
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ REPO: ${{ github.repository }}
run: |
echo "$INPUT_TAG"
echo "RELEASE_VERSION=$INPUT_TAG" >> $GITHUB_ENV
git config user.name "${GITHUB_ACTOR}"
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com"
+ git remote set-url origin "https://x-access-token:${GH_TOKEN}@github.com/${REPO}"
git tag -a "$INPUT_TAG" -m "$INPUT_TAG"
git push origin "$INPUT_TAG"
echo "TAG_NAME=$INPUT_TAG" >> $GITHUB_OUTPUT
@@ -127,7 +137,10 @@ jobs:
- name: Configure echo mirror for dependency resolution
run: |
- sed -i 's||echocentralhttps://maven.echohq.com|' ~/.m2/settings.xml
+ sed -i 's||echo-repo'"$ECHO_LIBRARIES_ACCESS_KEY"'|' ~/.m2/settings.xml
+ sed -i 's||echo-repo*https://maven.echohq.com|' ~/.m2/settings.xml
+ env:
+ ECHO_LIBRARIES_ACCESS_KEY: ${{ secrets.ECHO_LIBRARIES_ACCESS_KEY }}
- name: Update the POM version.
run: mvn -B versions:set -DnewVersion="$RELEASE_VERSION" --file pom.xml -DskipTests
diff --git a/.github/workflows/scan-github-action.yml b/.github/workflows/scan-github-action.yml
new file mode 100644
index 00000000..12731513
--- /dev/null
+++ b/.github/workflows/scan-github-action.yml
@@ -0,0 +1,31 @@
+name: Scan for GitHub Actions issues
+
+on:
+ pull_request:
+ workflow_call:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.repository }}-${{ github.ref }}
+
+permissions: {}
+
+jobs:
+ zizmor:
+ name: Scan repository contents
+ runs-on: cx-public-ubuntu-x64
+ permissions:
+ contents: read
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+ with:
+ persist-credentials: false
+
+ - name: Run Zizmor linter
+ uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6
+ with:
+ advanced-security: false
+ annotations: false
+ persona: pedantic
+ fail-on-no-inputs: false
+ online-audits: false
diff --git a/.github/workflows/update-cli.yml b/.github/workflows/update-cli.yml
index 64037254..1d42cf93 100644
--- a/.github/workflows/update-cli.yml
+++ b/.github/workflows/update-cli.yml
@@ -3,17 +3,23 @@ name: Update checkmarx ast cli
on:
workflow_dispatch:
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: false
+
permissions:
contents: read
jobs:
update_cli:
+ name: Update CLI
runs-on: cx-public-ubuntu-x64
steps:
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
lfs: true
+ persist-credentials: false
- name: Install Git LFS
run: |
diff --git a/.gitignore b/.gitignore
index d6921c32..921e4fdf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,4 +32,5 @@ docker-compose.override.yml
#################################
Thumbs.db
.directory
-.DS_Store
\ No newline at end of file
+.DS_Store
+/.vscode
diff --git a/Claude.md b/Claude.md
new file mode 100644
index 00000000..c0c3be08
--- /dev/null
+++ b/Claude.md
@@ -0,0 +1,598 @@
+# Cloud.md - AST CLI Java Wrapper Repository
+
+## Project Overview
+
+The **ast-cli-java-wrapper** is a Java SDK/wrapper library that provides a shared infrastructure and abstraction layer for the Checkmarx Application Security Testing (AST) platform. It serves as a client library for integrating AST capabilities into Java-based applications and CI/CD pipelines. The wrapper offers technology-neutral repository interfaces and a metadata model for persisting Java classes, enabling developers to interact with the AST platform programmatically.
+
+**Repository:** https://github.com/CheckmarxDev/ast-cli-java-wrapper
+**Package:** Published as Maven dependency (com.checkmarx.ast:ast-cli-java-wrapper)
+
+---
+
+## Architecture
+
+The ast-cli-java-wrapper follows a modular architecture with clear separation of concerns:
+
+```
+ast-cli-java-wrapper/
+├── src/main/java/com/checkmarx/ast/
+│ ├── wrapper/ # Core wrapper utilities (CxConfig, CxException, CxConstants)
+│ ├── asca/ # ASCA (Application Source Code Analysis) module
+│ ├── codebashing/ # CodeBashing integration
+│ ├── containersrealtime/ # Container scanning real-time results
+│ ├── iacrealtime/ # IaC (Infrastructure as Code) real-time results
+│ ├── kicsRealtimeResults/ # KICS (Kics Infrastructure Code Scanner) results
+│ ├── ossrealtime/ # OSS (Open Source Software) real-time vulnerability scanning
+│ ├── learnMore/ # Learning resources integration
+│ ├── mask/ # Secret masking functionality
+│ ├── project/ # Project management interfaces
+│ ├── scan/ # Scan management
+│ ├── results/ # Result handling and processing
+│ ├── remediation/ # Remediation guidance
+│ ├── predicate/ # Predicate-based filtering
+│ └── tenant/ # Tenant management
+├── src/test/java/ # Unit tests (JUnit 5)
+└── src/main/resources/ # Configuration resources
+```
+
+**Design Pattern:** The wrapper uses a layered architecture with:
+- **Interface Layer:** Technology-neutral interfaces for extensibility
+- **Implementation Layer:** Concrete implementations for AST integration
+- **Data Model Layer:** POJOs (Plain Old Java Objects) for data persistence and serialization
+- **Utility Layer:** Configuration management (CxConfig), exception handling (CxException), and constants
+
+---
+
+## Repository Structure
+
+```
+.
+├── pom.xml # Maven configuration and dependencies
+├── README.md # User-facing documentation
+├── Cloud.md # This file - development/deployment documentation
+├── src/
+│ ├── main/
+│ │ ├── java/ # Production source code
+│ │ └── resources/ # Configuration files and resources
+│ └── test/
+│ ├── java/ # Unit tests (JUnit 5 + Jupiter)
+│ └── resources/ # Test configuration and fixtures
+├── target/ # Build output (generated during maven clean install)
+└── .github/ # GitHub Actions, workflows (if present)
+```
+
+**Key Files:**
+- `pom.xml` - Defines Maven build configuration, dependencies, and JaCoCo code coverage plugin
+- `src/main/java/com/checkmarx/ast/wrapper/CxConfig.java` - Core configuration class
+- `src/main/java/com/checkmarx/ast/wrapper/CxException.java` - Custom exception handling
+- `src/main/java/com/checkmarx/ast/wrapper/CxConstants.java` - Application constants
+
+---
+
+## Technology Stack
+
+| Component | Technology | Version |
+|-----------|-----------|---------|
+| **Language** | Java | 8+ |
+| **Build Tool** | Maven | 3+ |
+| **JSON Processing** | Jackson | 2.21.1 |
+| **JSON Serialization** | GSON | 2.12.1 |
+| **Utilities** | Lombok | 1.18.32 |
+| **Commons** | Apache Commons Lang3 | 3.18.0 |
+| **JSON Parsing** | JSON-Simple | 1.1.1 |
+| **Logging** | SLF4J | 2.0.12 |
+| **Testing** | JUnit 5 (Jupiter) | 5.10.2 |
+| **Code Coverage** | JaCoCo | 0.8.8 |
+
+**Key Dependencies:**
+- **Jackson** - Primary JSON serialization/deserialization framework
+- **GSON** - Alternative/supplementary JSON processing
+- **Lombok** - Reduces boilerplate via annotations (@Data, @Getter, @Setter, etc.)
+- **SLF4J** - Logging abstraction layer with slf4j-simple binding
+- **JUnit 5** - Modern testing framework with parameterized tests and extensions
+
+---
+
+## Development Setup
+
+### Prerequisites
+
+- **Java Development Kit (JDK):** Version 8 or higher
+ - Download from [Oracle JDK](https://www.oracle.com/java/technologies/downloads/) or use OpenJDK
+ - Verify: `java -version` and `javac -version`
+
+- **Maven:** Version 3.6.0 or higher
+ - Download from [Apache Maven](https://maven.apache.org/download.cgi)
+ - Verify: `mvn -version`
+
+- **Git:** For cloning and version control
+
+### Local Setup Steps
+
+1. **Clone the repository:**
+ ```bash
+ git clone https://github.com/CheckmarxDev/ast-cli-java-wrapper.git
+ cd ast-cli-java-wrapper
+ ```
+
+2. **Build the project:**
+ ```bash
+ mvn clean install
+ ```
+ - Compiles source code, runs tests, and generates JAR artifact
+ - Output: `target/ast-cli-java-wrapper-[version].jar`
+
+3. **Run tests:**
+ ```bash
+ mvn test
+ ```
+
+4. **Generate code coverage report:**
+ ```bash
+ mvn test jacoco:report
+ ```
+ - Coverage report available at: `target/site/jacoco/index.html`
+
+5. **Install to local Maven repository:**
+ ```bash
+ mvn install
+ ```
+
+### Integration Tests Setup
+
+To run integration tests that interact with the AST platform, set environment variables:
+
+**Linux/macOS:**
+```bash
+export CX_CLIENT_ID="your_client_id"
+export CX_CLIENT_SECRET="your_client_secret"
+export CX_APIKEY="your_api_key"
+export CX_BASE_URI="https://ast.checkmarx.net"
+export CX_BASE_AUTH_URI="https://iam.checkmarx.net"
+export CX_TENANT="your_tenant_name"
+export PATH_TO_EXECUTABLE="/path/to/ast-cli-executable"
+```
+
+**Windows (PowerShell):**
+```powershell
+setx CX_CLIENT_ID "your_client_id"
+setx CX_CLIENT_SECRET "your_client_secret"
+setx CX_APIKEY "your_api_key"
+setx CX_BASE_URI "https://ast.checkmarx.net"
+setx CX_BASE_AUTH_URI "https://iam.checkmarx.net"
+setx CX_TENANT "your_tenant_name"
+setx PATH_TO_EXECUTABLE "path\to\ast-cli-executable"
+```
+
+### IDE Configuration
+
+- **IntelliJ IDEA:** Import project as Maven project, mark `src/main/java` as Sources Root, `src/test/java` as Tests Root
+- **Eclipse:** Use `mvn eclipse:eclipse` or import via "Existing Maven Projects"
+- **VS Code:** Install "Extension Pack for Java" and "Maven for Java" extensions
+
+---
+
+## Coding Standards
+
+### Code Style Guidelines
+
+1. **Naming Conventions:**
+ - Classes: PascalCase (e.g., `CxConfig`, `ScanResult`)
+ - Methods/Variables: camelCase (e.g., `getScanId()`, `scanDetails`)
+ - Constants: UPPER_SNAKE_CASE (e.g., `MAX_TIMEOUT`, `DEFAULT_PORT`)
+ - Private fields: prefix with underscore or use Lombok annotations
+
+2. **Lombok Annotations:**
+ - Use `@Data` for POJOs (generates getters, setters, equals, hashCode, toString)
+ - Use `@Getter` / `@Setter` for selective generation
+ - Use `@AllArgsConstructor` / `@NoArgsConstructor` for constructors
+ - Avoid verbose getter/setter implementations
+
+3. **Jackson Annotations:**
+ - Use `@JsonProperty("fieldName")` for JSON serialization mapping
+ - Use `@JsonIgnore` for excluding fields from JSON
+ - Use `@JsonDeserialize` / `@JsonSerialize` for custom type handling
+
+4. **Documentation:**
+ - Add JavaDoc comments for public classes and methods
+ - Keep comments concise and explain the "why", not the "what"
+ - Include examples in JavaDoc for complex methods
+
+5. **Exception Handling:**
+ - Extend `CxException` for domain-specific exceptions
+ - Use try-catch only for exceptional conditions, not control flow
+ - Log exceptions with appropriate level (error, warn, debug)
+
+6. **Code Organization:**
+ - Keep classes focused on a single responsibility
+ - Group related methods and fields together
+ - Use access modifiers appropriately (private by default, public only when needed)
+
+### Code Quality Tools
+
+- **JaCoCo Code Coverage:** Minimum coverage target is maintained via `pom.xml` configuration
+ - Excluded packages (data models, generated code) specified in JaCoCo excludes
+ - Run: `mvn jacoco:report` to generate coverage report
+
+- **Maven Compiler:** Configured for Java 8 compatibility
+ - Source: Java 8
+ - Target: Java 8
+ - Encoding: UTF-8
+
+---
+
+## Project Rules
+
+1. **Branching Strategy:**
+ - Main development branch: `main`
+ - Feature branches: `feature/*`
+ - Bug fixes: `bugfix/*`
+ - Hotfixes: `hotfix/*`
+ - Delete merged branches to keep repository clean
+
+2. **Commit Standards:**
+ - Write clear, descriptive commit messages
+ - Reference Jira ticket IDs in commit messages (e.g., "AST-12345: Add feature description")
+ - Keep commits atomic and logically grouped
+
+3. **Pull Requests:**
+ - Create PR against `main` branch
+ - Include description and acceptance criteria
+ - Ensure all tests pass before merging
+ - Require code review from at least one team member
+ - Squash commits on merge for cleaner history
+
+4. **Version Management:**
+ - Versions defined in `pom.xml` as `${ast.wrapper.version}`
+ - Follow semantic versioning (MAJOR.MINOR.PATCH)
+ - Update version before release
+ - Tag releases in Git (e.g., `v1.0.14`)
+
+5. **Dependency Management:**
+ - Keep dependencies updated, especially security patches
+ - Use Maven Dependabot or similar tools for automatic updates
+ - Review dependency changes in PRs for breaking changes
+ - Exclude conflicting transitive dependencies if needed
+
+6. **Documentation:**
+ - Keep README.md and Cloud.md synchronized with changes
+ - Document API changes in PR descriptions
+ - Update environment variables list if new ones are required
+
+---
+
+## Testing Strategy
+
+### Testing Pyramid
+
+```
+ /\
+ / \ Integration Tests (Integration with AST platform)
+ /____\
+ / \
+ / \ Unit Tests (JUnit 5 - ~80% of tests)
+ /________\
+ / \
+ / \ Manual Testing & E2E
+ /____________\
+```
+
+### Unit Testing
+
+- **Framework:** JUnit 5 (Jupiter)
+- **Location:** `src/test/java/`
+- **Naming Convention:** `*Test.java` or `*Tests.java`
+- **Coverage Target:** >70% for core modules
+- **Execution:** `mvn test`
+
+**Example Unit Test Structure:**
+```java
+@DisplayName("ScanResult Tests")
+class ScanResultTest {
+ @Test
+ @DisplayName("Should deserialize scan result from JSON")
+ void testDeserializeScanResult() {
+ // Test implementation
+ }
+}
+```
+
+### Integration Tests
+
+- **Environment Setup:** Requires AST platform credentials (see Development Setup)
+- **Credentials:** Use environment variables for sensitive data
+- **Isolation:** Test data should be isolated and cleaned up after tests
+- **Skip in CI:** Can be skipped in pull request CI if platform access is limited
+
+### Test Fixtures & Mocks
+
+- Use JSON files in `src/test/resources/` for sample data
+- Mock external dependencies where appropriate
+- Use parameterized tests (`@ParameterizedTest`) for multiple scenarios
+
+### Code Coverage
+
+- **Tool:** JaCoCo Maven Plugin
+- **Report Location:** `target/site/jacoco/index.html`
+- **Excluded from Coverage:** Data models, POJOs, generated code (as specified in pom.xml)
+- **Run:** `mvn test jacoco:report`
+
+---
+
+## Known Issues
+
+1. **Java 8 Compatibility:** The project targets Java 8 for compatibility with older systems, which limits access to newer Java features (records, text blocks, sealed classes, etc.)
+
+2. **Dual JSON Libraries:** Both Jackson and GSON are included as dependencies, which may lead to subtle differences in serialization behavior. Prefer Jackson for primary serialization unless GSON is specifically required.
+
+3. **SLF4J Simple Binding:** The `slf4j-simple` binding is basic and may not be suitable for production environments. Consider switching to Logback or Log4j2 for advanced features.
+
+4. **JaCoCo Excludes:** Large portions of the codebase are excluded from code coverage (data models, results, etc.), which may mask untested code paths. Review excludes periodically.
+
+5. **Maven Build Performance:** Large transitive dependency trees and full coverage analysis can slow down builds. Use `mvn clean install -DskipTests` for faster builds during development.
+
+---
+
+## Database Schema
+
+Not applicable - this is a client library with no persistent storage or database dependencies.
+
+---
+
+## External Integrations
+
+1. **Checkmarx AST Platform:**
+ - **Purpose:** Provides security scanning, remediation guidance, and vulnerability data
+ - **Integration Points:** REST API calls via HTTP clients
+ - **Authentication:** OAuth 2.0 via `CX_CLIENT_ID` and `CX_CLIENT_SECRET`, or API key via `CX_APIKEY`
+ - **Endpoints:** Configured via `CX_BASE_URI` and `CX_BASE_AUTH_URI`
+
+2. **Maven Central Repository:**
+ - **Artifact:** com.checkmarx.ast:ast-cli-java-wrapper
+ - **Distribution:** Published JAR for inclusion in other projects
+
+3. **GitHub:**
+ - **Repository:** CheckmarxDev/ast-cli-java-wrapper
+ - **CI/CD:** Likely uses GitHub Actions for automated builds and tests
+
+---
+
+## Deployment Info
+
+### Publishing to Maven Central
+
+1. **Build Release:**
+ ```bash
+ mvn clean install
+ ```
+
+2. **Create Release Tag:**
+ ```bash
+ git tag -a v1.0.14 -m "Release version 1.0.14"
+ git push origin v1.0.14
+ ```
+
+3. **Deploy to Maven Central (Checkmarx Process):**
+ - Typically handled by CI/CD pipeline or release manager
+ - Requires Sonatype credentials and GPG signing
+ - Uses `mvn deploy` with Maven settings.xml configuration
+
+### Artifact Coordinates
+
+```xml
+
+ com.checkmarx.ast
+ ast-cli-java-wrapper
+ 1.0.14
+
+```
+
+### Versioning
+
+- Current version: Check `pom.xml` for `` property
+- Increment version before release
+- Use semantic versioning (MAJOR.MINOR.PATCH)
+
+---
+
+## Performance Considerations
+
+1. **Serialization:** Jackson is the primary JSON serialization engine and is optimized for performance. Ensure large result sets are streamed rather than loaded entirely in memory.
+
+2. **HTTP Client Configuration:** Consider connection pooling and timeout configurations when making requests to the AST platform.
+
+3. **Memory Usage:** For large scan results (KICS, OSS, containers), implement pagination or streaming to avoid OutOfMemoryError.
+
+4. **Compilation:** Java 8 target ensures compatibility but limits optimization opportunities available in newer Java versions.
+
+5. **Build Optimization:** Use `mvn clean install -T 1C` for parallel build threads to speed up compilation.
+
+---
+
+## API/Endpoints/Interfaces
+
+### Core Interfaces
+
+**CxConfig** - Configuration management
+- `getClientId()` - OAuth client identifier
+- `getClientSecret()` - OAuth client secret
+- `getApiKey()` - API key for authentication
+- `getBaseUri()` - AST platform base URL
+- `getBaseAuthUri()` - Identity/authentication service URL
+- `getTenant()` - Tenant identifier
+
+**CxException** - Custom exception for domain errors
+- Extends RuntimeException
+- Used for all AST-specific error conditions
+
+### Module-Specific Interfaces
+
+- **Scan Module:** Scan creation, retrieval, status management
+- **Results Module:** Result parsing, filtering, and analysis
+- **ASCA Module:** Application source code analysis results
+- **OSS Module:** Open source software vulnerability data
+- **KICS Module:** Infrastructure as code scanning results
+- **Remediation Module:** Remediation guidance and solutions
+- **CodeBashing Module:** Security training integration
+- **Containers Module:** Container image scanning results
+
+---
+
+## Security & Access
+
+### Authentication
+
+1. **OAuth 2.0:**
+ - Client ID: `CX_CLIENT_ID`
+ - Client Secret: `CX_CLIENT_SECRET`
+ - Token endpoint: `CX_BASE_AUTH_URI`
+ - Recommended for service-to-service integration
+
+2. **API Key:**
+ - API Key: `CX_APIKEY`
+ - Recommended for personal use and testing
+ - Less secure than OAuth, use with caution in production
+
+### Authorization
+
+- **Tenant-Based:** Access controlled at tenant level via `CX_TENANT`
+- **Scope-Based:** Different operations may require different permissions in AST platform
+- **Role-Based:** User roles in AST platform determine available operations
+
+### Secrets Management
+
+- **Never commit credentials** to version control
+- Use environment variables for local development
+- Use CI/CD secrets managers for automated deployments
+- Rotate API keys and client secrets regularly
+- Audit access logs for suspicious activity
+
+### Data Protection
+
+- Use HTTPS for all API communication
+- Jackson's default serialization is safe from injection attacks
+- Validate all external input before processing
+- Sanitize output if displaying user data
+- Review JaCoCo excludes to ensure security code is tested
+
+---
+
+## Logging
+
+### Logging Framework
+
+- **Framework:** SLF4J with slf4j-simple binding
+- **Configuration:** Can be customized via `simplelogger.properties` in classpath
+- **Production Use:** Consider upgrading to Logback or Log4j2 for advanced features
+
+### Logger Usage
+
+```java
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class MyClass {
+ private static final Logger log = LoggerFactory.getLogger(MyClass.class);
+
+ public void myMethod() {
+ log.info("Operation started");
+ log.debug("Debug information");
+ log.warn("Warning message");
+ log.error("Error occurred", exception);
+ }
+}
+```
+
+### Log Levels
+
+- **DEBUG:** Detailed information for debugging
+- **INFO:** General informational messages
+- **WARN:** Warning messages for potentially problematic situations
+- **ERROR:** Error messages for failures
+
+### Sensitive Data
+
+- Never log credentials, API keys, or secrets
+- Mask sensitive information in logs (user IDs, tokens, etc.)
+- Use `log.debug()` for development-only logging
+- Review logs regularly for security issues
+
+---
+
+## Debugging Steps
+
+### Local Debugging
+
+1. **Enable Debug Logging:**
+ ```bash
+ mvn test -Dorg.slf4j.simpleLogger.defaultLogLevel=debug
+ ```
+
+2. **IDE Debugging:**
+ - Set breakpoints in IDE
+ - Run tests in debug mode: Right-click test → "Debug"
+ - Use IntelliJ Debugger or Eclipse Debug perspective
+
+3. **Maven Debug Output:**
+ ```bash
+ mvn -X clean install # Very verbose output
+ mvn -e test # Print stack traces
+ ```
+
+### Common Issues
+
+| Issue | Cause | Solution |
+|-------|-------|----------|
+| Test failures | Missing environment variables | Set CX_* environment variables for integration tests |
+| Build failures | Java version mismatch | Ensure JDK 8+ is installed and JAVA_HOME is set |
+| Dependency conflicts | Transitive dependency issues | Check pom.xml for exclusions or use `mvn dependency:tree` |
+| OOM errors | Large scan results | Increase heap size: `export MAVEN_OPTS="-Xmx2g"` |
+| Slow builds | Parallel testing disabled | Use `mvn clean install -T 1C` for parallel builds |
+
+### Useful Maven Commands
+
+```bash
+mvn dependency:tree # Show dependency hierarchy
+mvn help:describe-mojo -Dplugin=org.apache.maven.plugins:maven-compiler-plugin # Plugin help
+mvn clean install -o # Offline build (use cached dependencies)
+mvn test -Dtest=ScanResultTest # Run specific test
+mvn test -Dtest=*Integration # Run tests matching pattern
+```
+
+### Profiling & Analysis
+
+```bash
+# Generate detailed build report
+mvn clean install -Dmaven.compiler.verbose=true
+
+# Check for deprecated API usage
+mvn compile -Werror:sunapi
+
+# Analyze code with SpotBugs (if configured)
+mvn spotbugs:check
+```
+
+---
+
+## Contributing
+
+- Follow coding standards outlined above
+- Write unit tests for new functionality
+- Ensure all tests pass: `mvn clean install`
+- Update documentation for API changes
+- Create pull request with clear description
+- Respond to code review feedback
+- Maintain backward compatibility where possible
+
+---
+
+## Support & Contact
+
+**Team:** Checkmarx - AST Integrations Team
+**Project Link:** https://github.com/CheckmarxDev/ast-cli-java-wrapper
+**Issues:** GitHub Issues for bug reports and feature requests
+
+---
+
+**Last Updated:** April 20, 2026
+**Status:** In Active Development
diff --git a/checkmarx-ast-cli.version b/checkmarx-ast-cli.version
index fae17394..c5324251 100644
--- a/checkmarx-ast-cli.version
+++ b/checkmarx-ast-cli.version
@@ -1 +1 @@
-2.3.54
+2.3.57
diff --git a/pom.xml b/pom.xml
index a468a86c..fdfeca80 100644
--- a/pom.xml
+++ b/pom.xml
@@ -40,7 +40,7 @@
com.fasterxml.jackson.core
jackson-databind
- 2.21.1
+ 2.22.0
org.projectlombok
@@ -211,14 +211,32 @@
+
+
+ echo-repo
+ https://maven.echohq.com
+
+
- central
- https://central.sonatype.com/api/v1/publish
+ echo-repo
+ https://maven.echohq.com
+
+
+ echo-repo
+ https://maven.echohq.com
+
+ true
+
+
+ false
+
+
+
diff --git a/src/main/resources/cx-linux b/src/main/resources/cx-linux
index 85f008ed..9b4adbb5 100755
--- a/src/main/resources/cx-linux
+++ b/src/main/resources/cx-linux
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:776d9864c0104e1d0023641ef931bd1c58478cf56768ce77f2bfbfd6e9e64493
-size 80568482
+oid sha256:2adc258dd3754f62456970a2c3b3e6f9127dbeede3df373079b2a24ca3e5f28c
+size 83243170
diff --git a/src/main/resources/cx-linux-arm b/src/main/resources/cx-linux-arm
index 10629171..8867d68e 100755
--- a/src/main/resources/cx-linux-arm
+++ b/src/main/resources/cx-linux-arm
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:d40b3cfb9f930e96a9d6b494d4c7b9cd98e3bb857e55a0f55c92d764bb8c3c1a
-size 75235490
+oid sha256:3bbf6915f6c7740ad41422859ec8f984402884abffe3777727b1c047b490099d
+size 77660322
diff --git a/src/main/resources/cx-mac b/src/main/resources/cx-mac
index e137bc67..ac4fb358 100755
--- a/src/main/resources/cx-mac
+++ b/src/main/resources/cx-mac
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:df4a2d6b72936afa65df8730f0ee491f6d518286421063f50df2e48d3d5b56f9
-size 160422432
+oid sha256:8b0e2df928eb29718936480d2492431e051d7058b60754c3514c87da864e2267
+size 165800304
diff --git a/src/main/resources/cx.exe b/src/main/resources/cx.exe
index f2f6b695..c18ff7fe 100644
--- a/src/main/resources/cx.exe
+++ b/src/main/resources/cx.exe
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c7227ac9dd89f344c12629d367774a2428595b3daff0a2e710981d924f13dbf4
-size 82488128
+oid sha256:08691c1a33980ae863dd8990bdafca9e64622d450727251355118b851306bfae
+size 85228864
diff --git a/src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java b/src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java
index 6911e4af..d21246c3 100644
--- a/src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java
+++ b/src/test/java/com/checkmarx/ast/ContainersRealtimeResultsTest.java
@@ -8,8 +8,6 @@
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.Optional;
-
import static org.junit.jupiter.api.Assertions.*;
/**
@@ -19,10 +17,6 @@
*/
class ContainersRealtimeResultsTest extends BaseTest {
- private boolean isCliConfigured() {
- return Optional.ofNullable(getConfig().getPathToExecutable()).filter(s -> !s.isEmpty()).isPresent();
- }
-
/* ------------------------------------------------------ */
/* Integration tests for Container Realtime scanning */
/* ------------------------------------------------------ */
@@ -35,7 +29,6 @@ private boolean isCliConfigured() {
@Test
@DisplayName("Basic container scan on Dockerfile returns detected images")
void basicContainerRealtimeScan() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String dockerfilePath = "src/test/resources/Dockerfile";
Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)), "Dockerfile not found - cannot test container scanning");
@@ -61,7 +54,6 @@ void basicContainerRealtimeScan() throws Exception {
@Test
@DisplayName("Container scan with ignore file works correctly")
void containerRealtimeScanWithIgnoreFile() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String dockerfilePath = "src/test/resources/Dockerfile";
String ignoreFile = "src/test/resources/ignored-packages.json";
Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)) && Files.exists(Paths.get(ignoreFile)),
@@ -88,7 +80,6 @@ void containerRealtimeScanWithIgnoreFile() throws Exception {
@Test
@DisplayName("Repeated container scans produce consistent results")
void containerRealtimeScanConsistency() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String dockerfilePath = "src/test/resources/Dockerfile";
Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)), "Dockerfile not found - cannot test consistency");
@@ -114,7 +105,6 @@ void containerRealtimeScanConsistency() throws Exception {
@Test
@DisplayName("Container domain objects are properly mapped from scan results")
void containerDomainObjectMapping() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String dockerfilePath = "src/test/resources/Dockerfile";
Assumptions.assumeTrue(Files.exists(Paths.get(dockerfilePath)), "Dockerfile not found - cannot test mapping");
@@ -147,7 +137,6 @@ void containerDomainObjectMapping() throws Exception {
@Test
@DisplayName("Container scan throws appropriate exception for non-existent file")
void containerScanHandlesInvalidPath() {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
// Test with a non-existent file path
String invalidPath = "src/test/resources/NonExistentDockerfile";
diff --git a/src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java b/src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java
index 6ea0fea0..d09769ba 100644
--- a/src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java
+++ b/src/test/java/com/checkmarx/ast/OssRealtimeParsingTest.java
@@ -6,8 +6,6 @@
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.Optional;
-
import static org.junit.jupiter.api.Assertions.*;
/**
@@ -17,10 +15,6 @@
*/
class OssRealtimeParsingTest extends BaseTest {
- private boolean isCliConfigured() {
- return Optional.ofNullable(getConfig().getPathToExecutable()).filter(s -> !s.isEmpty()).isPresent();
- }
-
/**
* Tests basic OSS realtime scan functionality on pom.xml.
* Verifies that the scan returns a valid results object with detected Maven dependencies.
@@ -28,7 +22,6 @@ private boolean isCliConfigured() {
@Test
@DisplayName("Basic OSS scan on pom.xml returns Maven dependencies")
void basicOssRealtimeScan() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
OssRealtimeResults results = wrapper.ossRealtimeScan("pom.xml", "");
@@ -49,7 +42,6 @@ void basicOssRealtimeScan() throws Exception {
@Test
@DisplayName("OSS scan with ignore file filters packages correctly")
void ossRealtimeScanWithIgnoreFile() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String ignoreFile = "src/test/resources/ignored-packages.json";
Assumptions.assumeTrue(Files.exists(Paths.get(ignoreFile)), "Ignore file not found - cannot test ignore functionality");
@@ -69,7 +61,6 @@ void ossRealtimeScanWithIgnoreFile() throws Exception {
@Test
@DisplayName("Display detected package names for diagnostic purposes")
void diagnosticPackageNames() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
OssRealtimeResults results = wrapper.ossRealtimeScan("pom.xml", "");
assertFalse(results.getPackages().isEmpty(), "Should have packages for diagnostic");
@@ -91,7 +82,6 @@ void diagnosticPackageNames() throws Exception {
@Test
@DisplayName("Ignore file excludes detected packages correctly")
void ignoreFileExcludesPackages() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String ignoreFile = "src/test/resources/ignored-packages.json";
Assumptions.assumeTrue(Files.exists(Paths.get(ignoreFile)), "Ignore file not found - cannot test ignore functionality");
@@ -125,7 +115,6 @@ void ignoreFileExcludesPackages() throws Exception {
@Test
@DisplayName("Repeated OSS scans produce consistent results")
void ossRealtimeScanConsistency() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
OssRealtimeResults firstScan = wrapper.ossRealtimeScan("pom.xml", "");
OssRealtimeResults secondScan = wrapper.ossRealtimeScan("pom.xml", "");
@@ -141,7 +130,6 @@ void ossRealtimeScanConsistency() throws Exception {
@Test
@DisplayName("Package domain objects are properly mapped from scan results")
void packageDomainObjectMapping() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
OssRealtimeResults results = wrapper.ossRealtimeScan("pom.xml", "");
assertFalse(results.getPackages().isEmpty(), "Should have packages to validate mapping");
diff --git a/src/test/java/com/checkmarx/ast/ScanTest.java b/src/test/java/com/checkmarx/ast/ScanTest.java
index a414281e..f37e5bdf 100644
--- a/src/test/java/com/checkmarx/ast/ScanTest.java
+++ b/src/test/java/com/checkmarx/ast/ScanTest.java
@@ -5,7 +5,6 @@
import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults;
import com.checkmarx.ast.ossrealtime.OssRealtimeResults;
import com.checkmarx.ast.scan.Scan;
-import org.junit.jupiter.api.Assumptions;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -109,8 +108,6 @@ void testKicsRealtimeScan() throws Exception {
@Test
void testOssRealtimeScanWithIgnoredFile() throws Exception {
- Assumptions.assumeTrue(getConfig().getPathToExecutable() != null && !getConfig().getPathToExecutable().isEmpty(), "PATH_TO_EXECUTABLE not set");
-
String source = "pom.xml";
String ignoreFile = "src/test/resources/ignored-packages.json";
diff --git a/src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java b/src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java
index a662d0f1..e2b0ebeb 100644
--- a/src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java
+++ b/src/test/java/com/checkmarx/ast/SecretsRealtimeResultsTest.java
@@ -7,8 +7,6 @@
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.Optional;
-
import static org.junit.jupiter.api.Assertions.*;
/**
@@ -18,10 +16,6 @@
*/
class SecretsRealtimeResultsTest extends BaseTest {
- private boolean isCliConfigured() {
- return Optional.ofNullable(getConfig().getPathToExecutable()).filter(s -> !s.isEmpty()).isPresent();
- }
-
/* ------------------------------------------------------ */
/* Integration tests for Secrets Realtime scanning */
/* ------------------------------------------------------ */
@@ -34,7 +28,6 @@ private boolean isCliConfigured() {
@Test
@DisplayName("Basic secrets scan on python file returns detected secrets")
void basicSecretsRealtimeScan() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String pythonFile = "src/test/resources/python-vul-file.py";
Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)), "Python vulnerable file not found - cannot test secrets scanning");
@@ -61,7 +54,6 @@ void basicSecretsRealtimeScan() throws Exception {
@Test
@DisplayName("Secrets scan with ignore file works correctly")
void secretsRealtimeScanWithIgnoreFile() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String pythonFile = "src/test/resources/python-vul-file.py";
String ignoreFile = "src/test/resources/ignored-packages.json";
Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)) && Files.exists(Paths.get(ignoreFile)),
@@ -86,7 +78,6 @@ void secretsRealtimeScanWithIgnoreFile() throws Exception {
@Test
@DisplayName("Repeated secrets scans produce consistent results")
void secretsRealtimeScanConsistency() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String pythonFile = "src/test/resources/python-vul-file.py";
Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)), "Python file not found - cannot test consistency");
@@ -109,7 +100,6 @@ void secretsRealtimeScanConsistency() throws Exception {
@Test
@DisplayName("Secret domain objects are properly mapped from scan results")
void secretDomainObjectMapping() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String pythonFile = "src/test/resources/python-vul-file.py";
Assumptions.assumeTrue(Files.exists(Paths.get(pythonFile)), "Python file not found - cannot test mapping");
@@ -141,7 +131,6 @@ void secretDomainObjectMapping() throws Exception {
@Test
@DisplayName("Secrets scan on clean file returns empty results")
void secretsScanOnCleanFile() throws Exception {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String cleanFile = "src/test/resources/csharp-no-vul.cs";
Assumptions.assumeTrue(Files.exists(Paths.get(cleanFile)), "Clean C# file not found - cannot test clean scan");
@@ -161,7 +150,6 @@ void secretsScanOnCleanFile() throws Exception {
@Test
@DisplayName("Secrets scan throws appropriate exception for non-existent file")
void secretsScanHandlesInvalidPath() {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
// Test with a non-existent file path
String invalidPath = "src/test/resources/NonExistentFile.py";
@@ -186,7 +174,6 @@ void secretsScanHandlesInvalidPath() {
@Test
@DisplayName("Secrets scan handles multiple file types correctly")
void secretsScanMultipleFileTypes() {
- Assumptions.assumeTrue(isCliConfigured(), "PATH_TO_EXECUTABLE not configured - skipping integration test");
String[] testFiles = {
"src/test/resources/python-vul-file.py",