Date: 2026-05-11
Time: 15:41
This is an FTL2 AI-loop rule that ensures a host called "stargate" has a hardened SSH configuration and an admin user with key-based access. It follows the observe → condition → action pattern used by the FTL2 reconciliation loop: it observes current state, checks whether remediation is needed, and applies changes if the system has drifted from the desired state.
This rule is executed automatically by the FTL2 AI-loop (ftl2-ai-loop). It is not called directly by a user. The loop evaluates observe to gather state, calls condition(state) to decide whether to act, and calls action(ftl) if the condition returns True.
The observe list runs two commands on the target host:
observe = [
{"name": "admin_user", "module": "command", "params": {"cmd": "id admin"}, "host": "stargate"},
{"name": "sshd_config", "module": "command", "params": {"cmd": "cat /etc/ssh/sshd_config"}, "host": "stargate"},
]
The action function uses the ftl host accessor pattern — ftl["stargate"] — to call modules sequentially via await:
await ftl["stargate"].user(name="admin", shell="/bin/bash", create_home=True)
await ftl["stargate"].lineinfile(path="/etc/ssh/sshd_config", regexp="^#?PasswordAuthentication", line="PasswordAuthentication no")
Observe state keys:
admin_user — result of id admin; rc == 0 means user existssshdconfig — full contents of /etc/ssh/sshdconfig in stdoutCondition triggers (any one triggers action):
admin user does not exist (rc != 0)sshd_config missing PasswordAuthentication nosshd_config missing PermitRootLogin nosshd_config missing AddressFamily inetModules used in action: user, file, copy, lineinfile, service
Hardcoded values: SSH public key for ben@bthomass-mac, target host stargate, admin username admin.
admin (steps 2–3). The docstring explicitly calls this out as a race condition avoidance measure.user, file, copy, lineinfile) is idempotent — safe to re-run. The condition gate prevents unnecessary runs, but the action itself is also safe if re-triggered./etc/sudoers.d/admin rather than editing /etc/sudoers directly — the safer pattern.observe block. The file contains two observe definitions and two docstrings (from two AI-loop generations). The second observe overwrites the first at runtime; they are identical so this is benign but messy.command, user, file, copy, lineinfile, service — the standard module library called via ftl["host"].module() syntaxstargate — the host defined in FTL2 inventory that this rule managesstargate must be defined in the FTL2 inventory with SSH connectivity for the observe and action steps to reach it