Skip to main content

Licence Gitea Release pre-commit

chguard

chguard logo

chguard is a safety-first command-line tool that snapshots and restores filesystem ownership and permissions.

Think of it as a guardrail around chmod and chown: it records the current state, shows you exactly what would change, and only applies changes after explicit confirmation.

Features

Snapshots ownership and permissions

Records numeric uid, gid, and file mode for files, directories, and symbolic links.

Preview before restore

Always shows a clear, readable table of differences before applying changes. Missing paths and type mismatches are shown as skipped items because restore does not create, delete, or replace files.

Interactive confirmation

A single confirmation prompt at the end of a restore (default: No).

Dry-run mode

Preview restore operations without prompting or applying changes.

Wrapper mode (automatic snapshots)

chguard can also run as a wrapper around ownership and permission commands. In this mode, chguard automatically saves a snapshot before the command runs, so the user can easily restore the previous state if needed.

Supported commands

Wrapper mode is intentionally limited to commands that modify filesystem metadata only:

  • chown
  • chmod
  • chgrp

Other commands are rejected to avoid giving a false sense of protection.

Automatic snapshot names

Snapshots created in wrapper mode are named automatically, for example:

auto-20251230-161301

Auto-generated snapshots are visually distinguished in the output so they are easy to identify.

Scope control

Restore:

  • both ownership and permissions (default)
  • permissions only
  • ownership only

Safe by design

  • Never creates, deletes, or moves files
  • Missing files are ignored
  • New files are ignored
  • Symbolic links are handled without following their targets
  • Requires sudo only when necessary

Non-Goals

chguard deliberately does not:

  • restore deleted files
  • remove newly created files
  • track file contents or checksums
  • manage ACLs or extended attributes
  • provide full “undo” semantics

It only concerns itself with ownership and permissions.

Installation

From GuardUtils package repo

This is the preferred method of installation.

Debian/Ubuntu

1) Import the GPG key

sudo mkdir -p /usr/share/keyrings
curl -fsSL https://repo.sysmd.uk/guardutils/guardutils.gpg | sudo gpg --dearmor -o /usr/share/keyrings/guardutils.gpg

The GPG fingerprint is 0032C71FA6A11EF9567D4434C5C06BD4603C28B1.

2) Add the APT source

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/guardutils.gpg] https://repo.sysmd.uk/guardutils/debian stable main" | sudo tee /etc/apt/sources.list.d/guardutils.list

3) Update and install

sudo apt update
sudo apt install chguard

Fedora/RHEL

1) Import the GPG key

sudo rpm --import https://repo.sysmd.uk/guardutils/guardutils.gpg

2) Add the repository configuration

sudo tee /etc/yum.repos.d/guardutils.repo > /dev/null << 'EOF'
[guardutils]
name=GuardUtils Repository
baseurl=https://repo.sysmd.uk/guardutils/rpm/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://repo.sysmd.uk/guardutils/guardutils.gpg
EOF

4) Update and install

sudo dnf upgrade --refresh
sudo dnf install chguard

From PyPI

pip install chguard

From this repository

git clone https://git.sysmd.uk/guardutils/chguard.git
cd chguard/
poetry install

This installs the chguard CLI into the Poetry environment.

Usage

Save a state

chguard --save /srv/app --name app-baseline

If the path contains root-owned files, saving requires sudo.

List saved states

chguard --list

Example output:

app-baseline   /srv/app   2025-12-20 18:11:08 +00:00

Restore a state (preview only)

chguard --restore app-baseline

This shows a table of ownership and permission differences. Missing paths and type mismatches are reported as skipped items.

Restore with confirmation

chguard --restore app-baseline

You will be prompted:

Do you want to restore this state? (y/N)

The default answer is No.

Dry-run

chguard --restore app-baseline --dry-run

Restore only permissions or only ownership

chguard --restore app-baseline --permissions
chguard --restore app-baseline --owner

Remove old states

chguard --prune-states

This removes states older than the number of days set in CHGUARD_STATES_LIFE

Remove states older than N days

chguard --prune-states=14

This removes all states older than 14 days.

Remove all states

chguard --prune-states=all

Environment Variable

CHGUARD_STATES_LIFEcontrols the default number of days to keep when using chguard --prune-states.

Wrapper mode

Use -- to separate chguard arguments from the wrapped command:

chguard -- chown user:group file
chguard -- chmod 755 file
chguard -- chgrp staff file

Privilege model

chguard never escalates privileges automatically

  • Saving fails if root-owned files are present and the user is not root
  • Restoring fails if changes require elevated privileges
  • Preview and dry-run operations never require sudo

Storage

Snapshots are stored in a local SQLite database containing:

  • relative path
  • file type (file, directory, or symbolic link)
  • numeric uid / gid
  • numeric mode

Usernames and permission strings are resolved only for display.

TAB completion

Add this to your .bashrc

eval "$(register-python-argcomplete chguard)"

And then

source ~/.bashrc

pre-commit

This project uses pre-commit to run automatic formatting and security checks before each commit (Black, Bandit, and various safety checks).

To enable it:

poetry install
poetry run pre-commit install

This ensures consistent formatting, catches common issues early, and keeps the codebase clean.

Tests

Run the pytest suite with:

poetry run pytest

Support

If you find chguard useful, consider supporting its development:

Support me on Ko-fi

Metadata

Release files for chguard 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chguard 0.6.0
File Size Uploaded Provenance Actions
chguard-0.6.0.tar.gz 25.8 kB Without provenance Details for chguard-0.6.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for chguard 0.6.0
File Interpreter ABI Platform Actions
chguard-0.6.0-py3-none-any.whl Python 3 none any Details for chguard-0.6.0-py3-none-any.whl

Total release size: 51.6 kB

Release files / chguard-0.6.0.tar.gz

Download URL chguard-0.6.0.tar.gz
Size 25.8 kB
Tags Source
SHA-256 checksum
How to use checksums
447c29dfefca1f3a5675b07c8d29365c960b4e1bb3da2c827c062cd10bf0e557
BLAKE2b-256 checksum
How to use checksums
b276fb3ea3827bedc3f4baa83bfd32b8f7ed9ee6e0fa65cb4e4a97adb1d81089
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.0 CPython/3.14.7 Linux/7.2.8-100.fc43.x86_64

Release files / chguard-0.6.0-py3-none-any.whl

Download URL chguard-0.6.0-py3-none-any.whl
Size 25.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b3ec120b9e1dc59fff6433a828b065dcff2374e7ff6e2c9bfc8af1c6a9e2c47d
BLAKE2b-256 checksum
How to use checksums
358387f9ac0393d8b2480840a3aa863c2b85746feff358fd916b8c9c79e44e16
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.5.0 CPython/3.14.7 Linux/7.2.8-100.fc43.x86_64

Security for chguard 0.6.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page