children
children
¶
Per-service child runners — one hardened process per supervisor service.
The supervisor used to compose every service (vault proxy, SSH signer, git gate, clearance hub, verdict server) as coroutines in a single asyncio loop. That put secret-holding code (the vault's SQLCipher session key, the signer's private keys) in the same address space as convenience services (the desktop notifier), so a bug in any of them exposed all of them.
Each service now runs in its own process, launched by the parent
supervisor via launch_child.
A child does exactly one thing:
harden_self— clear the dumpable flag, zero the core limit, lock memory — before it opens the credential store or binds a socket.- Re-read the sidecar (the parent hands it the same path), rebuild the one service it owns, and run that service's asyncio loop.
- Await
SIGTERMfrom the parent, then stop the service and exit 0.
The service classes are constructed and driven the standard way — only the process boundary is new. IPC is unchanged because every service already binds a per-container filesystem socket (or loopback port); a child in a separate process binds the identical path the container reaches.
The five children map onto the six former services: clearance owns
the hub and the desktop notifier/subscriber (they share the clearance
socket and the notifier only drives the subscriber), while verdict,
vault, signer, and gate are one service each. gate only
runs when the sidecar wired it.
SERVICE_NAMES = tuple(_RUNNERS)
module-attribute
¶
run_child(service, container_id, sidecar_path)
¶
Harden, build the one service, run it until SIGTERM; return an exit code.
The synchronous entry the supervise-child CLI verb calls via
asyncio.run. Arms the parent-death signal first (a supervisor
that dies without teardown must never strand a running child), then
loads the sidecar the parent pinned (config, not secrets), hardens
the process before the runner opens the credential store or binds
a socket — honouring the sidecar's debug-mode opt-out — then drives
the single service's lifecycle. A start failure returns
_EXIT_START_FAILED (4) so the parent can log it and carry on,
degrading one service without taking the rest down.