diff --git a/.github/workflows/README.md b/.github/workflows/README.md index f2047b9..474c448 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -4,7 +4,7 @@ **File**: `update-demo-server.yml` -Automatically updates the public demo server (`pulse-relay`) when a new stable release is published. +Automatically updates the public demo server when a new stable release is published. ### Configuration Required @@ -38,11 +38,6 @@ To test without publishing a release: 2. Select `Update Demo Server` workflow 3. Click `Run workflow` (if manual trigger is enabled) -Or test manually: -```bash -ssh pulse-relay "curl -fsSL https://raw.githubusercontent.com/rcourtman/Pulse/main/install.sh | sudo bash" -``` - ### Benefits - ✅ Demo server always showcases latest stable release diff --git a/.gitignore b/.gitignore index 1819bc9..deed813 100644 --- a/.gitignore +++ b/.gitignore @@ -148,7 +148,6 @@ tmp_*.py tmp_*.sh # Experimental/abandoned features (not part of main project) -cloud-relay/ scripts/agent/ docs/internal/ claude.md diff --git a/docs/operations/audit-log-rotation.md b/docs/operations/audit-log-rotation.md new file mode 100644 index 0000000..d58867e --- /dev/null +++ b/docs/operations/audit-log-rotation.md @@ -0,0 +1,61 @@ +# Pulse Sensor Proxy Audit Log Rotation + +The sensor proxy writes a tamper-evident audit trail to +`/var/log/pulse/sensor-proxy/audit.log`. Every entry includes the SHA-256 hash +of the previous entry, so any modification becomes obvious. Because the process +keeps the file open and maintains the running hash in memory, rotation requires +special handling. + +## Rotation Strategy + +Use `logrotate` to rotate the file once it reaches 100 MB. After each rotation, +restart the proxy so it opens a new file and starts a fresh hash chain. + +Create `/etc/logrotate.d/pulse-sensor-proxy` with the following contents: + +```conf +/var/log/pulse/sensor-proxy/audit.log { + daily + size 100M + rotate 90 + compress + delaycompress + missingok + notifempty + create 0640 pulse pulse + sharedscripts + postrotate + systemctl restart pulse-sensor-proxy.service >/dev/null 2>&1 || true + endscript +} +``` + +### Why a Restart Is Mandatory + +`copytruncate` and similar tricks break the chain integrity. Restarting the +service ensures: + +1. The proxy releases the old file descriptor. +2. A new hash chain starts at sequence 1 with an all-zero `prev_hash`. + +If the proxy is not restarted, it will continue writing to the renamed file and +the rotation will have no effect. + +### Chain Continuity Across Rotations + +Each rotated log (`audit.log.1.gz`, `audit.log.2.gz`, …) is self-contained. To +prove continuity between files: + +1. After each rotation, record the final `event_hash` from the rotated file (for + example, store it in the filename or a checksum manifest). +2. When reviewing logs, verify the `prev_hash` of the first entry in the new + file is the zero hash, and reconcile the recorded final hash from the prior + file to show no entries were removed. + +Maintaining this “final hash ledger” allows auditors to stitch the rotated files +together chronologically while preserving the tamper-evident guarantees. + +### Permissions + +Adjust the `create` directive to match the user and group that run the sensor +proxy. The example assumes both user and group are `pulse`.