ops(infra-ops): per-host satellite keys; satellite-1 authorized on esh-nas
Satellite agents get their OWN key under the infra-ops identity instead of a copy of the fleet key, so one can be revoked by deleting a line. The list is playbooks/files/infra-ops-satellite-keys (target short hostname + public key). bootstrap-infra-ops-user.yaml now writes the fleet key plus that host's satellite keys, exactly, so a re-run keeps listed keys and removes unlisted ones. satellite-1 (SHA256:KEFUjceF...) is authorized on esh-nas only (Prime, 2026-10-13); the playbook re-run there installed both keys, and the fleet key still logs in with sudo.
This commit is contained in:
@@ -7,7 +7,8 @@
|
||||
# WHY a dedicated identity (not the agent borrowing lkraven/vh sudo):
|
||||
# - Clean audit trail — every agent action attributable to `infra-ops`,
|
||||
# separate from human accounts, with sudo I/O logging on.
|
||||
# - Revocation = pull one authorized_keys line + one sudoers file.
|
||||
# - Revocation = pull one authorized_keys line + one sudoers file. Satellite agents carry their own keys,
|
||||
# listed per host in playbooks/files/infra-ops-satellite-keys; revoke one by deleting its line and re-running.
|
||||
# - No human password ever in the agent's reach (key-gated NOPASSWD).
|
||||
#
|
||||
# RUN (operator, with YOUR sudo — infra-ops doesn't exist yet, so you bootstrap
|
||||
@@ -64,12 +65,23 @@ steps:
|
||||
sudo: true
|
||||
shell: install -d -m 700 -o {{ ops_user }} -g {{ ops_user }} /home/{{ ops_user }}/.ssh
|
||||
|
||||
- name: Install infra-ops authorized_keys (exact line, mode 600)
|
||||
# Satellite agents get their OWN keys, per host, from playbooks/files/infra-ops-satellite-keys (Prime 2026-10-13).
|
||||
- name: Stage the satellite key list
|
||||
upload:
|
||||
src: playbooks/files/infra-ops-satellite-keys
|
||||
dest: /tmp/infra-ops-satellite-keys
|
||||
mode: "0644"
|
||||
|
||||
- name: Install infra-ops authorized_keys (the fleet key + this host's satellite keys, exactly; mode 600)
|
||||
sudo: true
|
||||
shell: |
|
||||
line='{{ ops_pubkey }}'
|
||||
[ -n '{{ ssh_from }}' ] && line='from="{{ ssh_from }}" {{ ops_pubkey }}'
|
||||
printf '%s\n' "$line" > /home/{{ ops_user }}/.ssh/authorized_keys
|
||||
{ printf '%s\n' "$line"
|
||||
awk -v h="$(hostname -s)" '!/^#/ && $1==h { $1=""; sub(/^ /,""); print }' /tmp/infra-ops-satellite-keys
|
||||
} > /home/{{ ops_user }}/.ssh/authorized_keys
|
||||
rm -f /tmp/infra-ops-satellite-keys
|
||||
echo "satellite keys for $(hostname -s): $(($(wc -l < /home/{{ ops_user }}/.ssh/authorized_keys) - 1))"
|
||||
chown {{ ops_user }}:{{ ops_user }} /home/{{ ops_user }}/.ssh/authorized_keys
|
||||
chmod 600 /home/{{ ops_user }}/.ssh/authorized_keys
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# Satellite agents' own keys for the infra-ops identity, scoped PER HOST (Prime 2026-10-13).
|
||||
# Format: <target's `hostname -s`> <public key line>. playbooks/bootstrap-infra-ops-user.yaml writes the fleet key
|
||||
# plus every line here whose first field matches the target's short hostname. Nothing else survives, so a key
|
||||
# that is not listed here is removed on the next run. Revoke a satellite by deleting its line(s) and re-running
|
||||
# the playbook on those hosts. Public keys only: never put a private key in this repo.
|
||||
#
|
||||
# satellite-1: generated by Prime on his satellite machine 2026-10-13, fingerprint
|
||||
# SHA256:KEFUjceFjuIZDuVbEq3FWYHm0rzdqx9hC+wFrA5h3xc (its own comment was "infra-ops@", with no hostname).
|
||||
esh-nas ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0XLLZVTJUTgrWbMAx5exF3UDqPdi/30l/1lRo6d4bt infra-ops@satellite-1
|
||||
Reference in New Issue
Block a user