One Action. CIS, SOC 2, and ISO 27001 in CI.
Stop stitching Dockle, Grype, and docker-bench-security into a gate that still has no unified score. jakelamon/keelix@v0.1.0 runs all 93 compliance checks — CIS Docker Benchmark, SOC 2, ISO 27001 — in one step, emits a 0–100 posture score, and gates the promote-to-production job if the box is not fit to ship.
The stitching problem
The conventional approach to a Docker compliance gate is to chain three tools: Dockle for image best-practice linting, Grype for CVE matching, and docker-bench-security for CIS host and daemon checks. Each tool does its slice reasonably well. The gate does not.
Here is what you are actually taking on when you stitch them:
Scope: Image construction only
Gap: Cannot check the running host, daemon config, or anything provisioned after the image was built. No numeric score.
Scope: CVE matching in image layers and filesystems
Gap: No CIS compliance checks, no host config auditing, no posture scoring. Exits non-zero on severity threshold only.
Scope: Host + daemon + container runtime checks (CIS-aligned)
Gap: Emits prose PASS/WARN/INFO output with no unified numeric score — a limitation noted in the project's own issue tracker. Designed for post-deployment auditing, not pre-deploy gating.
After all three steps pass, you still do not have a single threshold to gate on. You have three exit codes, three output formats, and glue scripts to maintain. And none of the three tools can see the AI agents or MCP servers deployed on the same box — because none of that lives in an image layer.
One gate, one score
Keelix runs all compliance checks in a single action step. The 93 deterministic checks span:
- CIS Docker Benchmark — host, daemon, container runtime, and image configuration
- SOC 2 Trust Services Criteria — CC6/CC7 logical access and system operations controls
- ISO 27001 Annex A — access control, cryptography, operations security
- Outside-in exposure— what's actually reachable from the internet (0.0.0.0 bindings, open ports)
- AI-agent / MCP posture — auto-approval, plaintext secrets in MCP config, unvetted servers
Every finding maps to its source control so the scan output is audit-ready — shareable with an external auditor without re-running the scanner. The result is a single 0–100 posture score you set a threshold on once.
Quick start
jobs:
compliance-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Keelix compliance gate
uses: jakelamon/keelix@v0.1.0
with:
compose: docker-compose.ymlThe action exits non-zero on any critical compliance finding. Add report: html to emit a shareable audit report artifact. Pass a baseline JSON to gate only on findings new since your last clean scan.
Full pipeline: Grype CVEs + Keelix compliance
Keelix and Grype (or Trivy) are complementary. Run Grype in the build stage for CVE gating on the image. Run Keelix in the deploy-to-staging stage for compliance and posture gating on the running box. They do not overlap, and neither replaces the other.
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Grype CVE gate
uses: anchore/scan-action@v6
with:
image: myapp:${{ github.sha }}
fail-build: true
severity-cutoff: critical
deploy-to-staging:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# … your staging deploy steps …
- name: Keelix compliance gate
uses: jakelamon/keelix@v0.1.0
with:
compose: docker-compose.yml
report: html
- name: Upload compliance report
if: always()
uses: actions/upload-artifact@v4
with:
name: keelix-compliance-report
path: ${{ runner.temp }}/keelix-report.html
promote-to-production:
needs: deploy-to-staging
runs-on: ubuntu-latest
steps:
# … runs only if both gates passed …The Grype step gates on CVEs in the image layer. The Keelix step gates on the compliance posture of the running deployment — the checks that only exist once the stack is up. Neither tool does the other's job.
Roll out without blocking your team: monitor then enforce
If you are adding compliance gating to an existing pipeline, start with monitoring. Run the action with continue-on-error: true, upload the HTML report, and review findings for a sprint without blocking deployments.
Once you have cleared or triaged the initial findings, remove continue-on-error and optionally supply a baseline JSON so the gate only fires on regressions — new findings since your last clean scan. Your backlog does not block new work; new violations do.
- name: Keelix compliance scan (monitor)
uses: jakelamon/keelix@v0.1.0
continue-on-error: true
with:
compose: docker-compose.yml
report: html
- name: Upload compliance report
uses: actions/upload-artifact@v4
with:
name: keelix-compliance-report
path: ${{ runner.temp }}/keelix-report.html - name: Restore compliance baseline
uses: actions/cache@v4
with:
path: keelix-baseline.json
key: keelix-baseline-${{ github.ref_name }}
- name: Keelix compliance gate (enforce)
uses: jakelamon/keelix@v0.1.0
with:
compose: docker-compose.yml
baseline: keelix-baseline.json
- name: Save new baseline
run: cp ${{ runner.temp }}/keelix-scan.json keelix-baseline.jsonThe compliance gap no image tool fills
Every CIS Docker Benchmark tool — docker-bench-security, Dockle, Trivy misconfiguration checks — scans artifacts and runtime config. None of them see the AI agents and MCP servers running alongside your Docker stack.
If your deployment includes Claude Code, Cursor, Windsurf, or any other MCP-enabled agent, those configs sit on the host filesystem — not in any container image. An MCP server with auto-approval enabled, or a .mcp.json with a plaintext API key, will pass every image-layer compliance check clean. Keelix grades that surface and folds it into the same posture score as the CIS findings — so the compliance gate covers the whole box, including the AI surface image tools cannot see.
Frequently asked
- How do I run a CIS Docker Benchmark check in GitHub Actions?
- Add `uses: jakelamon/keelix@v0.1.0` to your deploy-to-staging job. The action installs the Keelix CLI, runs all 93 CIS/SOC 2/ISO 27001 checks against the live stack, and exits non-zero if a critical compliance finding is present. The result is a single posture score, not a raw pass/warn/info log you have to manually parse.
- What is wrong with stitching Dockle, Grype, and docker-bench-security?
- Each tool covers a slice: Dockle lints image construction; Grype matches CVEs in image layers; docker-bench-security audits host and daemon config but emits prose output and no unified numeric score (a known limitation logged in the project's own issue tracker). Wiring them into a single gate means writing glue scripts to parse three different output formats, defining three different severity thresholds, and still lacking a single number to gate on. None of the three cover AI-agent/MCP posture. Keelix runs all compliance dimensions in one step and emits a 0–100 score you can threshold in one `with: compose:` line.
- What compliance frameworks does the Keelix compliance gate cover?
- The 93 deterministic checks map to CIS Docker Benchmark (v1.6), SOC 2 Trust Services Criteria (CC6/CC7 controls), and ISO 27001 Annex A controls. Each finding is tagged to its source control so the scan output doubles as audit evidence — shareable with auditors without re-running the scanner.
- Can I fail the build only on compliance violations, not CVEs?
- Yes. The Keelix gate operates on the posture score and critical findings from the compliance dimension. You can run Grype or Trivy in a parallel step for CVE gating and Keelix for the compliance/posture gate — they are complementary and do not overlap.
- Does the compliance gate cover AI-agent and MCP server risks?
- Yes — this is the gap no image-only compliance tool fills. If an MCP server is deployed with auto-approval enabled, or a Claude Code config file is storing a plaintext API key, those findings appear in the posture score alongside the CIS findings. docker-bench-security, Dockle, and Grype are all blind to the AI-agent surface because it does not live in an image layer.
- Does the action send scan data to Keelix servers?
- No. The action installs the Keelix CLI binary into the runner's temp directory, runs every check on-runner, and writes results to a local JSON file. No scan data, no secrets, no posture score leaves the runner. The CLI is Apache-2.0 and the source is public at github.com/jakelamon/keelix.
Related
- GitHub Action security gate — full inputs reference and pipeline patterns
- CIS Docker Benchmark scanner — scored, audit-ready reports
- SOC 2 evidence for self-hosted Docker — the Vanta/Drata blind spot
- Compliance control mapping — assess once, report many
- AI/MCP security — the posture surface compliance tools miss
- How to fail a CI build on security findings — thresholds and exit codes
- Pricing — the CLI and Action are free and Apache-2.0
One gate for all your compliance checks.
Free, local-first, Apache-2.0. CIS, SOC 2, and ISO 27001 checks run on-runner. Nothing leaves your box.