Kubernetes-Style Scan Scheduling Comes to Security Tools (JMo Security v0.8.0)

Running security scans manually gets old fast. You start with good intentions — “I’ll scan every Friday before release” — but then Friday becomes Saturday becomes “whenever I remember.”

The solution? Automation. But here’s the problem: most security tools don’t integrate cleanly with CI/CD platforms. You end up writing YAML by hand, copying configs between projects, and maintaining a dozen different cron schedules.

I built JMo Security to orchestrate 12+ security scanners (Trivy, Semgreg, TruffleHog, Checkov, ZAP, Nuclei, etc.) with a unified CLI. Version 0.8.0 adds the missing piece: enterprise-grade scheduling and CI/CD integration.

Table of Contents

  • What’s New in v0.8.0

    • 1. Kubernetes-Style Schedule Management
    • 2. GitLab CI/CD Workflow Generation
    • 3. Slack Notifications
  • Why This Matters
  • Real-World Use Cases
  • Getting Started
  • What’s Next
  • Contributing

What’s New in v0.8.0

1. Kubernetes-Style Schedule Management

If you’ve worked with Kubernetes CronJobs, this will feel instantly familiar:

# Create a weekly security scan schedule
jmo schedule create prod-security-audit 
  --cron "0 2 * * 1" 
  --profile balanced 
  --repo ./myapp 
  --image myapp:latest 
  --url https://myapp.com 
  --backend gitlab-ci 
  --slack-webhook "https://hooks.slack.com/services/YOUR/WEBHOOK"

This creates a schedule resource with Kubernetes-style metadata, spec, and status fields:

metadata:
  name: prod-security-audit
  uid: f47ac10b-58cc-4372-a567-0e02b2c3d479
  creationTimestamp: "2025-10-28T14:30:00Z"
spec:
  schedule: "0 2 * * 1"  # Every Monday at 2 AM
  jobTemplate:
    spec:
      profile: balanced
      targets:
        repo: ./myapp
        image: myapp:latest
        url: https://myapp.com
      notifications:
        channels:
          - type: slack
            url: "https://hooks.slack.com/..."
  backend:
    type: gitlab-ci
status:
  lastScheduleTime: null
  nextScheduleTime: "2025-11-04T02:00:00Z"

Schedules are stored locally in ~/.jmo/schedules.json with secure permissions (0o600). No cloud dependencies.

2. GitLab CI/CD Workflow Generation

Once you’ve defined a schedule, export it to a ready-to-use GitLab CI pipeline:

jmo schedule export prod-security-audit > .gitlab-ci.yml

This generates a complete .gitlab-ci.yml with:

  • Profile-based jobs (fast/balanced/deep)
  • Multi-target support (repos, containers, IaC, web apps, K8s clusters)
  • Slack notifications on success/failure
  • Artifact uploads (JSON findings, HTML dashboard, SARIF reports)
  • Pipeline schedules matching your cron syntax

Example generated pipeline:

# Generated by JMo Security Schedule Manager
# Schedule: prod-security-audit (0 2 * * 1)

variables:
  JMO_PROFILE: "balanced"
  SLACK_WEBHOOK_URL: "https://hooks.slack.com/services/YOUR/WEBHOOK"

stages:
  - scan
  - notify

jmo-security-scan:
  stage: scan
  image: jmogaming/jmo-security:latest
  script:
    - jmo scan --profile balanced --repo . --image myapp:latest --url https://myapp.com
    - jmo report ./results --profile
  artifacts:
    reports:
      sast: results/summaries/findings.sarif
    paths:
      - results/
    expire_in: 30 days
  only:
    - schedules

notify-slack-success:
  stage: notify
  image: curlimages/curl:latest
  script:
    - |
      curl -X POST "$SLACK_WEBHOOK_URL" 
        -H 'Content-Type: application/json' 
        -d "{
          "text": "✅ Security scan PASSED: $CI_PIPELINE_URL",
          "attachments": [{
            "color": "good",
            "fields": [
              {"title": "Commit", "value": "$CI_COMMIT_SHORT_SHA", "short": true},
              {"title": "Branch", "value": "$CI_COMMIT_BRANCH", "short": true}
            ]
          }]
        }"
  only:
    - schedules
  when: on_success

notify-slack-failure:
  stage: notify
  image: curlimages/curl:latest
  script:
    - |
      curl -X POST "$SLACK_WEBHOOK_URL" 
        -H 'Content-Type: application/json' 
        -d "{
          "text": "❌ Security scan FAILED: $CI_PIPELINE_URL",
          "attachments": [{
            "color": "danger",
            "fields": [
              {"title": "Commit", "value": "$CI_COMMIT_SHORT_SHA", "short": true},
              {"title": "Branch", "value": "$CI_COMMIT_BRANCH", "short": true}
            ]
          }]
        }"
  only:
    - schedules
  when: on_failure

3. Slack Notifications

Slack integration is built-in. Configure webhooks in your schedule:

notifications:
  channels:
    - type: slack
      url: "https://hooks.slack.com/services/YOUR/WEBHOOK"

Notifications include:

  • ✅ Pipeline status (success/failure)
  • 📊 Commit info (SHA, branch, author)
  • 🔍 Findings count (when available)
  • 🔗 Direct link to pipeline

Why This Matters

Before v0.8.0, you had three options:

  1. Manual scans — Inconsistent, easy to forget
  2. Hand-written CI/CD YAML — Error-prone, hard to maintain across projects
  3. Third-party services — Expensive, cloud dependencies, vendor lock-in

Now you have a fourth option:

  • Declarative schedules stored locally
  • Auto-generated CI/CD configs for GitLab (GitHub Actions coming soon)
  • Zero cloud dependencies (except Slack webhooks, optional)
  • 100% open source

Real-World Use Cases

Use Case 1: Multi-Environment Security Gates

# Dev environment: Fast scans on every commit
jmo schedule create dev-security 
  --cron "*/15 * * * *" 
  --profile fast 
  --repo . 
  --backend gitlab-ci

# Staging: Balanced scans nightly
jmo schedule create staging-security 
  --cron "0 1 * * *" 
  --profile balanced 
  --repo . 
  --image staging:latest 
  --url https://staging.example.com 
  --backend gitlab-ci 
  --slack-webhook "$STAGING_SLACK_WEBHOOK"

# Production: Deep scans weekly
jmo schedule create prod-security 
  --cron "0 2 * * 0" 
  --profile deep 
  --repo . 
  --image prod:latest 
  --url https://example.com 
  --k8s-context prod 
  --backend gitlab-ci 
  --slack-webhook "$PROD_SLACK_WEBHOOK"

Use Case 2: Compliance Automation

JMo Security auto-enriches findings with 6 compliance frameworks (OWASP Top 10, CWE Top 25, NIST CSF 2.0, PCI DSS 4.0, CIS Controls v8.1, MITRE ATT&CK). Schedule weekly compliance reports:

jmo schedule create compliance-weekly 
  --cron "0 9 * * 1" 
  --profile balanced 
  --repo . 
  --image app:latest 
  --terraform-state infrastructure.tfstate 
  --backend gitlab-ci 
  --slack-webhook "$COMPLIANCE_SLACK_WEBHOOK"

Pipeline artifacts include:

  • COMPLIANCE_SUMMARY.md — Cross-framework compliance status
  • PCI_DSS_COMPLIANCE.md — PCI DSS 4.0 detailed report
  • attack-navigator.json — MITRE ATT&CK Navigator heatmap

Use Case 3: GitOps Workflow

Commit schedules to version control:

# Create schedules
jmo schedule create security-scan --cron "0 2 * * *" --profile balanced --repo .

# Export to GitLab CI
jmo schedule export security-scan > .gitlab-ci.yml

# Commit and push
git add .gitlab-ci.yml
git commit -m "ci: add automated security scans"
git push

# GitLab automatically picks up the pipeline schedule

Architecture Deep Dive

Storage

Schedules are stored in ~/.jmo/schedules.json with strict permissions:

{
  "schedules": [
    {
      "metadata": {
        "name": "prod-security-audit",
        "uid": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
        "creationTimestamp": "2025-10-28T14:30:00Z"
      },
      "spec": {
        "schedule": "0 2 * * 1",
        "jobTemplate": {},
        "backend": { "type": "gitlab-ci" }
      },
      "status": {
        "nextScheduleTime": "2025-11-04T02:00:00Z"
      }
    }
  ]
}

Cron Validation

Uses croniter library for full cron syntax support:

  • Standard 5-field cron (0 2 * * 1)
  • Extended syntax (ranges, steps, lists)
  • Timezone support (UTC default)
  • Next run calculation

Backend Abstraction

Designed for extensibility:

  • gitlab-ci (v0.8.0)
  • github-actions (planned v0.9.0)
  • local-cron (planned v0.9.0)
  • jenkins (community request)

Getting Started

Option 1: Docker (Zero Installation)

docker pull jmogaming/jmo-security:0.8.0
docker run --rm -it 
  -v "$(pwd):/scan" 
  jmogaming/jmo-security:0.8.0 
  schedule create my-scan --cron "0 2 * * *" --profile balanced --repo .

Option 2: PyPI

pip install jmo-security==0.8.0
jmo schedule create my-scan --cron "0 2 * * *" --profile balanced --repo .

Option 3: GitHub Clone

git clone https://github.com/jimmy058910/jmo-security-repo.git
cd jmo-security-repo
make dev-deps
jmo schedule create my-scan --cron "0 2 * * *" --profile balanced --repo .

Upgrade Notes

Breaking Changes: None. v0.8.0 is fully backward-compatible.

New Dependencies:

  • croniter>=2.0 (cron parsing)
  • types-croniter (type hints)

Install with: pip install --upgrade jmo-security[scheduling]

What’s Next

v0.9.0 Roadmap:

  • GitHub Actions workflow generation
  • Local cron integration
  • Schedule templating (reusable schedule configs)
  • Multi-region scheduling (different timezones per schedule)
  • Schedule dependency chains (“run scan B after scan A succeeds”)

See full roadmap: ROADMAP.md

Contributing

JMo Security is 100% open source (MIT OR Apache-2.0 dual-licensed). Contributions welcome:

Looking to hire? I’m a recent cybersecurity bootcamp graduate (Michigan Tech × Institute of Data, October 2025) actively seeking cybersecurity/DevSecOps roles. JMo Security started as my capstone project and evolved into a production-grade platform. Connect with me on LinkedIn.

Support the Project

Links:

Total
0
Shares
Leave a Reply

Your email address will not be published. Required fields are marked *

Previous Post

Managing goose Configurations Across Multiple Projects

Related Posts