Skip to main content

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

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

Open in Codespaces (opens in new tab)

Free GitHub account required

Walkthrough
  1. 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.

  2. 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 -A
    

    Open 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.

  3. The Falco rule in falco-rules.yaml has a defect: find the break, fix it, and run make 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.

  4. 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.

  5. Open manifests/policies/: something is missing; the other policies show the structure, write what's needed, then run make 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 get a 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:
    ./verify.sh
    If it passes, it generates a Certificate of Completion you can paste into the discussion.
  • 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

Know someone who'd enjoy this?