Deploy Device Protection with Ansible
Use Ansible to install Device Protection across a Linux fleet you push to over SSH. The role below picks the right package for each host, installs it with your user group token, and leaves the service enabled.
Read Install Device Protection for Linux first for the token, the packages, and the install options that every method uses. The Linux Rollout Reference covers the rest: token handling, reboots, repeat runs, and device identity.
Role layout
roles/aikido_device_protection/
├── defaults/main.yml
├── handlers/main.yml
└── tasks/main.yml
group_vars/
└── developer_workstations.yml
site.ymlSet up the role
Add the defaults
roles/aikido_device_protection/defaults/main.yml --- aikido_release_url: https://github.com/AikidoSec/safechain-internals/releases/latest/download # Reboot after installing. Off by default, see step 3. aikido_reboot: falseAdd the tasks
The first task decides whether there is anything to do, so repeat runs are cheap and never touch the token.
roles/aikido_device_protection/tasks/main.yml --- - name: Check whether Device Protection is already installed ansible.builtin.command: aikidoctl --simple register: aikido_installed changed_when: false failed_when: false - name: Install Device Protection when: aikido_installed.rc != 0 block: - name: Work out the package architecture ansible.builtin.set_fact: aikido_arch: "{{ 'arm64' if ansible_facts['architecture'] == 'aarch64' else 'amd64' }}" - name: Work out the package name ansible.builtin.set_fact: aikido_package: >- {{ 'EndpointProtection-' ~ aikido_arch ~ '.deb' if ansible_facts['os_family'] == 'Debian' else 'EndpointProtection-' ~ aikido_arch ~ '.el' ~ ansible_facts['distribution_major_version'] ~ '.rpm' }} - name: Download the package ansible.builtin.get_url: url: "{{ aikido_release_url }}/{{ aikido_package }}" dest: "/tmp/{{ aikido_package }}" mode: "0600" - name: Install the package on Debian and Ubuntu ansible.builtin.apt: deb: "/tmp/{{ aikido_package }}" environment: AIKIDO_TOKEN: "{{ aikido_token }}" no_log: true when: ansible_facts['os_family'] == 'Debian' notify: Reboot to activate Device Protection - name: Install the package on RHEL, Rocky Linux and CentOS ansible.builtin.dnf: name: "/tmp/{{ aikido_package }}" state: present environment: AIKIDO_TOKEN: "{{ aikido_token }}" no_log: true when: ansible_facts['os_family'] == 'RedHat' notify: Reboot to activate Device Protection - name: Remove the downloaded package ansible.builtin.file: path: "/tmp/{{ aikido_package }}" state: absent - name: Make sure the service is enabled and running ansible.builtin.systemd_service: name: aikido-endpoint-protection state: started enabled: trueLeave
gather_factson, the role needs it.distribution_major_versionis what selects theel9orel10build. Amazon Linux 2023 reports2023, so map it toel9if you run it.The
environmentkeyword is what hands the token to the install, andno_log: truekeeps it out of the play output.Add the reboot handler
roles/aikido_device_protection/handlers/main.yml --- - name: Reboot to activate Device Protection ansible.builtin.reboot: reboot_timeout: 600 msg: Rebooting to activate Aikido Device Protection when: aikido_reboot | boolSet
aikido_reboot: truefor hosts nobody is working on. On developer machines, leave it off and ask people to log out and back in. See When protection becomes active.Store the token in Ansible Vault
Encrypt the token for the inventory group that maps to your Aikido user group:
ansible-vault encrypt_string --name aikido_token '<your-token>'Paste the output into the group's variables:
group_vars/developer_workstations.yml --- aikido_token: !vault | $ANSIBLE_VAULT;1.1;AES256 62313365396662343061393464336163383764373764613633653634306231386433626436623361 ...Repeat per group if you use more than one user group. Each group gets its own token and its own
group_varsfile.If the token already lives in your CI secrets, read it from the controller's environment instead of committing a vaulted copy:
aikido_token: "{{ lookup('env', 'AIKIDO_TOKEN') }}".Write the playbook and run it
site.yml --- - name: Deploy Aikido Device Protection hosts: developer_workstations become: true serial: 20% roles: - aikido_device_protectionStart with a few machines, then widen:
ansible-playbook site.yml --ask-vault-pass --limit pilot ansible-playbook site.yml --ask-vault-pass
Verify the rollout
ansible developer_workstations -m command -a "aikidoctl --simple"
ansible developer_workstations -b -m command -a "systemctl is-active aikido-endpoint-protection"The devices then appear in your device list with an Active status.
Troubleshooting
| Problem | Fix |
|---|---|
| The package installs but the device never appears in the dashboard | AIKIDO_TOKEN was not set for the install command. Configuration management tools do not forward your local environment to the host, so set the variable on the task itself, then install the package again |
apt or dnf looks for the package in your repositories instead of installing the file | Pass a path, not a name: apt install ./EndpointProtection-amd64.deb. The leading ./ is what makes the package manager treat it as a local file |
| The install fails on a Red Hat-family host | Match the build to the major version: use the el9 package on version 9 and the el10 package on version 10 |
| The service is not running | Run systemctl status aikido-endpoint-protection, then sudo aikidoctl diagnostics to send us the details |
| Node.js or uv still reject the Aikido certificate | Installing sets NODE_EXTRA_CA_CERTS and UV_SYSTEM_CERTS system-wide, and running shells do not pick them up. Open a new login shell or reboot the device |
| The token shows up in run output or logs | Use your tool's redaction: no_log in Ansible, sensitive true in Chef, Sensitive() in Puppet |
| Several machines share one entry in the device list | They booted with the same /etc/machine-id. Device identity on Linux follows that file, so clear it in the image you clone from and let systemd write a fresh one on first boot |
| No tray icon appears | Expected on GNOME outside Ubuntu, and cosmetic. See Tray Icon Support on Linux |