carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1# The tenant listener: systemd owns the unix socket at
2# /run/carlos/apps/<host>.sock and passes the bound fd to carlos-app@<host>
3# (sd_listen_fds — the app sees LISTEN_FDS=1 and serves on fd 3).
4#
5# Why socket activation instead of the app binding a path itself: it is the
6# simplest design that gets the PERMISSIONS right. The DynamicUser tenant
7# owns the listening process, but the file is created by root and owned by
8# carlos with mode 0600 — so the edge (user carlos) can connect and no
9# tenant can reach another tenant's socket. This closes the loopback
10# cross-talk gap that TCP Addr routes have. The alternatives all leak: a
11# tenant-bound socket is owned by an ephemeral uid the edge can't connect
12# to; umask/chmod games make it world-connectable; a shared group doesn't
13# exist for DynamicUser without inventing static accounts. Here the tenant
14# never needs path access at all — the fd arrives already bound, and the
15# socket survives service restarts, so the edge's unix dial never even sees
16# the rebind window.
17#
18# It is also the wake-on-connect half of hibernation: with the service
19# stopped (the activator's idle timeout), a connection here starts it —
20# including while the agent itself is down. The activator's edge-mediated
21# wake (systemctl start + HTTP health wait) remains the primary path
22# because it is health-gated: a broken boot becomes a clean 503 at the
23# edge, not a connect parked forever in the listen backlog.
24#
25# Enable per tenant, alongside the route:
26# systemctl enable --now carlos-app@<host>.socket
27# Apps that cannot accept an inherited listener yet keep a TCP Addr route
28# and NO socket unit — the documented fallback (with the cross-talk caveat
29# above, until the app learns LISTEN_FDS).
30
31[Unit]
32Description=CARLOS app %i socket
33
34[Socket]
35ListenStream=/run/carlos/apps/%i.sock
36SocketUser=carlos
37SocketGroup=carlos
38SocketMode=0600
39
40[Install]
41WantedBy=sockets.target
42