huskyCI is an open-source tool that orchestrates security tests inside Kubernetes and centralizes results for analysis and metrics.
It performs static security analysis across multiple languages and frameworks:
| Language | Tools |
|---|---|
| Python | Bandit, Safety |
| Ruby | Brakeman |
| JavaScript | Npm Audit, Yarn Audit |
| Go | Gosec |
| Java | SpotBugs + Find Sec Bugs |
| HCL | TFSec |
| Secrets | GitLeaks |
Forked from globocom/huskyCI and maintained by @githubanotaai.
GitHub Actions workflow triggers
|
v
huskyci-client (runs inside code-analysis runner pod)
|
v
huskyci-api (Kubernetes deployment, creates scanner pods)
|
v
Scanner pods (enry, bandit, gosec, gitleaks, npmaudit, etc.)
|
v
Results collected, returned to client, reported to SonarQube
The project has three components, all in this repo:
| Component | Path | Description |
|---|---|---|
| API | api/ |
REST API that receives analysis requests, creates scanner pods in Kubernetes, collects results |
| Client | client/ |
CLI binary that runs inside the GitHub Actions runner, calls the API, prints results |
| CLI | cli/ |
Interactive CLI for managing targets and tokens (optional) |
# API
cd api && go build -o huskyci-api server.go
# Client
cd client/cmd && go build -o huskyci-client main.go
# CLI
cd cli && go build -o huskyci-cli main.go# API image
docker build --platform linux/amd64 \
-f deployments/dockerfiles/api.Dockerfile .
# Client image
docker build --platform linux/amd64 \
-f deployments/dockerfiles/client.Dockerfile .CI contract checks (Gitleaks & deploy scripts). The CI workflow includes jobs that: build the Gitleaks image from deployments/dockerfiles/gitleaks/Dockerfile and assert the gitleaks binary is v8; run gitleaks dir on a fixture with one expected finding (api/securitytest/testdata/gitleaks_e2e_fixture); and run deployments/scripts/verify-depl-scripts.sh (bash -n on registry/push entrypoints). That complements unit tests in api/securitytest and api/context and does not push to any registry from CI.
Manual Gitleaks image e2e (optional). The API’s HUSKYCI_GITLEAKS_IMAGE and HUSKYCI_GITLEAKS_IMAGE_TAG overrides are covered by unit tests (api/context); to validate end-to-end with a real cluster, run the API (e.g. docker-compose or your environment), set those variables to a registry and tag you control, and run a security test that uses Gitleaks, then confirm scanner pods use the expected image in Kubernetes or Docker.
Registry hosts and account IDs are not hardcoded in scripts. Set environment variables when pushing.
Gitleaks image — deployments/scripts/push-huskyci-gitleaks.sh builds from deployments/dockerfiles/gitleaks/Dockerfile and pushes by version plus latest.
| Variable | Description |
|---|---|
HUSKYCI_PUSH_TARGET |
docker (default) or ecr |
ECR_REGISTRY |
Required for ECR, e.g. 123456789012.dkr.ecr.us-east-1.amazonaws.com |
AWS_REGION |
Required for ECR (e.g. us-east-1) |
GITLEAKS_ECR_REPOSITORY |
ECR repository name (default: huskyci-gitleaks) |
DOCKERHUB_ORG |
Docker Hub org for docker target (default: huskyci) |
DOCKERHUB_USER / DOCKERHUB_PASSWORD |
Optional; otherwise use an existing docker login on the host |
Client image to ECR — deployments/scripts/push-huskyci-client-ecr.sh requires ECR_REGISTRY (and uses AWS_REGION, optional IMAGE_NAME / IMAGE_TAG).
| Variable | Description |
|---|---|
HUSKYCI_DATABASE_DB_ADDR |
Database address |
HUSKYCI_DATABASE_DB_NAME |
Database name |
HUSKYCI_DATABASE_DB_USERNAME |
Database username |
HUSKYCI_DATABASE_DB_PASSWORD |
Database password |
HUSKYCI_API_DEFAULT_USERNAME |
Default API user |
HUSKYCI_API_DEFAULT_PASSWORD |
Default API password |
HUSKYCI_API_ALLOW_ORIGIN_CORS |
CORS origin |
HUSKYCI_INFRASTRUCTURE_USE |
kubernetes or docker |
HUSKYCI_KUBERNETES_NAMESPACE |
Namespace for scanner pods |
HUSKYCI_KUBERNETES_NODE_SELECTOR |
Node selector for scanner pods (e.g. karpenter.sh/nodepool=actions-runner) |
HUSKYCI_KUBERNETES_TOLERATIONS |
Tolerations for scanner pods (e.g. actions-runner=true:NoSchedule) |
HUSKYCI_KUBERNETES_POD_SCHEDULING_TIMEOUT |
Timeout in seconds for pod scheduling (default: 60) |
HUSKYCI_GITLEAKS_IMAGE |
If set, overrides the Gitleaks container image from config.yaml (e.g. ECR URL) |
HUSKYCI_GITLEAKS_IMAGE_TAG |
If set, overrides the Gitleaks image tag from config.yaml |
| Variable | Description |
|---|---|
HUSKYCI_CLIENT_API_ADDR |
huskyCI API URL |
HUSKYCI_CLIENT_REPO_URL |
Repository URL to analyze |
HUSKYCI_CLIENT_REPO_BRANCH |
Branch to analyze |
HUSKYCI_CLIENT_TOKEN |
API authentication token |
When vulnerabilities are found, the client prints a summary first, followed by collapsible detail groups (in GitHub Actions):
[HUSKYCI][SUMMARY] Total
[HUSKYCI][SUMMARY] High: 4
[HUSKYCI][SUMMARY] Medium: 2
[HUSKYCI][SUMMARY] Low: 3
::group::JavaScript - NpmAudit Details (6 findings)
[HUSKYCI][!] Title: Vulnerable Dependency: express <=4.21.2
[HUSKYCI][!] Severity: high
...
::endgroup::
[HUSKYCI][!] Analysis completed. Blocking vulnerabilities (HIGH/MEDIUM) were found.
[HUSKYCI][!] This is NOT an infrastructure error -- the security scan ran successfully.
[HUSKYCI][!] Fix the vulnerabilities listed above before merging.
Exit code 190 means the scan succeeded but HIGH/MEDIUM vulnerabilities were found. This is not an infrastructure error.
CI runs on every push/PR to main using GitHub-hosted runners:
- Build & Test: matrix across
api/,client/,cli/(Go 1.23,go vet,go test -race) - Lint: golangci-lint v2.11.4
- Docker Build: validates both Dockerfiles build (no push)
No secrets required. Runs on any fork.
Read CONTRIBUTING.md for the development process and PR guidelines.
huskyCI is licensed under the BSD 3-Clause License.
