Kubernetes Security Concepts¶
This page explains the Kubernetes security concepts used throughout this documentation. It is intended as a learning resource for platform operators who are deploying and managing the RCIIS security stack.
Admission Control¶
What Are Admission Webhooks?¶
When you run kubectl apply, the request does not go directly to etcd. It passes through a series of steps in the Kubernetes API server:
kubectl apply
|
v
Authentication (who are you?)
|
v
Authorization (are you allowed?)
|
v
Mutating Admission Webhooks <-- Can modify the resource
|
v
Schema Validation (is the YAML valid?)
|
v
Validating Admission Webhooks <-- Can reject the resource
|
v
Persisted to etcd
Admission webhooks are HTTP callbacks that the API server invokes before persisting a resource. They allow external services (like Kyverno) to inspect, modify, or reject resources.
Validating vs Mutating¶
| Type | What It Does | Example |
|---|---|---|
| Validating | Inspects the resource and returns allow/deny | Kyverno rejects a pod with privileged: true |
| Mutating | Modifies the resource before it is persisted | Kyverno adds default securityContext to a pod |
Mutating webhooks run before validating webhooks, so mutations are always validated.
Why This Matters for RCIIS¶
Kyverno is an admission controller. When it is deployed, every resource creation and update passes through Kyverno's webhook. This is the enforcement point for:
- Image registry allow-lists
- Pod security standards
- Resource limit requirements
- Image signature verification
- Label governance
If Kyverno is down and the webhook failurePolicy is Fail, no resources can be created — including deployments needed to fix the issue. See Webhook Failure Mode for mitigation.
Container Vulnerability Scanning¶
What Are CVEs?¶
A CVE (Common Vulnerabilities and Exposures) is a publicly disclosed security vulnerability. Each CVE has:
| Field | Example | Meaning |
|---|---|---|
| ID | CVE-2024-3094 | Unique identifier |
| Severity | CRITICAL / HIGH / MEDIUM / LOW | Impact rating (CVSS score) |
| Affected package | xz-utils 5.6.0-5.6.1 |
The specific software and versions |
| Fixed version | 5.6.2 |
The version that resolves the issue |
CVE severity is scored using the Common Vulnerability Scoring System (CVSS):
| CVSS Score | Severity | Meaning |
|---|---|---|
| 9.0–10.0 | CRITICAL | Easily exploitable, severe impact (remote code execution, data breach) |
| 7.0–8.9 | HIGH | Significant impact, moderate exploitation difficulty |
| 4.0–6.9 | MEDIUM | Limited impact or harder to exploit |
| 0.1–3.9 | LOW | Minimal impact, difficult to exploit |
How Scanners Work¶
Container vulnerability scanners compare the packages installed in a container image against CVE databases:
Container Image
|
v
Extract package list
(OS packages: dpkg, rpm, apk)
(Language deps: go.sum, requirements.txt, package-lock.json)
|
v
Compare against CVE databases
(NVD, GitHub Advisory, OS vendor advisories)
|
v
Generate report
(CVE ID, severity, affected package, fixed version)
Shift-Left vs Continuous Scanning¶
| Approach | When | Tool | Limitation |
|---|---|---|---|
| Shift-Left (CI pipeline) | Before deployment | Trivy CLI, Grype | Cannot detect CVEs discovered after the image was built |
| Continuous (in-cluster) | After deployment | Trivy Operator | Cannot prevent a vulnerable image from being deployed |
RCIIS uses both: CI pipeline scanning prevents known-vulnerable images from being pushed, and the Trivy Operator continuously rescans running workloads to catch newly disclosed CVEs.
Runtime Security & eBPF¶
Why Runtime Detection Matters¶
Static scanning (vulnerability scanning, policy enforcement) catches known issues before or at deployment time. But it cannot detect:
- Legitimate containers behaving maliciously — a compromised application making unexpected outbound connections
- Zero-day exploits — attacks using vulnerabilities not yet in any CVE database
- Runtime-specific behaviour — a shell being spawned inside a container, a process reading
/etc/shadow
Runtime security tools observe what containers actually do at the kernel level.
What Is eBPF?¶
eBPF (extended Berkeley Packet Filter) is a technology that allows programs to run in the Linux kernel without modifying kernel source code or loading kernel modules.
User Space
┌─────────────────────────────┐
│ Falco / Tracee │ ← Receives events, matches rules
│ (user-space process) │
└─────────────┬───────────────┘
│ events
Kernel Space │
┌─────────────┴───────────────┐
│ eBPF Program │ ← Attached to syscall entry points
│ (verified, sandboxed) │
├─────────────────────────────┤
│ Linux Kernel │
│ (syscalls, file ops, │
│ network, process mgmt) │
└─────────────────────────────┘
Key properties of eBPF:
| Property | Meaning |
|---|---|
| Sandboxed | eBPF programs are verified by the kernel before execution — they cannot crash the kernel |
| No kernel modification | No kernel module compilation or loading required |
| Low overhead | Programs run at near-native speed inside the kernel |
| CO-RE (Compile Once, Run Everywhere) | With BTF (BPF Type Format), a single eBPF binary works across kernel versions |
Why eBPF Matters for Talos Linux¶
Talos Linux is an immutable OS — it has:
- No shell, no SSH, no package manager
- No kernel headers or compiler toolchain
- Enforced kernel module signing
Traditional kernel module-based tools (like the Falco kernel module driver) cannot work on Talos because they need to compile a .ko file against the running kernel's headers at runtime.
eBPF-based tools (Falco with modern_ebpf, Tracee) work perfectly because they use pre-compiled eBPF programs that leverage CO-RE and BTF — no runtime compilation needed.
Supply Chain Security¶
The Container Supply Chain¶
Every container image has a supply chain — the sequence of steps and dependencies that produce it:
Source code (Git)
|
v
Build (CI pipeline: compile, test)
|
v
Container image (Docker build)
|
v
Push to registry (Harbor)
|
v
Deploy to cluster (FluxCD)
An attacker who compromises any step can inject malicious code:
| Attack Vector | Example | Mitigation |
|---|---|---|
| Compromised dependency | Malicious npm package | SBOM scanning, dependency pinning |
| Compromised CI pipeline | Injected build step | Signed images, reproducible builds |
| Registry tampering | Image tag overwritten with malicious image | Image signature verification |
| Tag mutability | latest tag points to different image over time |
Immutable tags, digest pinning |
Image Signing with cosign¶
cosign (part of the Sigstore project) signs container images to prove:
- Who built it — the signing identity (CI pipeline, developer)
- It has not been tampered with — the signature covers the image digest
Two signing modes:
| Mode | How It Works | Best For |
|---|---|---|
| Key-pair | Sign with a private key, verify with the corresponding public key | Air-gapped environments, full control |
| Keyless (Fulcio + Rekor) | Sign with an OIDC identity (e.g., GitHub Actions), record in a transparency log | Zero key management, public audit trail |
Software Bill of Materials (SBOM)¶
An SBOM is a machine-readable inventory of everything inside a container image — OS packages, language dependencies, and their versions.
Why SBOMs matter:
- When a new CVE is disclosed, an SBOM lets you instantly check which images are affected
- Compliance regulations increasingly require SBOMs for software in critical infrastructure
- Combined with signatures, SBOMs create a verifiable chain: this image contains these packages, and this CI pipeline built it
Policy as Code¶
What Is Policy as Code?¶
Instead of documenting security policies in a wiki and hoping teams follow them, policy as code defines policies as machine-readable files that are automatically enforced:
| Traditional Approach | Policy as Code |
|---|---|
| "All containers must run as non-root" (wiki page) | ClusterPolicy YAML that rejects pods with runAsNonRoot: false |
| Manual review of each deployment | Automatic admission webhook enforcement |
| Compliance checked quarterly | Compliance checked on every kubectl apply |
| Violations found after deployment | Violations blocked before deployment |
Audit vs Enforce Lifecycle¶
Policies should not go straight to enforcement. The recommended lifecycle:
1. Write policy (YAML)
|
v
2. Test locally (kyverno-cli)
|
v
3. Deploy in Audit mode
(violations logged, resources not blocked)
|
v
4. Baseline for 1-2 weeks
(review PolicyReports for false positives)
|
v
5. Fix false positives
(adjust rule conditions or create PolicyExceptions)
|
v
6. Switch to Enforce mode
(violations now block resource creation)
|
v
7. Monitor continuously
(alerts on high violation rates, exception reviews)
PolicyReports¶
Kyverno stores audit results as Kubernetes CRDs:
| CRD | Scope | What It Contains |
|---|---|---|
PolicyReport |
Namespace-scoped | Pass/fail results for resources in that namespace |
ClusterPolicyReport |
Cluster-scoped | Pass/fail results for cluster-scoped resources |
These reports are queryable via kubectl and can feed into dashboards and alerting systems.
Policy as Code + GitOps
In the RCIIS platform, Kyverno policies are stored in the GitOps repository and deployed via FluxCD. This means policy changes go through the same PR review, CI testing, and approval workflow as application code — providing a full audit trail of who changed what policy and when.
Further Reading¶
| Resource | Description |
|---|---|
| Kubernetes Documentation — Admission Controllers | Official documentation on how admission webhooks work |
| Kyverno Documentation | Full reference for Kyverno policies, rules, and configuration |
| Trivy Documentation | Trivy scanner documentation for CLI and Operator |
| Falco Documentation | Falco runtime security rules and configuration |
| Sigstore | The Sigstore project — cosign, Fulcio, Rekor |
| eBPF.io | Introduction to eBPF technology |
| NIST SBOM Guidance | NIST resources on Software Bill of Materials |
| CIS Kubernetes Benchmark | Center for Internet Security Kubernetes hardening guide |