Seccomp is one of the better controls Linux gives you, and almost nobody I've worked with runs it.
Here's what it does. A process talks to the kernel through system calls — open, read, connect, and a few hundred others. That syscall interface is the doorway between your application and everything the kernel can do: the filesystem, the network, other processes, the machine itself. Seccomp lets you hang a list on that doorway. These syscalls are allowed, everything else gets killed or errors out. If an attacker gets code execution inside your process, the blast radius is now bounded by that list instead of by the whole kernel. A web app that never needs to load a kernel module or reach into ptrace shouldn't be able to, even when it's compromised. That's a real reduction in what a foothold can turn into.
So it's a strong control that's cheap to run. Why is it sitting on the shelf?
To write a seccomp profile, you have to know exactly which syscalls your application makes. All of them. Not the ones in the happy path — the whole set, across every code path the app can take in production.
And that knowledge basically doesn't exist. Your app makes syscalls you've never thought about. Your language runtime makes them. The libraries you pulled in make them, and the libraries those pulled in. The garbage collector makes them. A DNS lookup on a cold cache goes down a different path than a warm one. An error handler you hit once a month reaches for something the normal path never touches. Nobody sat down and wrote a manifest of this. It's emergent behavior of a stack you assembled but didn't author line by line.
You can try to build the list by watching the app run — capture the syscalls it actually makes and turn that into a profile. That gets you the common paths. It does not get you the rare ones. The retry logic, the failover, the code that only runs when a disk fills up or a connection drops mid-write — those are exactly the paths your observation window didn't happen to cover, and exactly the ones you can't afford to guess wrong on.
Then the app changes. You upgrade a dependency, add a feature, bump the runtime a minor version, and the syscall footprint moves out from under the profile you wrote. A profile is a snapshot of behavior that keeps drifting.
Get the profile too tight and you've built a landmine. The app runs fine in test, ships, and then three weeks later hits the one edge case that needs the one syscall you left out — and seccomp does exactly what you told it to and kills the process. In production. On a path you didn't test, because if you'd tested it you'd have caught it. And now you're debugging a SIGSYS under incident pressure with no obvious way back to the state you were in an hour ago.
Get the profile too loose to be safe from that, and you've allowed everything that matters anyway. The control is on paper. It passes the audit. It stops nothing.
That's the bind. The safe-feeling version is theater, and the version that actually helps is the one that can take down prod on an edge case nobody enumerated.
The reason seccomp stays on the shelf isn't that people don't understand it. Plenty of engineers understand it fine. It's that the two things standing in the way are a knowledge problem and a reversibility problem, and neither gets solved by trying harder.
The knowledge problem wants you to stop guessing what your app does and observe what it actually does — over enough real behavior that the rare paths show up, not just the demo. The reversibility problem wants a way to tighten the profile without betting production on it: roll it out in a mode that reports what would have been blocked before it blocks anything, and be able to back it off the instant it bites.
Neither of those is exotic. But until the tightening step stops feeling like a one-way door, a control this good is going to keep losing to the risk of turning it on. That's the actual reason it's unused — not ignorance. Fear of the edge case you can't see, with nothing to catch you if you're wrong.