Your Terraform configurations haven't been scanned for security misconfigurations in 18 days. A Kubernetes manifest with an overly permissive container security context was merged and deployed last week. KICS would have flagged it immediately — but your KICS CI step was silently removed when someone restructured the pipeline.
KICS (Keeping Infrastructure as Code Secure) from Checkmarx is one of the most comprehensive open-source IaC security scanners available. But like any CI-integrated tool, it can disappear from your pipeline without generating a single alert. This tutorial shows you how to use Vigilmon heartbeat monitors to ensure KICS scans run on schedule and catch infrastructure security blind spots before they matter.
What You'll Cover
- Heartbeat monitoring for scheduled KICS IaC scans
- Detecting KICS scan steps silently removed from CI pipelines
- Multi-environment scan coverage (Terraform, Kubernetes, CloudFormation, Dockerfile)
- Alert routing for IaC security failures
- Dashboard setup for infrastructure security posture
Prerequisites
- KICS installed or available in CI (
docker pull checkmarx/kics) - Infrastructure-as-code files in your repository (Terraform, Kubernetes YAML, CloudFormation, Dockerfiles, etc.)
- A free account at vigilmon.online
The Problem: When IaC Security Scans Stop Running
KICS finds problems in your infrastructure code — but only when it runs. Silent scan failures create security blind spots at exactly the wrong moments:
- A CI pipeline refactor removes the KICS scan step without anyone noticing
- KICS exits non-zero (found issues) but the CI step is misconfigured with
continue-on-error: true, masking both the findings and the scan status - A new infrastructure directory is added that isn't covered by the existing KICS scan path
- A scheduled KICS scan fails silently due to a Docker pull timeout or image change
The result: infrastructure code ships to production without IaC security review, and your security posture silently degrades.
Vigilmon's heartbeat pattern makes the gap visible: KICS pings a URL on successful scan completion, and if that ping doesn't arrive within the expected window, you get alerted.
Step 1: Create a Heartbeat Monitor in Vigilmon
- Log in to Vigilmon and click New Monitor → Heartbeat.
- Name it clearly:
KICS Scan — terraform (daily)orKICS Scan — k8s manifests (weekly). - Set the Expected interval to match your scan schedule:
- Daily scans on every merge to main: 25 hours
- Weekly scheduled scans: 8 days
- Set the Grace period to 2 hours for daily scans, 12 hours for weekly.
- Save and copy the Ping URL — it looks like
https://vigilmon.online/api/heartbeat/<unique-id>.
Step 2: Add Heartbeat Monitoring to a GitHub Actions KICS Scan
Here's a complete workflow that runs KICS and pings Vigilmon on completion:
# .github/workflows/kics-scan.yml
name: KICS IaC Security Scan
on:
push:
branches: [main]
paths:
- "terraform/**"
- "k8s/**"
- "**.dockerfile"
- "Dockerfile*"
schedule:
- cron: "0 4 * * 1" # weekly on Monday at 04:00 UTC
workflow_dispatch:
jobs:
kics-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run KICS scan
uses: checkmarx/kics-github-action@v2
with:
path: "."
output_path: kics-results/
output_formats: "json,sarif"
# Exit code 0 = no findings; 50 = findings found (non-blocking)
# Use fail_on to control which severities block the pipeline
fail_on: "critical,high"
exclude_paths: "node_modules,vendor,.git"
- name: Upload KICS results as artifact
uses: actions/upload-artifact@v4
if: always()
with:
name: kics-results
path: kics-results/
- name: Upload SARIF results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: kics-results/
- name: Ping Vigilmon heartbeat
if: success()
run: |
curl -fsS -X POST "${{ secrets.VIGILMON_KICS_SCAN_URL }}" \
--max-time 10 \
--retry 3 \
--retry-delay 2
Important: the heartbeat is sent on if: success() — meaning the KICS action itself must exit 0. The fail_on: "critical,high" option means KICS exits non-zero only when high or critical findings exist. If you want to always send the heartbeat when KICS ran (even with findings), use:
- name: Ping Vigilmon heartbeat
if: steps.kics-scan.conclusion == 'success' || steps.kics-scan.conclusion == 'failure'
run: |
# Only send heartbeat if KICS ran — not if the step was skipped or cancelled
if [ "${{ steps.kics-scan.conclusion }}" != "cancelled" ]; then
curl -fsS -X POST "${{ secrets.VIGILMON_KICS_SCAN_URL }}" --max-time 10 --retry 3
fi
Choose the approach that fits your team's policy: heartbeat on clean scan only, or heartbeat on scan completion regardless of findings.
Step 3: Running KICS Directly (Docker-based)
If you're not using the official GitHub Action, run KICS via Docker and add the heartbeat manually:
- name: Run KICS scan (Docker)
run: |
docker run --rm \
-v "$(pwd):/path" \
checkmarx/kics:latest scan \
--path /path \
--output-path /path/kics-results \
--output-name results \
--report-formats "json,sarif" \
--exclude-paths "node_modules,vendor,.git" \
--fail-on "critical,high"
- name: Ping Vigilmon heartbeat
if: success()
run: |
curl -fsS -X POST "${{ secrets.VIGILMON_KICS_SCAN_URL }}" \
--max-time 10 \
--retry 3
Step 4: GitLab CI Integration
# .gitlab-ci.yml
stages:
- security
- notify
kics-iac-scan:
stage: security
image: checkmarx/kics:latest
script:
- >
kics scan
--path .
--output-path ./kics-results
--report-formats json,sarif
--fail-on critical,high
--exclude-paths "node_modules,vendor,.git"
artifacts:
when: always
paths:
- kics-results/
reports:
sast: kics-results/results.sarif
only:
- main
- schedules
kics-heartbeat:
stage: notify
script:
- >
curl -fsS -X POST "$VIGILMON_KICS_SCAN_URL"
--max-time 10
--retry 3
when: on_success
needs: ["kics-iac-scan"]
only:
- main
- schedules
Step 5: Scan Coverage Per Infrastructure Type
KICS supports many infrastructure types. Create a separate heartbeat monitor for each major scan target so you can detect coverage gaps at a granular level:
| Infrastructure type | Scan path | Monitor name | Interval |
|---|---|---|---|
| Terraform | terraform/ | KICS — Terraform | 8 days |
| Kubernetes | k8s/, helm/ | KICS — Kubernetes | 8 days |
| Dockerfiles | **/Dockerfile* | KICS — Dockerfiles | 8 days |
| CloudFormation | cloudformation/ | KICS — CloudFormation | 8 days |
Split your CI job into per-type scans and map each to its own heartbeat monitor. This makes it clear exactly which infrastructure type lost scan coverage when a pipeline breaks.
kics-scan-terraform:
# ... scans terraform/ only, pings VIGILMON_KICS_TERRAFORM_URL
kics-scan-k8s:
# ... scans k8s/ only, pings VIGILMON_KICS_K8S_URL
Step 6: Monitoring KICS Availability in Self-Hosted Environments
Teams running KICS in self-hosted runners or on private infrastructure may want to monitor whether KICS itself is reachable. If your CI agents can't pull the KICS Docker image or the binary is missing, scans fail silently.
Add a lightweight pre-scan check job:
verify-kics-available:
stage: .pre
script:
- docker pull checkmarx/kics:latest
- docker run --rm checkmarx/kics:latest version
allow_failure: false
If this job fails, the downstream scan job is never attempted, and the heartbeat is never sent — Vigilmon will alert you.
Step 7: Configure Alert Channels
In Vigilmon, go to Notifications → New Channel and configure:
- Email — alert to your security team or DevSecOps distribution list
- Slack webhook — post to
#security-alertsor#infrastructure - PagerDuty — for environments where IaC security coverage is a compliance requirement
Use separate notification channels for scan failures (heartbeat misses) vs. finding alerts (which come from KICS directly or GitHub Advanced Security). Scan failure alerts mean you've lost coverage — that's a higher-priority signal.
When KICS stops running:
🔴 MISSED HEARTBEAT: KICS — Terraform
Last ping: 9 days ago
Expected interval: 7 days
This tells your team that Terraform configurations have had no IaC security review for 9 days — before a compliance auditor or a production incident surfaces the gap.
What You're Now Catching
| Silent failure mode | How Vigilmon detects it |
|---|---|
| CI step removed after pipeline refactor | No ping → alert after grace period |
| KICS Docker image pull fails | Scan never runs, no ping → alert |
| New IaC directory not covered by scan path | Separate monitor per path surfaces gap |
| continue-on-error masks scan failure | Heartbeat wired to success only → alert |
| Scheduled scan trigger drops off | No ping in expected window → alert |
| Self-hosted runner loses KICS binary | Pre-check fails, no ping → alert |
KICS provides comprehensive IaC security coverage across Terraform, Kubernetes, CloudFormation, and dozens of other formats — but only when it runs. Vigilmon's heartbeat monitors give your security team the confidence that IaC security scans are actually executing on schedule, and an immediate alert when they stop.
Start monitoring your KICS scans today — register free at vigilmon.online.