A TypeScript-based CLI tool for scanning Docker, Kubernetes, and Nginx configuration files for security issues.
- π Automatic Detection: Discovers and classifies Docker, Kubernetes, and Nginx config files
- π‘οΈ 25+ Security Rules: Comprehensive rule set covering common misconfigurations
- π Risk Scoring: Weighted severity-based scoring (LOW: 0.5, MEDIUM: 1, HIGH: 3, CRITICAL: 5)
- π Multiple Output Formats: Console, JSON, and Markdown reports
- π CI/CD Ready: GitHub Actions integration with automated blocking on HIGH/CRITICAL findings
cd server
npm install
npm run build# Scan current directory (console output)
npm start .
# Scan specific directory
npm start ./examples
# Scan with JSON output
npm start ./examples --format=json --out=./reports
# Generate all formats (console + JSON + Markdown)
npm start ./examples --format=all --out=./reports
# Scan entire repository with all formats from root repo
node dist/server.js .. --format=all --out=./reports config-scan [path] [options]
Arguments:
path Root path to scan (default: ".")
Options:
--format <format> Output format: console | json | md | all (default: "console")
--out <dir> Output directory for reports (default: "./reports")
--llm Enrich report with AI insights using Google Gemini (NEW!)
-h, --help Display help
Generate AI-enhanced reports with Google Gemini:
# 1. Set up your API key
cd server
echo "GOOGLE_API_KEY=your_key_here" > .env
# 2. Run scan with LLM enrichment
node server/dist/server.js . --llm --format=json --out=./reports
# This generates report-llm.json with:
# - Executive summary of overall security posture
# - Per-file AI analysis and recommendations
# - Actionable remediation stepsNote: Get your free API key at https://aistudio.google.com/app/apikey
Visualize scan results with the beautiful React dashboard:
cd client
# First time setup
npm install
# Sync latest report
npm run sync-report
# Start dashboard
npm run devOpen http://localhost:3000 to explore:
- π― Interactive filters (severity, config type, search)
- π Visual file cards with risk indicators
- β¨ AI insights panel with smart recommendations
- π Real-time statistics and trends
Human-readable output with findings grouped by file:
File: examples/Dockerfile.bad
Type: docker
Overall risk: HIGH
Overall score: 6
Findings: 4
- [HIGH] DOCKER_LATEST_TAG: Docker image uses the 'latest' tag.
Line: 1
Recommendation: Pin a specific version tag...
Machine-readable format suitable for CI/CD integration:
{
"files": [
{
"path": "examples/Dockerfile.bad",
"configType": "docker",
"findings": [...],
"overallScore": 6,
"overallRisk": "HIGH"
}
],
"scannedAt": "2025-11-25T07:16:21.092Z"
}Documentation-friendly format for reports and PR comments.
DOCKER_LATEST_TAG(HIGH) - Detects:latesttag usageDOCKER_MISSING_USER(MEDIUM) - No USER instruction (runs as root)DOCKER_MISSING_HEALTHCHECK(MEDIUM) - No HEALTHCHECK configuredDOCKER_EXPOSE_SSH(HIGH) - SSH port 22 exposedDOCKER_COPY_DOT_DOT(MEDIUM) - Broad COPY . . patternDOCKER_NO_CMD_OR_ENTRYPOINT(LOW) - Missing CMD/ENTRYPOINTDOCKER_BAD_BASE_IMAGE(HIGH) - Outdated base imagesDOCKER_PACKAGE_INSTALL_NO_CLEANUP(LOW) - No cleanup after package install
K8S_PRIVILEGED_CONTAINER(HIGH) - Privileged mode enabledK8S_RUN_AS_ROOT(HIGH) - Running as root userK8S_MISSING_SECURITY_CONTEXT(MEDIUM) - No securityContextK8S_MISSING_RESOURCES(MEDIUM) - No resource limitsK8S_MISSING_PROBES(MEDIUM) - No health probesK8S_HOSTPATH_VOLUME(HIGH) - hostPath volumes usedK8S_HOSTNETWORK_TRUE(HIGH) - hostNetwork enabledK8S_IMAGE_LATEST_TAG(MEDIUM) - Image uses :latest tagK8S_MISSING_READONLY_ROOT_FS(MEDIUM) - Mutable root filesystem
NGINX_SSL_PROTOCOLS_WEAK_OR_MISSING(MEDIUM/CRITICAL) - Weak TLS protocolsNGINX_SERVER_TOKENS_ON(MEDIUM) - Version disclosure enabledNGINX_MISSING_X_CONTENT_TYPE_OPTIONS(MEDIUM) - Missing security headerNGINX_MISSING_X_FRAME_OPTIONS(MEDIUM) - Missing anti-clickjacking headerNGINX_AUTOINDEX_ON(MEDIUM) - Directory listing enabledNGINX_HTTP_NO_REDIRECT(MEDIUM) - HTTP without HTTPS redirectNGINX_CLIENT_MAX_BODY_SIZE(LOW/MEDIUM) - Missing or excessive size limitNGINX_MISSING_HSTS(MEDIUM) - Missing Strict-Transport-Security header
Every security finding is mapped to recognized industry standards and frameworks for credibility and compliance tracking:
- CIS Benchmarks: Center for Internet Security best practices for Docker, Kubernetes, and Nginx
- CWE (Common Weakness Enumeration): Standardized software weakness identifiers
- OWASP ASVS: Application Security Verification Standard
- NSA Kubernetes Hardening: National Security Agency's Kubernetes hardening guidance
Example Console Output:
[HIGH] K8S_PRIVILEGED_CONTAINER [CIS 5.2.5 | CWE-250 | ASVS 9.x | NSA Kubernetes Hardening]
Example JSON Output:
{
"id": "DOCKER_LATEST_TAG",
"severity": "HIGH",
"cis": "CIS Docker 4.1",
"cweId": "CWE-1104",
"owasp": "ASVS 14.2"
}Example Markdown Output:
**Related Standards:**
- CIS: CIS Docker 4.1
- CWE: CWE-1104
- OWASP: ASVS 14.2This mapping helps with:
- β Compliance auditing and reporting
- β Risk communication to stakeholders
- β Integration with vulnerability management systems
- β Academic and industry credibility
Scores are calculated by summing individual finding severities:
| Severity | Points | Description |
|---|---|---|
| LOW | 0.5 | Minor issues, cosmetic |
| MEDIUM | 1 | Best-practice violations |
| HIGH | 3 | Significant security risks |
| CRITICAL | 5 | Severe vulnerabilities |
Score Interpretation:
- 0-2: β Low Risk
- 3-5:
β οΈ Medium Risk - 6-10: π΄ High Risk
- 10+: π¨ Critical Risk
The tool includes a GitHub Actions workflow that:
- Runs on every push and pull request
- Scans all config files in the repository
- Blocks builds if any file has HIGH or CRITICAL risk
- Uploads scan reports as artifacts
The workflow is automatically configured at .github/workflows/config-scan.yml.
To enable it:
- Ensure the workflow file exists (created during Phase 7)
- Push to your repository
- The workflow will run automatically
You can manually run the CI check locally:
# Generate JSON report
npm start . --format=json --out=./reports
# Run CI check (exits with code 1 if HIGH/CRITICAL findings exist)
node dist/utils/ciCheck.js ./reports/report.jsonPassing Build:
β
config-scan: No HIGH/CRITICAL findings. CI check passed.Failing Build:
β config-scan: Blocking findings detected.
- examples/Dockerfile.bad (type=docker, risk=HIGH, score=6)
Findings: 4
β’ [HIGH] DOCKER_LATEST_TAG
β’ [MEDIUM] DOCKER_MISSING_USER
...
Total files with HIGH/CRITICAL risk: 2For other CI systems (GitLab CI, CircleCI, etc.):
# In your CI script:
cd server
npm install
npm run build
# Run scan and generate JSON report
node dist/server.js . --format=json --out=./reports
# Check for blocking findings
node dist/utils/ciCheck.js ./reports/report.jsonThe ciCheck.js script exits with:
- Exit code 0: No HIGH/CRITICAL findings (build passes)
- Exit code 1: HIGH/CRITICAL findings detected (build fails)
This repository uses GitHub Rulesets to enforce secure development practices and ensure that no insecure configuration changes are merged into main.
The following protections are enforced on the main branch:
Require Pull Request Before Merging
- Direct pushes to main are blocked. All changes must come through PRs.
Require Status Checks to Pass
- The
config-scanGitHub Actions workflow must succeed before a PR can be merged. - Required Status Check:
config-scan(GitHub Actions)
Block Force Pushes
- Prevents bypassing or overwriting protected history.
1. Pushing to main is rejected
Attempting a direct push results in:
remote: error: GH013: Repository rule violations found.
- Changes must be made through a pull request.
- Required status check "config-scan" is expected.
This ensures nothing hits production without scanning.
2. Feature branches work normally
Branches such as:
feature/new-rulefix-classifierbad-config
can be pushed freely, because the ruleset targets only main.
3. Opening a Pull Request triggers the scan
When a PR is opened:
- GitHub automatically starts the
config-scanworkflow - UI shows: "Some checks haven't completed yet"
- GitHub cannot disable the merge button while checks are running, butβ¦
4. β If the scan fails β Merge is blocked
Once the check completes and fails:
- "All checks have failed"
- The merge button is disabled
- PR cannot be merged until issues are fixed
This ensures insecure configuration changes can never reach main.
5. β If scan passes β Merge is allowed
When the scan reports ZERO HIGH/CRITICAL findings:
- Check passes β
- PR becomes mergeable
- Ruleset validates both code integrity and configuration security
- Create a new branch
- Commit changes
- Push branch
- Open PR to main
- Wait for config-scan to finish
- Fix issues if workflow fails
- Merge only when scan is green β
# Install dependencies
cd server
npm install
# Run in development mode with watch
npm run dev -- ./examples
# Build for production
npm run build
# Run built version
npm start ./examplesserver/
βββ handlers/
β βββ rules/ # Security rule implementations
β β βββ dockerRules.ts
β β βββ kubernetesRules.ts
β β βββ nginxRules.ts
β βββ scanHandler.ts # Main scanning logic
β βββ reportHandler.ts # Report formatting
βββ models/
β βββ rule.ts # Rule type definitions
β βββ report.ts # Report type definitions
βββ utils/
β βββ scoring.ts # Risk scoring logic
β βββ ciCheck.ts # CI/CD check script
β βββ ...
βββ routes/
β βββ cliRoutes.ts # CLI interface
βββ server.ts # Entry point
See the examples/ directory for sample configurations that trigger various rules:
Dockerfile.bad- Docker with multiple issuesdeployment-bad.yaml- Kubernetes with security problemsnginx-bad.conf- Nginx with missing security headers
ISC
Contributions welcome! Please ensure:
- All rules are deterministic (same input β same output)
- Rules include clear descriptions and actionable recommendations
- New rules are added to the appropriate rule file
- Tests pass:
npm run buildshould complete without errors