News

Enroll 0.7.0: stronger safety tooling and other improvements

The new release focuses on hardening Enroll's defenses against various types of attack/content injection, along with some other new features and improvements.

What Enroll is doing

  • Harvest bundles with state.json and captured artifacts.
  • Ansible manifesting in single-site mode or --fqdn multi-site mode.
  • Role grouping by package section/group where possible, with --no-common-roles available when you prefer one generated role per package or unit.
  • Remote harvesting over SSH, including OpenSSH config support, sudo prompts, and encrypted key passphrase handling.
  • Diff, explain, and validate workflows for drift reporting and bundle inspection.
  • SOPS at-rest encryption for harvest and manifest bundles.
  • JinjaTurtle integration for supported Ansible templates when the executable is available.

A current workflow

$ enroll harvest --out ./harvest
$ enroll validate ./harvest
$ enroll manifest --harvest ./harvest --out ./ansible
$ cd ./ansible
$ ansible-galaxy collection install -r requirements.yml
$ ansible-playbook -i "localhost," -c local playbook.yml --check

Security and provenance changes

Version 0.7.0 is also more explicit about trust boundaries. Enroll validates structure and tries to avoid accidental secret capture, symlink traversal, unsafe artifact paths, unsafe root output paths, and root PATH foot-guns. It still cannot prove that a harvested desired state is semantically safe to apply.

When manifesting from a harvest, you'll see a message like this:

This harvest is structurally valid, but Enroll cannot prove it is semantically safe. Only apply manifests generated from harvests whose provenance you trust.

Other notable changes

  • In 'single site' mode, Enroll now combines packages/configs into 'common' roles where the 'Section' name of that software is common. This makes Ansible faster to run, and is easier to digest cognitively (you might now get 20 roles instead of 200!). This behaviour can be disabled with --no-common-roles or when using the --fqdn mode.
  • Enroll now tries to detect Docker images on your system. This requires the docker galaxy role in Ansible. It will enforce that the specific SHA256 of that image is present (not floating tagsZ), when running Ansible.
  • Enroll now tries to detect system and user-level Flatpaks, as well as Snaps.
  • Safe-mode content scanning tolerates value-less credential words in comments, but populated credential assignments are still treated as sensitive even if commented out.
  • Automatic per-user shell dotfile harvesting is only enabled in --dangerous mode.
  • Plain directory harvests are frozen into a private temp tree before manifesting, reducing TOCTOU exposure between validation and rendering.
  • Remote harvests reject unknown SSH host keys by default.
  • Enroll now implicitly 'validates' a harvest before trying to manifest it to Ansible code.
  • Root runs refuse unsafe non-interactive PATH setups unless --assume-safe-path is supplied.
  • Enroll will not want to harvest or manifest to a directory that is writable by others. It will try to make the harvest or manifest readable only by the user that is executing the command. This is in an effort to resist tampering attacks.
  • Enroll's --enforce argument to enroll diff has been removed. Non-interactive application of manifests is considered too dangerous by the maintainer, despite all the additional hardening of the harvesting described above. If you really want to enforce the previous harvest, you can still code up an enroll manifest [...] && ansible-playbook [....] yourself when detecting that enroll diff sees changes between two harvests.