Quis Custodiet
An intruder is already inside the Republic, and the watchmen cannot see it. Fix the Praetorian Guard's broken detection rule, close the admission gap that let the intruder slip through, and seal the census archive against unauthorized access.
Mission Objective
- The Praetorian Guard awake: Falco fires an alert every time an unauthorized process reads the census archive, with live alerts streaming into the Falcosidekick UI
- The gate closed: the intruder is denied re-admission. The policy that kept privileged containers out now covers every path to unchecked host power
- The archive sealed: the census-archive secret is inaccessible to any workload that does not bear the Archivist role
- The empire-wide laws holding: all intermediate-level checks still green across every province
Key Learnings
- How Falco rules (opens in new tab) are structured: conditions, output, and kernel-level fields, and how to write a rule targeting a specific runtime behaviour
- Why
privileged: falseis not enough: how Linux capabilities (opens in new tab) grant host-level access without the privileged flag - How to use spec.variables (opens in new tab) in a
ValidatingPolicyto share reusable CEL expressions across validations - How pod volumes reference secrets, and why a volume's name and the secret it mounts are two separate fields in the pod spec
- How Falcosidekick (opens in new tab) aggregates Falco alerts and how to use its UI to watch a runtime incident in real time
Best Suited For
Security engineers and platform engineers who want to explore the boundary between admission control and runtime security. Completing the Intermediate level first is helpful but not required. You should be comfortable reading Kyverno ValidatingPolicies and CEL expressions. No prior Falco experience required.
The Story
The Republic's defences have always rested on the law: block the wrong workloads at the gate, and nothing bad gets in. But the Senate's Praetorian Guard was built for a different threat: the workload that slips through and acts badly at runtime. The Guard watches the provinces through Falco, but tonight, the watchtower is dark. Someone broke the rule that should fire when the census archive is touched. The Guard sees nothing.
And while the Guard slept, an intruder crept in. It declared valid labels, passed the census, and presented itself as a loyal citizen of the Republic. Its papers were in order. Its power was not. Once inside, it reached straight for the census archive: the imperial rolls of every citizen, sealed records it had no right to touch. It reads them on a loop and tries to send them out of the Republic.
Architecture
The estate inherits the full intermediate topology: four province namespaces (gallia, hispania, britannia, aegyptus) and one infra namespace (castra), each labelled as before. Alongside the Kyverno stack and Policy Reporter, the cluster now runs Falco (eBPF-based, as a DaemonSet) and Falcosidekick with its UI at port 30111. At startup, an intruder pod is already running in one of the provinces, quietly reading the census archive: imperial rolls that only workloads bearing the republic.rome/role: archivist label are permitted to access.
Your working directory is the challenge root. manifests/secrets/ and manifests/workloads/ are already in place. They define the estate and the intruder, and need no changes. Everything else is yours to investigate and fix.
Ready to start?
Launch in a preconfigured devcontainer
Free GitHub account required
Walkthrough
Open in GitHub Codespaces. The devcontainer is pre-configured and starts automatically. When you push from Codespaces, GitHub forks the repository to your account automatically.
Prefer working locally? Clone the repo and open it in any editor that supports the Dev Containers specification (VS Code, JetBrains IDEs, and others). The devcontainer config will be detected automatically.
When your Codespace opens, the intruder is already running. Open the Falcosidekick UI at the forwarded port 30111. It should be streaming alerts about census archive reads, but it is silent. That silence is your first clue that something is wrong with the Guard.
Start by getting oriented:
# Can you find the intruder? kubectl get pods -A # Read the Falco rule that should be firing cat falco-rules.yaml # Which policies are in force? kubectl get validatingpolicies kubectl get namespacedvalidatingpolicies -AOpen Policy Reporter at port 30110 as well. The intermediate estate should look clean: the intruder left no trace at admission. That is part of the problem.
The Falco rule in
falco-rules.yamlhas a defect: find the break, fix it, and runmake apply; alerts streaming into the Falcosidekick UI at port 30111 are your signal. The Falco condition fields reference (opens in new tab) documents every available field.The intruder passed admission: find the policy gap that let it through, close it, and run
make apply; re-admission denied and the Falcosidekick UI going quiet confirm Act 2 is done. The existing policy already uses spec.variables (opens in new tab) to share expressions across validations, a pattern worth exploring.Open
manifests/policies/: something is missing; the other policies show the structure, write what's needed, then runmake apply.Going further: even with the archive sealed at admission, any workload admitted with the Archivist role can read the secret. Kubernetes RBAC can restrict which service accounts may
geta secret at the API level, a complementary layer that admission control alone cannot provide.
Complete Your Challenge
- When you push from Codespaces, GitHub forks the repository to your account automatically. If you are working locally, fork the repository on GitHub before pushing.
- Verify your solution:
If it passes, it generates a Certificate of Completion you can paste into the discussion../verify.sh - Share your solutions in the challenge thread (opens in new tab) on community.offon.dev.
Completed the challenge? Share your achievement on LinkedIn (opens in new tab)
Toolbox
- kubectl (opens in new tab) - Apply and inspect cluster resources, check pod status and security contexts
- k9s (opens in new tab) - Explore cluster resources, pod logs, and policy reports in a terminal UI
- kyverno (opens in new tab) - Test a policy against a resource locally before applying it to the cluster