Deploy Mondoo security and compliance scanning in your Kubernetes cluster using ArgoCD for GitOps-based continuous deployment.
- Overview
- Features
- Prerequisites
- Architecture
- Quick Start
- Installation
- Configuration
- ArgoCD Application
- Usage
- Monitoring
- Troubleshooting
- Security Considerations
- Contributing
This repository contains GitOps configurations to deploy Mondoo security scanning platform to Kubernetes using ArgoCD. Mondoo provides:
- Container Security Scanning - Scan container images for vulnerabilities
- Kubernetes Security Posture - Assess cluster security configurations
- Compliance Scanning - CIS, NIST, PCI-DSS, SOC 2, and more
- Policy as Code - Define and enforce security policies
- Continuous Monitoring - Real-time security and compliance monitoring
- β GitOps-based deployment using ArgoCD
- β Automated sync from Git repository
- β Multi-environment support (dev, staging, production)
- β Helm-based installation with customizable values
- β Secret management with Sealed Secrets or External Secrets
- β Health checks and status monitoring
- β Automated updates with image updater
- β Policy enforcement via OPA Gatekeeper integration
Before deploying Mondoo via ArgoCD, ensure you have:
| Requirement | Version | Description |
|---|---|---|
| Kubernetes | 1.24+ | Target cluster |
| ArgoCD | 2.8+ | GitOps deployment tool |
| Helm | 3.0+ | Package manager (for local testing) |
| kubectl | 1.24+ | Kubernetes CLI |
| Mondoo Account | - | Free account at console.mondoo.com |
- Sign up at console.mondoo.com
- Create a new Space
- Generate a Service Account token
- Download the credentials JSON file
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Git Repository β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β manifests/ β β
β β βββ base/ β β
β β β βββ namespace.yaml β β
β β β βββ mondoo-secret.yaml (sealed) β β
β β β βββ mondoo-values.yaml β β
β β βββ overlays/ β β
β β βββ dev/ β β
β β βββ staging/ β β
β β βββ production/ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β (ArgoCD syncs)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ArgoCD β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Application: mondoo β β
β β - Auto-sync: enabled β β
β β - Self-heal: enabled β β
β β - Prune: enabled β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β (deploys to)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Kubernetes Cluster β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Namespace: mondoo β β
β β βββ mondoo-operator (Deployment) β β
β β βββ mondoo-client (DaemonSet) β β
β β βββ mondoo-admission-controller (Deployment) β β
β β βββ mondoo-config (Secret) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β (reports to)
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Mondoo Console β
β https://console.mondoo.com β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
git clone https://github.com/your-org/mondoo-argocd.git
cd mondoo-argocd# Create namespace
kubectl create namespace mondoo
# Create secret from Mondoo credentials
kubectl create secret generic mondoo-client \
--from-file=config=/path/to/mondoo-credentials.json \
-n mondoo
# Seal the secret (if using Sealed Secrets)
kubeseal --format=yaml --cert=pub-cert.pem \
< mondoo-secret.yaml > mondoo-sealed-secret.yamlkubectl apply -f argocd/mondoo-application.yaml# Check ArgoCD sync status
argocd app get mondoo
# Check Mondoo pods
kubectl get pods -n mondoo
# View Mondoo operator logs
kubectl logs -n mondoo -l app=mondoo-operatormondoo-argocd/
βββ argocd/
β βββ mondoo-application.yaml # ArgoCD Application manifest
β βββ mondoo-appproject.yaml # ArgoCD AppProject (optional)
β βββ image-updater-config.yaml # Image updater config
βββ manifests/
β βββ base/
β β βββ kustomization.yaml
β β βββ namespace.yaml
β β βββ mondoo-values.yaml # Helm values
β β βββ mondoo-secret-sealed.yaml # Sealed secret
β βββ overlays/
β βββ dev/
β β βββ kustomization.yaml
β β βββ mondoo-values.yaml
β βββ staging/
β β βββ kustomization.yaml
β β βββ mondoo-values.yaml
β βββ production/
β βββ kustomization.yaml
β βββ mondoo-values.yaml
βββ policies/
β βββ mondoo-policies.yaml # Custom Mondoo policies
βββ README.md
# manifests/base/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: mondoo
labels:
name: mondoo
app.kubernetes.io/name: mondoo
app.kubernetes.io/managed-by: argocdOption A: Using Sealed Secrets (Recommended)
# 1. Create regular secret
kubectl create secret generic mondoo-client \
--from-file=config=mondoo-credentials.json \
--dry-run=client -o yaml > mondoo-secret.yaml
# 2. Seal the secret
kubeseal --format=yaml --cert=pub-cert.pem \
< mondoo-secret.yaml > manifests/base/mondoo-secret-sealed.yaml
# 3. Commit sealed secret to Git
git add manifests/base/mondoo-secret-sealed.yaml
git commit -m "Add sealed Mondoo credentials"
git pushOption B: Using External Secrets Operator
# manifests/base/mondoo-external-secret.yaml
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: mondoo-client
namespace: mondoo
spec:
refreshInterval: 1h
secretStoreRef:
name: vault-backend
kind: SecretStore
target:
name: mondoo-client
creationPolicy: Owner
data:
- secretKey: config
remoteRef:
key: secret/mondoo/credentials
property: config# manifests/base/mondoo-values.yaml
mondoo:
# Mondoo operator configuration
operator:
image:
repository: mondoo/mondoo-operator
tag: latest
pullPolicy: IfNotPresent
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
# Mondoo client (DaemonSet)
client:
enable: true
image:
repository: mondoo/mondoo
tag: latest
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 50m
memory: 64Mi
# Scan configuration
scan:
schedule: "0 */6 * * *" # Every 6 hours
containers: true
nodes: true
workloads: true
# Admission controller (optional)
admission:
enable: true
mode: "enforce" # enforce, monitor, or disabled
replicas: 2
resources:
limits:
cpu: 300m
memory: 384Mi
requests:
cpu: 100m
memory: 128Mi
# Policy enforcement
policies:
- critical-vulnerabilities
- cis-kubernetes
- pod-security-standards
# Integration settings
integration:
kubernetes:
enabled: true
scanInterval: 6h
# Report findings
reporting:
webhook:
enabled: false
url: ""
slack:
enabled: false
webhook: ""
# RBAC
rbac:
create: true
# Service Account
serviceAccount:
create: true
name: mondoo
# Additional Kubernetes resources
nodeSelector: {}
tolerations: []
affinity: {}# manifests/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mondoo
resources:
- namespace.yaml
- mondoo-secret-sealed.yaml
helmCharts:
- name: mondoo-operator
repo: https://mondoohq.github.io/mondoo-operator
version: 1.14.0
releaseName: mondoo
namespace: mondoo
valuesFile: mondoo-values.yamlDevelopment Environment:
# manifests/overlays/dev/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mondoo
bases:
- ../../base
patchesStrategicMerge:
- mondoo-values.yaml# manifests/overlays/dev/mondoo-values.yaml
mondoo:
admission:
mode: "monitor" # Don't enforce in dev
client:
scan:
schedule: "0 */12 * * *" # Less frequent in devProduction Environment:
# manifests/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: mondoo
bases:
- ../../base
patchesStrategicMerge:
- mondoo-values.yaml# manifests/overlays/production/mondoo-values.yaml
mondoo:
admission:
mode: "enforce" # Enforce in production
replicas: 3 # High availability
client:
scan:
schedule: "0 */4 * * *" # More frequent in prod
resources:
limits:
cpu: 500m
memory: 512MiCreate the ArgoCD Application manifest:
# argocd/mondoo-application.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mondoo
namespace: argocd
labels:
app: mondoo
environment: production
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
# Source repository
source:
repoURL: https://github.com/your-org/mondoo-argocd.git
targetRevision: main
path: manifests/overlays/production
# Destination cluster
destination:
server: https://kubernetes.default.svc
namespace: mondoo
# Sync policy
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
# Health checks
ignoreDifferences:
- group: apps
kind: Deployment
jsonPointers:
- /spec/replicas# argocd/mondoo-application-dev.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mondoo-dev
namespace: argocd
spec:
project: mondoo
source:
repoURL: https://github.com/your-org/mondoo-argocd.git
targetRevision: develop
path: manifests/overlays/dev
destination:
server: https://dev-cluster.example.com
namespace: mondoo
syncPolicy:
automated:
prune: true
selfHeal: true# argocd/mondoo-application-prod.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: mondoo-prod
namespace: argocd
spec:
project: mondoo
source:
repoURL: https://github.com/your-org/mondoo-argocd.git
targetRevision: main
path: manifests/overlays/production
destination:
server: https://prod-cluster.example.com
namespace: mondoo
syncPolicy:
automated:
prune: true
selfHeal: false # Manual sync in production# argocd/mondoo-appproject.yaml
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: mondoo
namespace: argocd
spec:
description: Mondoo Security Platform
# Source repositories
sourceRepos:
- https://github.com/your-org/mondoo-argocd.git
- https://mondoohq.github.io/mondoo-operator
# Destination clusters
destinations:
- namespace: mondoo
server: https://kubernetes.default.svc
- namespace: mondoo
server: https://dev-cluster.example.com
- namespace: mondoo
server: https://prod-cluster.example.com
# Allowed cluster resources
clusterResourceWhitelist:
- group: ''
kind: Namespace
- group: ''
kind: ClusterRole
- group: ''
kind: ClusterRoleBinding
- group: 'admissionregistration.k8s.io'
kind: ValidatingWebhookConfiguration
- group: 'admissionregistration.k8s.io'
kind: MutatingWebhookConfiguration
# Namespace resources
namespaceResourceWhitelist:
- group: '*'
kind: '*'
# RBAC roles
roles:
- name: read-only
description: Read-only access
policies:
- p, proj:mondoo:read-only, applications, get, mondoo/*, allow
- name: admin
description: Admin access
policies:
- p, proj:mondoo:admin, applications, *, mondoo/*, allow# Apply ArgoCD Application
kubectl apply -f argocd/mondoo-application.yaml
# Watch deployment
argocd app get mondoo --watch
# Or use kubectl
kubectl get applications -n argocd -w# Manual sync
argocd app sync mondoo
# Sync with prune
argocd app sync mondoo --prune
# Force sync
argocd app sync mondoo --force# Get application details
argocd app get mondoo
# View sync history
argocd app history mondoo
# View application tree
argocd app tree mondoo# Check all Mondoo resources
kubectl get all -n mondoo
# Check operator logs
kubectl logs -n mondoo -l app=mondoo-operator -f
# Check client pods (DaemonSet)
kubectl get pods -n mondoo -l app=mondoo-client
# Check admission controller
kubectl logs -n mondoo -l app=mondoo-admission# Get scan reports
kubectl get mondooauditconfigs -n mondoo
# View specific scan
kubectl describe mondooauditconfig cluster-scan -n mondoo
# Check for vulnerabilities
kubectl get vulnerabilities -n mondooArgoCD monitors these resources:
# Health assessment rules
spec:
health:
mondooauditconfig:
# Custom health check for Mondoo CRDs
lua: |
hs = {}
if obj.status ~= nil then
if obj.status.conditions ~= nil then
for i, condition in ipairs(obj.status.conditions) do
if condition.type == "Available" and condition.status == "True" then
hs.status = "Healthy"
hs.message = "Mondoo is scanning"
return hs
end
end
end
end
hs.status = "Progressing"
hs.message = "Waiting for scan to complete"
return hs# ServiceMonitor for Prometheus
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: mondoo-operator
namespace: mondoo
spec:
selector:
matchLabels:
app: mondoo-operator
endpoints:
- port: metrics
interval: 30s
path: /metricsImport Mondoo dashboard:
# Dashboard ID: TBD (create custom dashboard)
# Monitor:
# - Scan success rate
# - Vulnerabilities found
# - Policy violations
# - Scan duration# Check application status
argocd app get mondoo
# View sync errors
argocd app sync mondoo --dry-run
# Check for differences
argocd app diff mondoo# Check pod status
kubectl get pods -n mondoo
# View pod events
kubectl describe pod <pod-name> -n mondoo
# Check logs
kubectl logs <pod-name> -n mondoo# Verify secret exists
kubectl get secret mondoo-client -n mondoo
# Check secret content
kubectl get secret mondoo-client -n mondoo -o jsonpath='{.data.config}' | base64 -d
# Recreate secret
kubectl delete secret mondoo-client -n mondoo
kubectl create secret generic mondoo-client \
--from-file=config=mondoo-credentials.json \
-n mondoo# Check webhook configuration
kubectl get validatingwebhookconfigurations | grep mondoo
# View webhook logs
kubectl logs -n mondoo -l app=mondoo-admission -f
# Test webhook
kubectl run test-pod --image=nginx --dry-run=server# ArgoCD debugging
argocd app manifests mondoo # View rendered manifests
argocd app logs mondoo # View application logs
argocd app events mondoo # View application events
# Kubernetes debugging
kubectl get events -n mondoo --sort-by='.lastTimestamp'
kubectl top pods -n mondoo
kubectl describe mondooauditconfig -n mondoo
# Helm debugging (for local testing)
helm template mondoo mondoo-operator/mondoo-operator \
-f manifests/base/mondoo-values.yaml \
--namespace mondoo- Never commit plaintext secrets to Git
- Use Sealed Secrets or External Secrets Operator
- Rotate Mondoo credentials regularly
- Limit secret access with RBAC
# Example: Rotate secret
apiVersion: v1
kind: Secret
metadata:
name: mondoo-client
namespace: mondoo
annotations:
sealedsecrets.bitnami.com/managed: "true"
rotation-date: "2024-01-01"
type: Opaque
data:
config: <base64-encoded-new-credentials># Limit ArgoCD access to Mondoo namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: mondoo-manager
namespace: mondoo
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: mondoo-manager-binding
namespace: mondoo
subjects:
- kind: ServiceAccount
name: argocd-application-controller
namespace: argocd
roleRef:
kind: Role
name: mondoo-manager
apiGroup: rbac.authorization.k8s.io# Restrict Mondoo network access
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: mondoo-netpol
namespace: mondoo
spec:
podSelector:
matchLabels:
app: mondoo
policyTypes:
- Ingress
- Egress
egress:
# Allow DNS
- to:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: UDP
port: 53
# Allow Mondoo API
- to:
- podSelector: {}
ports:
- protocol: TCP
port: 443- Make changes in Git first
- Create Pull Requests for reviews
- Use branch protection for production
- Enable auto-sync for non-production
- Manual sync for production deployments
# Pin Helm chart version
helmCharts:
- name: mondoo-operator
version: 1.14.0 # Specific version, not 'latest'# Use ArgoCD Progressive Sync
spec:
syncPolicy:
automated: null # Disable auto-sync
syncOptions:
- CreateNamespace=true
# Manual approval for production
# Use ArgoCD Rollouts for canary deploymentsContributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Mondoo Team for the security platform
- ArgoCD Team for the GitOps tool
- Community contributors
- Mondoo Support: support@mondoo.com
- Community Slack: Mondoo Slack
- Issues: GitHub Issues
Made with β€οΈ for Kubernetes Security