feat(manifest): add allow-listed per-netns sysctls primitive

Routing apps (a rootless VPN exit) need packet forwarding in their own
network namespace, but /proc/sys is read-only inside a rootless
container, so it can only be set at create time. Add `app.sysctls`,
allow-listed to net.ipv4.ip_forward / net.ipv6.conf.all.forwarding with
values "0"/"1", and rejected under host networking where it would change
the host. Rendered on all three create paths: podman CLI --sysctl, the
libpod spec `sysctl` map, and Quadlet `Sysctl=`. Absent by default and
not serialized when empty, so existing manifests and units are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 21:16:53 +00:00
co-authored by Claude Opus 5.5
parent 02b840f2d1
commit e42bd26ec7
8 changed files with 167 additions and 1 deletions
+4
View File
@@ -74,6 +74,7 @@ because a wrong source produces a confident wrong verdict.
| `environment` | list of string | — | `- KEY=value` pairs (static). |
| `health_check` | HealthCheck | — | `{ type, endpoint/path, interval, timeout, retries }`. `type` is free-form today; `http` is what the monitor exercises. |
| `devices` | list of string | — | Host device paths; must start with `/dev/`. |
| `sysctls` | map | — | Kernel parameters for the app's **own** network namespace (podman `--sysctl`, Quadlet `Sysctl=`). Allow-list: `net.ipv4.ip_forward`, `net.ipv6.conf.all.forwarding`; values `"0"`/`"1"`. Rejected under host networking. Needed by routing apps because rootless `/proc/sys` is read-only inside the container. |
| `interfaces` | map | — | Launch surfaces, keyed by name (`main`): `{ name, description, type, port, protocol, path }`. |
| `hooks` | LifecycleHooks | — | Allow-listed lifecycle hooks. See [Hooks](#hooks). |
| `upstream` | UpstreamSource | — | Where the app comes from, so release tooling can tell when the pin has fallen behind. See [Upstream tracking](#upstream-tracking). |
@@ -116,6 +117,9 @@ Validation (enforced at `AppManifest::validate()`):
FOWNER, NET_ADMIN, NET_BIND_SERVICE, NET_RAW, SETGID, SETUID, SYS_ADMIN).
- `network_policy` must be exactly `isolated`, `bridge`, or `host`.
- No `container:`/`ns:` network modes; devices must be `/dev/*`.
- `sysctls` keys must be on `ALLOWED_SYSCTLS` (packet forwarding only) and
need the app's own network namespace — never host networking, where they
would change the host.
- Bind-mount sources are confined to `/var/lib/archipelago` (reviewed
exceptions: the rootless podman socket and dbus).
- `derived_env` templates may only use the placeholder allow-list;