Update README
This commit is contained in:
204
README.md
204
README.md
@@ -0,0 +1,204 @@
|
||||
[](https://git.sysmd.uk/guardutils/chguard/src/branch/main/LICENCE)
|
||||
[](https://git.sysmd.uk/guardutils/chguard/releases)
|
||||
[](https://git.sysmd.uk/guardutils/chguard/src/branch/main/.pre-commit-config.yaml)
|
||||
|
||||
# chguard
|
||||
|
||||
**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 and directories.
|
||||
|
||||
### Preview before restore
|
||||
Always shows a clear, readable table of differences before applying changes.
|
||||
|
||||
### 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.
|
||||
|
||||
### 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 skipped entirely
|
||||
* 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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
## 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 or directory)
|
||||
* numeric uid / gid
|
||||
* numeric mode
|
||||
|
||||
Usernames and permission strings are resolved only for display.
|
||||
|
||||
## pre-commit
|
||||
This project uses [**pre-commit**](https://pre-commit.com/) 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.
|
||||
|
||||
Reference in New Issue
Block a user