The most important warning
When manifesting, Enroll prints:
This harvest is structurally valid, but Enroll cannot prove it is semantically safe.
Only apply manifests generated from harvests whose provenance you trust.
Validation checks shape and consistency. It does not prove the captured configuration is a good idea, that service files are benign, or that the host was not already compromised.
Default secret avoidance
In normal mode, Enroll uses path deny-lists, symlink-safe file opening, file size limits, binary detection, and sampled content sniffing to avoid likely secrets and noisy data.
Safe-mode scanning treats common credential-looking assignments as sensitive, including password/pass/passwd/pwd/pw forms, API keys, auth tokens, client secrets, secret keys, cloud access key names, service-account key names, and similar patterns.
--dangerous
--dangerous disables likely-secret checks. It may copy private keys, TLS key material, tokens, passwords, cloud credentials, and user shell dotfiles into the harvest in plaintext.
Use it only when you intentionally want an aggressive disaster-recovery snapshot and you already know how the output will be protected.
SOPS is storage-at-rest protection
--sops writes encrypted .tar.gz.sops bundles for harvest and manifest outputs. It is not the same as generating Ansible Vault or SOPS-managed inventory variables.
enroll harvest --out ./secure-harvest --dangerous --sops <GPG_FINGERPRINT>
enroll manifest --harvest ./secure-harvest/harvest.tar.gz.sops \
--out ./secure-manifest --sops <GPG_FINGERPRINT>Decrypt and extract an encrypted manifest before running Ansible.
Filesystem and rendering hardening
- Plaintext harvest/manifest output directories are created private and are refused when unsafe or unexpectedly pre-existing.
- Root-run output refuses parent directories controlled by unprivileged users, except safe sticky boundaries such as
/tmpwith further child checks. - Source and artifact reads use no-follow semantics and reject symlinked components, non-regular files, hardlinks, and unexpected large inputs.
- Directory harvests are frozen into a private temporary copy before validation and rendering to avoid post-validation swaps.
- Tar/SOPS/remote inputs are extracted through safe extraction rules.
- Harvested strings that look like Jinja are emitted as Ansible
!unsafedata, while generated task scaffolding only accepts strict Enroll-controlled tokens.
- Harvest in normal mode first.
- Run
enroll explainandenroll validate. - Use targeted
--include-pathinstead of broad--dangerouswhere possible. - Encrypt outputs if they may contain sensitive data or leave the host.
- Run Ansible with
--check --diffand review before applying.
When run as root, Enroll checks PATH for empty, relative, current-directory, or group/world-writable entries that could cause host tools to resolve to attacker-controlled binaries.
Use --assume-safe-path only in trusted automation where the PATH is intentional.
- Proving harvested config is semantically safe
- Protecting against a fully compromised root account
- Guaranteeing generated Ansible is an ideal long-term design
- Secret management after you intentionally disable safety checks