• 0.9.0 6c90107d56

    0.9.0
    All checks were successful
    CI / test (push) Successful in 51s
    CI / test (almalinux, docker.io/library/almalinux:9, python3.11) (push) Successful in 10m53s
    CI / test (debian, docker.io/library/debian:13, python3) (push) Successful in 15m34s
    Lint / test (push) Successful in 42s
    Stable

    mig5 released this 2026-09-27 02:10:13 -05:00 | 6 commits to main since this release

    0.9.0

    Breaking changes

    • Replace manifest --fqdn with explicit --host and --extend. Standalone output still requires a new directory; multi-host extension requires metadata generated by this version.
    • Make live firewall and sysctl capture opt-in with --harvest-firewall and --harvest-sysctl on local/remote harvest and single-shot. Persistent configuration is still harvested normally. Existing bundles retain their recorded runtime snapshots.

    Changes for multi-host projects

    • Share roles when their task and handler implementations match. Keep identical artifacts in the role; promote a differing artifact into per-host inventory for all affected hosts, including later extensions. Preserve complete per-host settings and independent play order. Distinct task or handler implementations retain separate roles named after the host.
    • Generate one inventory-driven restart handler per grouped service role, so hosts with different active service lists can share the role. A notified handler restarts all active services listed for that role on that host.
    • Run APT and DNF repository configuration once, before package prerequisites, while keeping their roles selected for multi-host sharing and artifact validation.
    • Keep package, account and service activation phases out of the generated play's configuration pass. A generated role's default entry point still performs the complete role when imported independently.
    • Add hosts without retaining earlier harvests. Preserve edited host variables; refuse duplicate hosts, edited roles needed for sharing, namespace collisions and conflicting collection requirements.
    • Lock and stage extensions, detect concurrent changes, then publish with an atomic Linux directory exchange. Reject unsafe filesystem entries and unsupported atomic publication without changing existing projects.
    • Keep versioned project metadata and per-host capture notes. Support --host/--extend on manifest and single-shot; encrypted projects must be unpacked before extension.

    Security and correctness

    • Associate service packages using installed direct dependencies and shared source identity on both Debian/Ubuntu and RPM/DNF/Yum systems. Capture related configuration in the service role; use deterministic ambiguity handling and record attribution evidence. Avoid recursive dependency grouping and retain the namespace fallback when attribution is unresolved.

    • Keep independently harvested same-named services and packages in separate artifact namespaces (for example console_setup and package_console_setup), instead of aborting when package ownership inference does not associate them. Retain rejection of ambiguous normalized names within each resource type.

    • Screen Flatpak remote metadata and opted-in runtime output for secrets; prevent FIFO reads from blocking before validation.

    • Scope service handlers per role/unit, filter changed loop results, and activate symlink and systemd unit/drop-in changes.

    • Install package/account prerequisites before configuration and defer service activation until all configuration is deployed. Keep multi-host prerequisite and activation imports on the selected host-specific role. Capture unpackaged unit fragments and report executable prerequisites.

    • Preserve group GIDs and refuse conflicting identity mappings; retain additive supplementary memberships.

    • Compare DNF/firewall artifacts, directories, symlinks, images and application inventories. Observe all installed packages, including automatic dependencies.

    • Honor generated-runtime destination exclusions; fail Snap replay instead of silently dropping requested attributes.

    • Add optional firewall boot restoration with ipset-before-iptables ordering and per-run reconciliation. firewall_runtime_persist defaults to false to avoid competing with existing persistence.

    • Reject role-name collisions, reserve enroll_runtime, stage manifest publication, and refuse incompatible retained templates.

    • Always emit standalone Ansible configuration and collection requirements; synchronize modern and legacy package metadata.

    Downloads
  • 0.8.2 32bf09887a

    0.8.2
    All checks were successful
    CI / test (push) Successful in 47s
    CI / test (almalinux, docker.io/library/almalinux:9, python3.11) (push) Successful in 11m14s
    CI / test (debian, docker.io/library/debian:13, python3) (push) Successful in 16m23s
    Lint / test (push) Successful in 44s
    Stable

    mig5 released this 2026-08-03 02:36:12 -05:00 | 39 commits to main since this release

    Regression fix: Make remote harvest zipapp stdlib-only

    Lazy-load manifest, explain, and validation dependencies so the remote harvest zipapp does not require jsonschema, PyYAML, Paramiko, or other site-packages on the target host.

    Run the remote zipapp with Python isolated mode and site-packages disabled, while preserving existing CLI monkeypatch hooks.

    And some routine dependency updates.

    Downloads
  • 0.8.1 5166894992

    0.8.1
    All checks were successful
    CI / test (push) Successful in 46s
    CI / test (almalinux, docker.io/library/almalinux:9, python3.11) (push) Successful in 11m24s
    CI / test (debian, docker.io/library/debian:13, python3) (push) Successful in 15m55s
    Lint / test (push) Successful in 43s
    Stable

    mig5 released this 2026-08-03 00:54:02 -05:00 | 43 commits to main since this release

    Fix a TOCTOU in remote harvest zipapp

    Promote uploaded zipapps into a private root-owned directory before verification and execution. Copy and hash through the same pinned file descriptor, reject unsafe file types and metadata, publish atomically, and ensure sudo executes only the verified root-owned copy.

    Downloads
  • 0.8.0 5bf247c485

    0.8.0
    All checks were successful
    CI / test (push) Successful in 41s
    CI / test (almalinux, docker.io/library/almalinux:9, python3.11) (push) Successful in 9m2s
    CI / test (debian, docker.io/library/debian:13, python3) (push) Successful in 13m39s
    Lint / test (push) Successful in 39s
    Stable

    mig5 released this 2026-07-12 19:31:34 -05:00 | 47 commits to main since this release

    • Security: keep sudo-created remote harvest bundles root-owned while root packages and hashes them, expose only the archive to the authenticated SSH uid, and verify the root-computed digest after download. This removes the post-harvest tampering window created by recursively chowning the bundle before packaging without making the plaintext archive world-readable.
    • Security: enforce tar member limits while lazily parsing untrusted archives rather than after TarFile.getmembers() has already indexed the entire archive; count repeated . entries and cap remote compressed downloads as well.
    • Security: apply aggregate byte and total filesystem-entry limits when freezing directory harvest bundles, reject symlinked bundle roots, and abort when files or discovered directories change during the copy, so direct directory inputs remain bounded and fail closed under mutation.
    Downloads
  • 0.7.0 da0d8851d3

    0.7.0
    All checks were successful
    CI / test (push) Successful in 56s
    CI / test (almalinux, docker.io/library/almalinux:9, python3.11) (push) Successful in 11m59s
    CI / test (debian, docker.io/library/debian:13, python3) (push) Successful in 17m26s
    Lint / test (push) Successful in 53s
    Stable

    mig5 released this 2026-07-09 20:38:37 -05:00 | 48 commits to main since this release

    • BREAKING CHANGE: Remove the enroll diff --enforce option. Enroll no longer applies the old harvest state locally to repair drift; this avoids the risk of enforcing a potentially malicious or tampered harvest. To restore baseline state, regenerate a manifest from the trusted harvest and apply it yourself, or compare two enroll diff runs and act on the result.
    • BREAKING CHANGE: Group all package and systemd-unit roles into Debian Section/RPM Group roles by default, including managed config files and unit state. This mode is not used if --fqdn or --no-common-roles is set, in which case, the traditional behaviour of preserving one role per package/unit is used instead.
    • BREAKING CHANGE: Only capture user-specific .bashrc style files when using --dangerous mode, in case they contain sensitive env vars.
    • BREAKING CHANGE: Don't allow reading .enroll.ini in the CWD. Use only the ENROLL_CONFIG env var, an explicit --config path or else the XDG default location (or ~/.config/enroll/enroll.ini if XDG_CONFIG_HOME is not set).
    • Detect active sysctl parameters and write them to a /etc/sysctl.d/99-enroll.conf file
    • Use no_log on systemd unit interrogations to suppress potential sensitive output when applying Ansible
    • Support for detecting Docker and Podman images and enforcing their presence (by SHA256 hash).
    • Add support for detecting Flatpaks and Snaps.
    • Stricter validation of harvests to ensure that they meet the schema and don't contain unsafe artifacts (e.g symlinks pointing outside the artifact tree)
    • Perform harvest validation before trying to manifest from it.
    • Stricter validation on FQDN name in multisite mode.
    • Strict check of $PATH when running harvest as root, in case it could lead to execution of unsafe binaries during harvest. Override with --assume-safe-path for non-interactive or CI purposes.
    • Stricter validation of the destination dirs that harvest or manifest write to, to prevent writing to a different user-controlled area. Stricter permissions on the output dirs too.
    Downloads