Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for DevOps Security & Hardening By James Joyner IV · · 10 min read

Sandboxing Linux Services With Landlock and AI-Assisted Review

Landlock lets a process drop its own filesystem access at runtime. Here's how I use AI to scope a least-privilege sandbox and review the rules before they ship.

  • #security
  • #hardening
  • #linux
  • #landlock
  • #sandboxing

When I started taking process sandboxing seriously, my mental model was containers and AppArmor profiles, both of which live outside the process and require privileged setup. Landlock changed that for me. It’s a Linux LSM that lets an unprivileged process voluntarily restrict its own filesystem and network access at runtime, with no root, no policy file shipped separately, and no daemon. A web service can, on startup, declare “I only ever need to read /etc/myapp and write /var/lib/myapp,” and the kernel enforces it for the life of the process. If the service is later compromised, the attacker inherits those restrictions.

The catch is that Landlock rules are unforgiving and scope is easy to get wrong: too tight and the service crashes on a path it legitimately needs, too loose and the sandbox is decorative. Working out the minimal ruleset is patient, enumerative work, which is where I use AI as a fast junior engineer. It helps me list what the service touches and draft the ruleset; I verify every rule against the running service before trusting it. Defensive hardening only, and no secrets in the prompt.

Understand the model before you write a rule

Landlock works by creating a ruleset that defines allowed access rights on filesystem paths, then restricting the calling thread to it. After restriction, anything not explicitly allowed is denied, and restrictions can only ever be tightened, never loosened, even by the process itself. That irreversibility is the security property and the footgun at once.

I keep the AI grounded in those mechanics:

Explain Landlock’s enforcement model: rulesets, access rights, the restrict step, and the fact that it’s one-way. Then help me reason about scoping a sandbox for a service that reads config and writes a data directory. Defensive use only.

Getting the model to articulate the semantics back to me, and checking it against the kernel docs, is how I confirm we’re both reasoning from the same rules before any code gets written.

Enumerate what the service actually touches

You can’t sandbox what you haven’t inventoried. The honest way to scope is to observe the real filesystem access of the service under normal load, then allow exactly that. I trace it and feed the AI the result:

strace -f -e trace=openat,open,connect -o app.trace ./myservice --selftest

Then:

Here is a sanitized list of paths and syscalls this service touched during a normal run. Group them into read-only paths, read-write paths, and execute paths, and propose the minimal Landlock access rights for each. Flag anything that looks like it shouldn’t need access.

That last clause is a free security review: when the AI flags that the service opened /etc/shadow or reached for a socket it has no business using, that’s a finding to investigate, not just a path to allowlist. I strip real hostnames and any sensitive paths before pasting, describing structure instead.

Pro Tip: scope read and write separately and stingily. A service that reads its config and writes one data directory should get read-only rights on the config tree and read-write only on the data directory, never a blanket grant on a shared parent. The whole point is that a compromised process can’t wander, so don’t hand it the parent directory out of convenience.

Draft the ruleset, then read every line

For services that don’t have native Landlock support, a wrapper like landlock-restrict (or the landlock crate / libpsx helpers in code) applies the sandbox at launch. I have the AI draft the invocation and explain each grant:

Draft a Landlock sandbox launcher for this service: read-only on /etc/myapp and the runtime libs, read-write on /var/lib/myapp, and deny everything else. Annotate why each path is included.

I read the result as carefully as I’d read a firewall rule, because that’s effectively what it is. The bug to catch is an over-broad path that quietly defeats the sandbox, like granting read-write on /var because /var/lib/myapp was awkward to type. The AI’s annotations make over-broad grants obvious on review.

Test the failure modes deliberately

A sandbox you haven’t tested by trying to break out of it is just a hope. After applying the rules in staging, I confirm two things: the service still works for every legitimate code path, and a deliberate out-of-bounds access actually gets denied. From inside the sandboxed process context, an attempt to read a path outside the allowlist should fail with EACCES. I have the AI help me enumerate the legitimate code paths to exercise so I don’t miss the once-a-day log-rotation path that needs write access I forgot to grant. Missing a needed grant turns into a crash at the worst possible time, so coverage matters.

Combine Landlock with the rest of the sandbox

Landlock covers filesystem and some network access, but it’s one layer. The defensive posture is to stack it with the controls the rest of the toolkit covers: a seccomp profile restricting syscalls, dropped capabilities, and a non-root user. I ask the AI to review the full launch context and tell me where the layers overlap and where there are gaps, so the sandbox isn’t strong on files and wide open on syscalls. Defense in depth means no single layer is load-bearing on its own.

Make it a reviewed change, not a clever hack

Because Landlock rules are one-way and a wrong scope means an outage, these changes deserve review. I route the sandbox launcher and its ruleset through the code review dashboard so a human approves the grants with the AI’s annotations attached, rather than the model shipping a sandbox config on its own.

The reusable Linux-hardening prompts live in our prompts library, with the system-hardening set bundled in the DevOps security prompt pack. For the tracing-to-ruleset reasoning I’ve used Claude, and for inline drafting while I’m already in the service repo, Cursor is convenient.

The takeaway

Landlock gives even unprivileged services a way to drop their own access and shrink the blast radius of a compromise, with no root and no external policy file. AI makes scoping the sandbox tractable by enumerating what the service touches and drafting the minimal ruleset, while you verify every grant against the running service, test the deny paths, and own the change. Keep it defensive, keep secrets out of the prompt, scope read and write separately, and stack Landlock with seccomp and dropped capabilities rather than leaning on it alone. The rest of the security hardening category covers the seccomp, capabilities, and namespace controls that complete the picture.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.