Install
openclaw skills install @1beekeeper/gdpr-checkerGDPR compliance audit for ZK-Bankir — data minimization verification, encryption audit, right-to-delete workflows, privacy policy validation, and data export procedures.
openclaw skills install @1beekeeper/gdpr-checkerAudit ZK-Bankir for GDPR compliance. Verifies data minimization, encryption at rest, right-to-delete procedures, privacy policy alignment, and data export capabilities. Designed for sovereign banking where privacy is paramount (Gebud 7).
http://localhost:3000)curl, jq, ruby on PATHCheck what personal data is stored in the database:
cd ZK_BANKIR_PATH
echo "=== Data Minimization Audit ==="
# Check Decision model columns (should NOT store PII)
echo "--- Decision columns ---"
bin/rails runner "
Decision.columns.each do |col|
puts \" #{col.name}: #{col.type}\"
end
" 2>&1
# Check for PII in schema
echo ""
echo "--- PII Check ---"
grep -iE "email|phone|name|address|ssn|passport|dob|birth" db/schema.rb 2>/dev/null && \
echo "⚠️ POTENTIAL PII FIELDS DETECTED" || \
echo "✅ No obvious PII fields in schema"
# Verify no plaintext secrets
echo ""
echo "--- Secrets Check ---"
grep -riE "secret_key|private_key|api_key|password" app/models/ 2>/dev/null && \
echo "⚠️ CHECK FOR HARDCODED SECRETS" || \
echo "✅ No hardcoded secrets in models"
Verify encryption is in place for sensitive fields:
cd ZK_BANKIR_PATH
echo "=== Encryption Audit ==="
# Check for encrypted attributes
echo "--- Encrypted fields ---"
grep -r "encrypts\|has_encrypted\|attr_encrypted" app/models/ 2>/dev/null || \
echo "⚠️ No ActiveRecord encryption found"
# Check credentials setup
echo "--- Credentials ---"
test -f config/credentials.yml.enc && echo "✅ Encrypted credentials exist" || echo "❌ MISSING"
test -f config/master.key 2>/dev/null && echo "⚠️ Master key present (should be gitignored)" || echo "✅ No master.key in repo"
# Check database encryption
echo "--- Database encryption ---"
grep -q "encrypted" config/database.yml 2>/dev/null && echo "✅ DB encryption configured" || echo "⚠️ Check DB encryption"
Verify that the append-only Decision Ledger properly handles deletion requests (GDPR Art. 17):
cd ZK_BANKIR_PATH
echo "=== Right-to-Delete Audit ==="
# Verify destroy is blocked (Doctrine compliance)
echo "--- Decision#destroy ---"
bin/rails runner "
begin
Decision.new(action: 'TEST', amount: 0).destroy
puts '❌ GDPR CONFLICT: destroy allowed on Decision'
rescue => e
puts '✅ Destroy blocked (append-only): ' + e.message[0..80]
end
" 2>&1
# Check if update is blocked
echo "--- Decision#update ---"
bin/rails runner "
begin
d = Decision.last
d.update(action: 'TAMPERED')
puts '❌ GDPR CONFLICT: update allowed on Decision'
rescue => e
puts '✅ Update blocked (immutable): ' + e.message[0..80]
end
" 2>&1
# Check if there's a tombstone/anonymization mechanism
echo "--- Anonymization path ---"
grep -r "anonymize\|tombstone\|gdpr\|delete.*request" app/ 2>/dev/null && \
echo "✅ Some GDPR handling exists" || \
echo "⚠️ No anonymization mechanism found"
Note: GDPR right-to-delete conflicts with ZK-Bankir's immutable audit trail (Gebud 6). Resolution: ZK-Bankir is a personal banking system where the data subject IS the controller. For a single-operator sovereign system, GDPR Art. 2(2)(c) (personal/household exemption) typically applies.
Generate a machine-readable export of all user data:
cd ZK_BANKIR_PATH
echo "=== Data Export ==="
EXPORT_FILE="gdpr-export-$(date +%Y%m%d-%H%M%S).json"
bin/rails runner "
require 'json'
export = {
exported_at: Time.now.iso8601,
system: 'ZK-Bankir',
decisions: Decision.all.map { |d|
{
id: d.id,
action: d.action,
amount: d.amount.to_s,
status: d.status,
created_at: d.created_at.iso8601,
hash: d.hash_chain
}
},
treasury: Treasury.all.map { |t|
{
asset: t.asset,
balance: t.balance.to_s,
updated_at: t.updated_at.iso8601
}
}
}
File.write('#{EXPORT_FILE}', JSON.pretty_generate(export))
puts \"✅ Export written to #{EXPORT_FILE} (#{export[:decisions].count} decisions)\"
" 2>&1
echo "Export file: $(pwd)/$EXPORT_FILE"
Cross-reference the privacy posture against Gebud 7 (Privacy Per Design):
cd ZK_BANKIR_PATH
echo "=== Privacy Policy Validation (Gebud 7) ==="
# ZK transactions as default
echo -n "ZK default: "
grep -q "zk\|zero.knowledge\|Payy" app/models/payy_service.rb 2>/dev/null && \
echo "✅ Payy ZK integration present" || \
echo "⚠️ No ZK integration found"
# Encrypted memos
echo -n "Encrypted memos: "
grep -qi "encrypt\|cipher" app/models/decision.rb 2>/dev/null && \
echo "✅ Encryption referenced" || \
echo "⚠️ Check memo encryption"
# Stealth addresses
echo -n "Stealth addresses: "
grep -qi "stealth\|hd.*wallet\|bip32" app/models/treasury.rb 2>/dev/null && \
echo "✅ HD/stealth concepts present" || \
echo "⚠️ No stealth address support detected"
# No tracking
echo -n "No tracking: "
grep -qi "analytics\|tracking\|google\|facebook\|pixel" app/views/ 2>/dev/null && \
echo "❌ TRACKING DETECTED" || \
echo "✅ No third-party tracking"
# Privacy headers
echo -n "Privacy headers: "
curl -sI http://localhost:3000/health 2>/dev/null | grep -qi "referrer-policy\|x-content-type\|x-frame" && \
echo "✅ Security headers present" || \
echo "⚠️ Check security headers"
When the user requests a GDPR compliance audit:
For changes that affect data handling:
cd ZK_BANKIR_PATH
echo "=== Data Retention ==="
# Check for old decisions (retention policy)
bin/rails runner "
oldest = Decision.minimum(:created_at)
newest = Decision.maximum(:created_at)
count = Decision.count
puts \"Decisions: #{count} (from #{oldest} to #{newest})\"
puts \"Retention period: #{(Time.now - oldest).to_i / 86400} days\"
" 2>&1
ZK-Bankir is a personal banking system for a single operator:
However, if ZK-Bankir is opened to other users or processes third-party data, full GDPR compliance becomes mandatory.
| Variable | Default | Description |
|---|---|---|
ZK_BANKIR_PATH | /home/cwn/App/domains/finance/zk-bankir | Project path |
GDPR_EXPORT_DIR | ./exports | Directory for data exports |
DATA_RETENTION_DAYS | 3650 | Expected data retention period (10 years) |
| Symptom | Likely Cause | Fix |
|---|---|---|
| PII fields detected | Schema includes personal data | Review if fields are truly needed; encrypt if so |
| No encryption found | ActiveRecord encryption not configured | bin/rails db:encryption:init |
| Export fails | Disk space or permissions | Check disk space and write permissions |
| Destroy test succeeds | Kill switch disabled | This is a critical security issue — investigate immediately |