Universalsandboxing
Put every inbound session in its own container, before anything is known about it.
Every session is containerised on connect. Not the suspicious ones. Every one. The safe execution boundary is not something switched on once a connection starts to look bad, because by then the interesting part has already happened.
Each container comes up on one network, backend_net, which is how the session reaches the real MySQL, Redis and internal API. It is internal: nothing on it has a route to the internet or to the host. The session itself never travels over a container network. SSH reaches the shell through the Docker API, and HTTP requests enter through a helper that shares the container's network namespace and talks to 127.0.0.1. That is what makes L4 possible at all: every network can be taken away without touching the session.
This is the layer that pays for the rest of the design. It costs a container per session whether or not that session ever does anything wrong.
- Session opened by L0
- Prior
- Per-session container
- backend_net attached (internal)
Rules this layer holds to
Each of these is written down because relaxing it would be locally convenient and globally wrong.
Containerising everything has a real cost in memory and startup latency, paid on benign sessions too. This build has hard ceilings: every session shares one Docker client whose pool of 100 connections each session's stats stream holds one of for as long as it lives, so it runs out below 100 concurrent sessions; a Linux bridge network takes at most 1,023 containers; and risk state lives in one process. The HTTP gateway forwards into the sandbox on port 80, so it protects nothing until the protected application runs in the sandbox image.