# This IS the shipped data-tier runtime rule: k8s/tracingpolicy.yaml is a verbatim copy of this
# zero-exec policy, applied by scripts/up. ADR 0001 promoted it from the earlier selective
# arg0-Postfix cut (now the M4 lab primitive `block-shell-in-data-tier`). This annotated copy
# carries the live-validation record + the design rationale; verify.sh asserts it (id+sh -> 137).
#
# VALIDATED LIVE on kind + Tetragon 1.7.0 (a tier=data nginx-unprivileged:alpine pod):
#   id  /  /bin/sh -c echo  /  a renamed busybox copy (/tmp/x)  /  /bin/busybox id
#       -> ALL SIGKILL (rc=137), arg0/name/rename-independent
#   nginx (PID1, exec'd before the policy) keeps serving (Running, ready, 0 restarts).
#
# WHY "kill all exec" and NOT matchBinaries (corrects a common claim):
#   Tetragon `matchBinaries` on sys_execve matches the CALLER binary, not the new image.
#   So `matchBinaries NotIn [/usr/sbin/nginx]` kills `nginx -v` (caller = the runtime exec
#   shim) AND MISSES an in-nginx-RCE shell (caller = nginx). It is the wrong tool for
#   "which binary is being launched." A datastore should run only its main process, so we
#   forbid ALL exec in the data tier instead of allowlisting by (spoofable) name.
#
# Hooks BOTH sys_execve and sys_execveat, so the execveat bypass (a separate, naive-rule-
# unhooked syscall) is closed too. fd-exec still goes through execve(at) -> covered.
# io_uring has no exec opcode (N/A).
#
# HONEST CAVEATS:
#   - Restart-tolerance comes from Tetragon's enforcement-attach WINDOW, not from the image.
#     Validated live: BOTH this alpine image AND a distroless chainguard/nginx come up Ready
#     with this policy active from t=0 — the container's PID1 entrypoint execve slips the
#     attach window in either case (fragile + image-independent; a faster attach could SIGKILL
#     the entrypoint -> CrashLoop). So distroless is NOT what makes it restart-safe.
#   - Distroless's distinct benefit is IMAGE-LAYER (defense-in-depth), not restart-safety:
#     chainguard/nginx ships NO /bin/sh and NO busybox at all (validated: `/bin/sh` -> "no such
#     file" before this policy even applies), whereas the alpine image ships both. So a
#     distroless data-tier image removes the shell entirely, and this runtime rule still kills
#     any binary an attacker WRITES into a writable mount. Use distroless + this rule together.
#   - This kills legitimate `kubectl exec` and exec-based liveness/readiness probes (that
#     is the point — zero interactive exec in the datastore). Use httpGet probes.
#   - For an allowlist (some exec permitted) rather than zero-exec, you need binary
#     identity from BPF-LSM (bprm_check_security), not arg0 strings.
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
  name: data-tier-no-exec
spec:
  podSelector:
    matchLabels:
      tier: data
  kprobes:
    - call: "sys_execve"
      syscall: true
      selectors:
        - matchActions:
            - action: Sigkill
    - call: "sys_execveat"
      syscall: true
      selectors:
        - matchActions:
            - action: Sigkill
