CI/CD Integration
Relevant source files
The following files were used as context for generating this wiki page:
- README.md
- README-ptBR.md
- api/config.yaml
- api/securitytest/securitytest.go
- cli/analysis/analysis.go
- cli/types/types.go
- client/analysis/output.go
- client/cmd/main.go
- client/integration/sonarqube/sonarqube_test.go
- client/integration/sonarqube/testdata/analysis/vulnerable_go_project.json
- client/integration/sonarqube/testdata/analysis/vulnerable_js_project.json
- client/integration/sonarqube/testdata/analysis/vulnerable_python_project.json
- deployments/docker-compose.yml
Introduction
huskyCI is an open-source tool designed to orchestrate various static application security testing (SAST) tools and centralize their results. Its primary purpose is to be integrated into CI/CD pipelines, acting as a security gate. By adding a huskyCI stage to a pipeline, developers can automatically scan their code for vulnerabilities before deployment.
The system is capable of performing security analysis for multiple languages, including Python, Ruby, JavaScript, Go, Java, and HCL, as well as auditing repositories for leaked secrets. All findings are stored in a central database for metrics and further analysis. huskyCI is also compatible with DefectDojo for vulnerability management.
Sources: README.md:11-15, README.md:3-5
How It Works
Developers can configure a new stage in their CI pipeline to execute huskyCI. When this stage runs, huskyCI orchestrates multiple security tools against the target repository. If any security issues are discovered, huskyCI provides detailed feedback directly in the CI job's log output.
The output includes the vulnerability title, severity, confidence level, the affected file and line number, and the problematic code snippet. Based on the severity of the findings, huskyCI can fail the build, preventing vulnerable code from proceeding further in the pipeline.
Sources: README.md:17-21
An example of the console output is shown below:
[HUSKYCI][*] poc-python-bandit -> https://github.com/globocom/huskyCI.git
[HUSKYCI][*] huskyCI analysis started! yDS9tb9mdt4QnnyvOBp3eVAXE1nWpTRQ
[HUSKYCI][!] Title: Use of exec detected.
[HUSKYCI][!] Language: Python
[HUSKYCI][!] Tool: Bandit
[HUSKYCI][!] Severity: MEDIUM
[HUSKYCI][!] Confidence: HIGH
[HUSKYCI][!] Details: Use of exec detected.
[HUSKYCI][!] File: ./main.py
[HUSKYCI][!] Line: 7
[HUSKYCI][!] Code:
6
7 exec(command)
8
[HUSKYCI][SUMMARY] Python -> huskyci/bandit:1.6.2
[HUSKYCI][SUMMARY] High: 0
[HUSKYCI][SUMMARY] Medium: 1
[HUSKYCI][SUMMARY] Low: 1
[HUSKYCI][SUMMARY] NoSecHusky: 1
[HUSKYCI][*] Some HIGH/MEDIUM issues were found in these securityTests:
[HUSKYCI][*] [huskyci/bandit:1.6.2]
ERROR: Job failed: exit code 190
Sources: README.md:23-58
Client Execution Flow
The CI/CD integration is driven by the huskyci-client, which is executed as a step in the pipeline. The client coordinates with the huskyCI API to perform the security analysis.
The following diagram illustrates the sequence of interactions between the CI pipeline, the huskyci-client, and the huskyCI API.
This diagram shows the interaction flow starting from the CI pipeline executing the huskyCI client.
Sources: client/cmd/main.go
The client-side logic follows these steps:
- Configuration Check: It first checks for necessary environment variables (
HUSKYCI_*) and sets up its configuration. - Start Analysis: It sends a request to the huskyCI API to initiate a new analysis for the specified repository and branch, receiving a unique Request ID (RID).
- Monitor Analysis: The client polls the API using the RID, waiting for the analysis status to become
finished. - Process Results: Once the analysis is complete, the client retrieves the full result set. It categorizes the security tests that ran into
passed,failed, orerrorlists. - Print Output: The results are printed to the standard output. This can be in a human-readable format or as a single JSON object if the
JSONargument is provided. - SonarQube Integration: It generates a
sonarqube.jsonfile in the./huskyCI/directory, which can be used by the SonarQube scanner. - Set Exit Code: Finally, it exits with a specific code to signal the CI system whether the build should pass or fail.
Sources: client/cmd/main.go:28-139, client/integration/sonarqube/sonarqube_test.go:29-32
Analysis Data Structures
The data related to a huskyCI analysis is organized into several Go structs. These structures define how information is stored in the database and returned by the API.
Sources: cli/types/types.go
Core Structures
The diagram below shows the relationship between the main data structures.
This class diagram outlines the key data structures used in a huskyCI analysis.
Sources: cli/types/types.go
Analysis
This is the top-level struct representing a single analysis run.
| Field | Type | Description |
|---|---|---|
RID | string | The unique Request ID for the analysis. |
URL | string | The URL of the repository being analyzed. |
Branch | string | The branch of the repository being analyzed. |
Status | string | The current status of the analysis (e.g., running, finished). |
Result | string | The final result of the analysis (e.g., passed, failed). |
Containers | []Container | A list of containers that executed the security tests. |
HuskyCIResults | HuskyCIResults | The aggregated vulnerability results from all tests. |
Sources: cli/types/types.go:34-45
Container
This struct holds information about a single security test execution within a Docker or Kubernetes container.
| Field | Type | Description |
|---|---|---|
CID | string | The ID of the container or pod that ran the test. |
SecurityTest | SecurityTest | The metadata of the security tool that was executed. |
CStatus | string | The status of the container run (e.g., finished, error running). |
COutput | string | The raw output (stdout/stderr) from the container. |
CResult | string | The interpreted result of the test (e.g., passed, failed). |
CInfo | string | A human-readable summary of the container run's outcome. |
Sources: cli/types/types.go:56-65
HuskyCIVulnerability
This struct represents a single vulnerability found by a security tool.
| Field | Type | Description |
|---|---|---|
Language | string | The programming language of the vulnerable code. |
SecurityTool | string | The name of the tool that found the vulnerability. |
Severity | string | The severity level (e.g., LOW, MEDIUM, HIGH). |
File | string | The path to the file containing the vulnerability. |
Line | string | The line number of the vulnerability. |
Code | string | The snippet of code that is vulnerable. |
Details | string | A detailed description of the vulnerability. |
Sources: cli/types/types.go:80-92
Supported Security Tools
huskyCI orchestrates a variety of security tools, each packaged as a Docker container. The configuration for each tool, including its Docker image, command, and language, is defined in api/config.yaml.
| Tool | Language/Type | Docker Image |
|---|---|---|
gosec | Go | huskyci/gosec:v2.3.0 |
bandit | Python | huskyci/bandit:1.6.2 |
safety | Python | huskyci/safety:1.9.0 |
brakeman | Ruby | huskyci/brakeman:4.8.2 |
npmaudit | JavaScript | huskyci/npmaudit:9.6.6 |
yarnaudit | JavaScript | huskyci/yarnaudit:1.22.19 |
spotbugs | Java | huskyci/spotbugs:4.0.0-beta4 |
gitleaks | Generic | huskyci/gitleaks:v.7.6.1 |
tfsec | HCL | huskyci/tfsec:0.58.15 |
securitycodescan | C# | huskyci/securitycodescan:v5.6.2 |
enry | Enry | huskyci/enry:v1.2.0 |
gitauthors | Generic | huskyci/gitauthors:2.18.4 |
Sources: api/config.yaml, cli/analysis/analysis.go:139-163
Below is an example of how the gosec tool is configured:
gosec:
name: gosec
image: huskyci/gosec
imageTag: v2.3.0
cmd: |+
mkdir -p ~/.ssh &&
echo '%GIT_PRIVATE_SSH_KEY%' > ~/.ssh/id_rsa &&
chmod 600 ~/.ssh/id_rsa &&
# ... more commands
cd code
touch results.json
$(which gosec) -quiet -fmt=json -nosec-tag nohusky -log=log.txt -out=results.json ./... 2> /dev/null
jq -j -M -c . results.json
type: Language
language: Go
default: true
timeOutInSeconds: 360
Sources: api/config.yaml:47-75
Result Processing and CI Feedback
After the analysis is complete, the huskyci-client processes the results to provide clear feedback and determine the CI job's outcome.
Result Summary
The client aggregates vulnerabilities from all tools and categorizes them by severity (High, Medium, Low, NoSec). It then prints a summary for each tool that found issues, followed by a total summary.
Sources: client/analysis/output.go:315-442
Exit Code Logic
The client uses a specific exit code to communicate the result to the CI system, which determines whether the pipeline should proceed or fail.
This flowchart shows the logic used by the huskyCI client to determine the final exit code.
Sources: client/cmd/main.go:107-139
- Exit Code 0 (Success): Returned if no vulnerabilities are found, or if only
LOWorINFOseverity issues are found. The build is allowed to pass. - Exit Code 1 (Error): Returned if there is an internal error in the client, such as a problem communicating with the API.
- Exit Code 190 (Failure): Returned if any
HIGHorMEDIUMseverity vulnerabilities are found. This signals the CI system to fail the build.
Sources: client/cmd/main.go:107-139
External System Integrations
SonarQube
huskyCI provides native support for SonarQube integration. After an analysis, the client automatically generates a sonarqube.json report. This file follows the SonarQube Generic Issue Data format and can be consumed by the SonarQube scanner to import huskyCI's findings into the SonarQube dashboard.
The severity mapping is as follows:
HIGH->BLOCKERMEDIUM->MAJORLOW->MINOR
Sources: client/cmd/main.go:99-104, client/integration/sonarqube/sonarqube_test.go, client/integration/sonarqube/testdata/sonarqube/vulnerable_js_output.json
DefectDojo
huskyCI is also compatible with DefectDojo. The JSON output from huskyCI can be imported into DefectDojo for centralized vulnerability management and tracking.
Sources: README.md:7
Conclusion
The CI/CD integration is a core feature of huskyCI, transforming it from a simple scanner into a powerful security gatekeeper within the software development lifecycle. By running as a stage in a pipeline, it provides developers with immediate, actionable feedback on security issues. The client's clear exit code logic enforces security policies automatically, preventing the deployment of code with high-risk vulnerabilities and helping to maintain a higher security posture for applications.