Govern
Audit & compliance
The difference between a log table and an audit trail: yours is verifiable by anyone, offline, without trusting Pliuz. This is your EU AI Act Article 12 evidence and your exit path.
The hash chain
Every event is chained by SHA-256 over the previous event's canonical payload, per tenant, inside append-only tables. The args that were approved are anchored by hash, so a post-hoc rewrite breaks the chain. Verify it any time:
SELECT * FROM pliuz_verify_chain(); -- or the Verify button in /auditSigned JSONL export + offline verifier
Export the chain as canonical JSONL, Ed25519-signed. Our open-source verifier recomputes the SHA-256, checks the signature against the published public key, and re-derives the whole chain — entirely offline.
# Download a signed export (headers carry signature, public key, sha256):
curl -sS -D headers.txt -o export.jsonl \
-H "Cookie: <authenticated session>" \
"https://pliuz.com/api/v1/events/export?limit=50000"
# Verify it OFFLINE — no API calls, no trust at verify time:
pip install cryptography
python verify_pliuz_export.py export.jsonl \
--public-key <X-Pliuz-Export-Public-Key> \
--signature <X-Pliuz-Export-Signature> \
--sha256 <X-Pliuz-Export-Sha256>External anchoring (against tail-truncation)
A signed chain-head receipt lets you anchor the chain outsidePliuz. Archive these receipts (a daily cron also persists them) and the verifier's --anchor-hash ties an export back to a head you captured independently — nobody can truncate or rewrite history before that point without your receipt no longer matching.
# A signed receipt of the chain head — archive it OUTSIDE Pliuz:
GET /api/v1/events/chain-head
{ "tenant_id": "...", "sequence_no": 5541,
"hash_current": "aae9b2…", "signed_at": "…",
"algorithm": "ed25519", "public_key_hex": "…", "signature": "…" }Retention & right-to-erasure
Set a per-tier retention window (POST /api/v1/tenant/retention): a daily job scrubs the raw PII columns of old approvals while keeping the chain (which holds only summaries + hashes). GDPR erasure (POST /api/v1/tenant/erase) removes a tenant's raw personal data and keeps the verifiable chain — immutability and storage-limitation coexist.