CLI Tool
Relevant source files
The following files were used as context for generating this wiki page:
The huskyCI CLI tool is the client-side application responsible for initiating security analyses from a CI/CD pipeline. It communicates with the huskyCI API to start a scan, monitor its progress, and retrieve the results. Based on the findings, it will output a detailed report and return a specific exit code to either pass or fail the CI build, thus integrating security scanning directly into the development workflow.
The tool supports multiple output formats, including a human-readable STDOUT format and a machine-readable JSON format. It also features an integration with SonarQube by generating a compatible report file.
Sources: README.md, client/cmd/main.go:17-23, client/cmd/main.go:70-76
Execution Flow
The CLI tool follows a clear, step-by-step process to perform a security analysis. The flow is designed to be executed within a CI job.
The diagram below illustrates the main execution path of the huskyCI client.
Sources: client/cmd/main.go:25-131
1. Configuration
The first step is to check for the required environment variables. If any are missing, the application will exit with an error. It also checks for a JSON argument to determine the output format.
Sources: client/cmd/main.go:28-34
2. Analysis Initiation
The client sends a request to the huskyCI API to start a new analysis. The API returns a unique RID (Request ID) for the analysis, which is used for subsequent status checks.
Sources: client/cmd/main.go:41-48
3. Monitoring
The client enters a monitoring loop, periodically querying the huskyCI API with the RID to check the status of the analysis. This continues until the analysis is finished.
Sources: client/cmd/main.go:51-57
4. Results Processing and Output
Once the analysis is complete, the client processes the results. It categorizes security tests into passed, failed, or error lists. The results are then printed to the console in either STDOUT or JSON format.
Sources: client/cmd/main.go:64-76, client/analysis/output.go:20-91
5. SonarQube Integration
After printing the results, the tool generates a sonarqube.json file in a ./huskyCI/ directory. This file contains the vulnerability data formatted for ingestion by SonarQube.
Sources: client/cmd/main.go:79-85, client/integration/sonarqube/sonarqube.go:21-27
6. Exit Code Determination
Finally, the client determines the exit code based on the severity of the vulnerabilities found:
- Exit 0: No vulnerabilities were found, or only
LOW/INFOseverity issues were detected. The build can proceed. - Exit 190:
HIGHorMEDIUMseverity vulnerabilities were found. The build is failed.
Sources: client/cmd/main.go:88-131
Client-API Interaction
The following sequence diagram shows the communication between the CLI client and the huskyCI API.
Sources: client/cmd/main.go:41-57
Output Formatting
The CLI provides two main output formats, controlled by passing JSON as a command-line argument.
Sources: client/cmd/main.go:25-27
Standard Output (STDOUT)
This is the default, human-readable format. It provides a detailed view of each vulnerability and concludes with a summary for each security tool and a total summary.
An example of a vulnerability found by gosec:
[HUSKYCI][!] Title: Errors unhandled.
[HUSKYCI][!] Language: Go
[HUSKYCI][!] Tool: GoSec
[HUSKYCI][!] Severity: LOW
[HUSKYCI][!] Confidence: HIGH
[HUSKYCI][!] Details: Errors unhandled.
[HUSKYCI][!] File: /go/src/code/api/util/util.go
[HUSKYCI][!] Line: 24
[HUSKYCI][!] Code: io.WriteString(h, s)
Sources: client/analysis/output.go:501-512, client/integration/sonarqube/testdata/analysis/vulnerable_go_project.json
A summary for a tool looks like this:
[HUSKYCI][SUMMARY] Go -> huskyci/gosec:v2.3.0
[HUSKYCI][SUMMARY] High: 0
[HUSKYCI][SUMMARY] Medium: 2
[HUSKYCI][SUMMARY] Low: 1
[HUSKYCI][SUMMARY] NoSecHusky: 0
Sources: client/analysis/output.go:336-343
JSON Output
When the JSON argument is provided, the output is a single JSON object containing all vulnerabilities grouped by language and tool, along with a summary. This format is suitable for programmatic processing.
Sources: client/analysis/output.go:14-20
Supported Security Tools
The CLI identifies languages in the target project and runs the corresponding security tools available in the huskyCI backend.
| Language | Security Tool(s) | Docker Image |
|---|---|---|
| Go | Gosec | huskyci/gosec |
| Python | Bandit, Safety | huskyci/bandit, huskyci/safety |
| Ruby | Brakeman | huskyci/brakeman |
| JavaScript | NPM Audit, Yarn Audit | huskyci/npmaudit, huskyci/yarnaudit |
| Java | SpotBugs | huskyci/spotbugs |
| HCL | TFSec | huskyci/tfsec |
| C# | SecurityCodeScan | huskyci/securitycodescan |
| Generic | GitLeaks | huskyci/gitleaks |
Sources: cli/analysis/analysis.go:151-177, api/config.yaml
SonarQube Integration
The CLI can generate a report file compatible with SonarQube's "Generic Issue Import Format".
Report Generation
The GenerateOutputFile function is responsible for creating the SonarQube report. It aggregates all vulnerabilities from the different security tools into a single structure.
Sources: client/integration/sonarqube/sonarqube.go:21-27
Data Mapping
Vulnerabilities are mapped to SonarQube issues with the following logic:
engineId: Hardcoded tohuskyCI.ruleId: Combination of the vulnerability's language and security tool (e.g.,Go - Gosec).type: Hardcoded toVULNERABILITY.severity: Mapped from huskyCI severity levels:high->BLOCKERmedium->MAJORlow->MINORdefault->INFO
primaryLocation: Contains the file path, line number, and vulnerability details. If a vulnerability is not associated with a specific file (e.g., a dependency issue), a placeholder file is referenced.
Sources: client/integration/sonarqube/sonarqube.go:90-123
An example of a generated SonarQube issue:
{
"engineId": "huskyCI",
"ruleId": "JavaScript - NpmAudit",
"primaryLocation": {
"message": "Affected versions of `negotiator` are vulnerable to regular expression denial of service...",
"filePath": "huskyCITest/huskyCI_Placeholder_File",
"textRange": {
"startLine": 1
}
},
"type": "VULNERABILITY",
"severity": "BLOCKER"
}
Sources: client/integration/sonarqube/testdata/sonarqube/vulnerable_js_output.json
Input Validation
To prevent command injection and other malicious inputs, the backend API validates the repository URL and branch name sent by the client.
- Repository URL: A regular expression (
((git|ssh|http(s)?)|((git@|gitlab@)[\w\.]+))(:(//)?)([\w\.@\:/\-~]+)(\.git)(/)?) is used to ensure the URL matches a valid Git repository format. - Repository Branch: A regular expression (
^[a-zA-Z0-9_\/.\-\+À-ÿ]*$) ensures the branch name contains only allowed characters.
If validation fails, the API returns a 400 Bad Request status, and the client will fail.
Sources: api/util/util.go:142-180