| 1 | # One unit-backed CONFIG sync pass (appconfig.Sync + restart the routes whose |
| 2 | # env file actually changed) — and nothing else. Started only by |
| 3 | # carlos-adopt.path, which fires when the agent touches |
| 4 | # /data/config-sync-requested; it has no [Install] section because nothing |
| 5 | # else should ever want it. Deliberately NOT carlos-adopt.service: that unit |
| 6 | # also runs release.Pass and the canary-TTL nag, so pointing a per-config-write |
| 7 | # trigger at it would let one app's `carlos env set` cut over another app's |
| 8 | # pending release within seconds, and would nag on every write instead of |
| 9 | # hourly. Same root + hardening shape as carlos-adopt.service, which is what |
| 10 | # writing /etc/carlos/apps and restarting carlos-app@ units requires. |
| 11 | [Unit] |
| 12 | Description=carlos config sync (unit-backed routes, on agent request) |
| 13 | After=network-online.target |
| 14 | Wants=network-online.target |
| 15 | # A path unit re-triggers as often as config is written; the default start |
| 16 | # rate limit would latch this unit into start-limit-hit after a burst and then |
| 17 | # ignore every later trigger until an operator reset it. ([Unit], not |
| 18 | # [Service] — systemd moved these two keys in v230.) |
| 19 | StartLimitIntervalSec=0 |
| 20 | |
| 21 | [Service] |
| 22 | Type=oneshot |
| 23 | # CARLOS_DEPLOYMENT_BUCKET/_DIR + CARLOS_SECRETS_KEY live here. |
| 24 | EnvironmentFile=-/etc/carlos/host.env |
| 25 | ExecStart=/opt/carlos/carlos adopt --config-only |
| 26 | |
| 27 | # --- hardening --- |
| 28 | # Runs as ROOT deliberately, exactly like carlos-adopt.service: this pass |
| 29 | # writes /etc/carlos/apps and restarts instance units via systemctl. |
| 30 | # NoNewPrivileges and the syscall filter are omitted for the systemctl child; |
| 31 | # the rest applies. |
| 32 | ProtectHome=yes |
| 33 | PrivateTmp=yes |
| 34 | PrivateDevices=yes |
| 35 | ProtectClock=yes |
| 36 | ProtectHostname=yes |
| 37 | ProtectKernelTunables=yes |
| 38 | ProtectKernelModules=yes |
| 39 | ProtectKernelLogs=yes |
| 40 | RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX |
| 41 | RestrictNamespaces=yes |
| 42 | RestrictRealtime=yes |
| 43 | LockPersonality=yes |
| 44 | MemoryDenyWriteExecute=yes |
| 45 | MemoryMax=256M |
| 46 | TasksMax=64 |
| 47 | |