ENFORCE AUTHORIZED_KEYS ACROSS HOSTS WITH SWAMP
This guide shows you how to make sure a list of approved SSH public keys is
installed on every host, and how to remove a retired key wherever it still
appears, using @hivemq/ssh/authorized-keys.
Prerequisites
swamp auth logincompleted- A private key that can log in to every host, stored in a Swamp vault (see
Storing Secrets). This guide uses a vault
named
ssh-keyswith the keyBASTION_KEY.
Pull the extension
swamp extension pull @hivemq/ssh/authorized-keysYou will see output like:
INF extension·pull: Pulling "@swamp/ssh"@"2026.10.13.1"
INF extension·pull: Identity verified: "@swamp/ssh"@"2026.10.13.1"
INF extension·pull: Pulled "@swamp/ssh"@"2026.10.13.1"
INF extension·pull: Extracted 14 files:Declare the hosts and keys
Create a behavior of type @hivemq/ssh/authorized-keys named bastion-keys
(see
Create and Run a Behavior).
Set state: present on keys that must be installed and state: absent on keys
that must be removed. searchPaths sets which directories are scanned for
authorized_keys files.
globalArguments:
privateKey: "${{ vault.get('ssh-keys', 'BASTION_KEY') }}"
defaultUser: root
searchPaths:
- /root/.ssh
- /home
hosts:
- name: bastion-1
address: 203.0.113.10
- name: bastion-2
address: 203.0.113.11
keys:
- name: alice
publicKey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAliceExampleKey alice@example.com"
state: present
- name: bob-old
publicKey: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBobRetiredKey bob@example.com"
state: absentReference the private key through vault.get() and never write the key body
into the definition. If a host needs a different key or user, set privateKey
or user on that host entry.
Check compliance
swamp behavior run bastion-keys verifyThis command reads every authorized_keys file under searchPaths on every
host and changes nothing. It writes a verify resource per host that reports
whether each present key is in every file and whether any absent key still
appears.
Add the approved keys
swamp behavior run bastion-keys addThis command appends each state: present key to every authorized_keys file
that lacks it and writes an addResult resource per host. Keys are matched on
algorithm and key body, and the comment is ignored, so running it again adds
nothing.
Remove the retired keys
swamp behavior run bastion-keys stripThis command removes each state: absent key from every authorized_keys file
and writes a stripResult resource per host. Each file is replaced atomically,
so it keeps its ownership and mode.
If you want each file to contain only the present keys, and any key not on the
list to be deleted, run the seal method instead of strip. seal is
destructive. Run audit first and review the audit resource it writes.
Confirm the result
swamp behavior run bastion-keys verifyThis command writes a new verify resource for each host. Every host should now
report that it complies.
To limit any of these methods to some of the hosts, pass
--input filter=<value>. See the
extensions reference for every
method and argument.