docs/09-privacy-security
Tuesday 17 March 2026

Privacy & Security Best Practices

This guide covers security considerations and privacy best practices when building and deploying Mau applications.

Table of Contents

Security Model

Mau’s security is built on several foundational principles:

Core Security Properties

Property Implementation Protection Against
Identity PGP public keys Impersonation, fake accounts
Authentication Digital signatures Forged content, tampering
Confidentiality PGP encryption Eavesdropping, data leaks
Integrity Cryptographic hashes Corruption, modification
Non-repudiation Signature verification Denial of authorship

Trust Model

Mau uses a web of trust model:

┌──────────────┐
│   You (A)    │──────────┐
└──────────────┘          │
       │                  │
       │ trust            │ direct
       │                  │ connection
       ▼                  ▼
┌──────────────┐    ┌──────────────┐
│  Friend (B)  │◄───│  Peer (C)    │
└──────────────┘    └──────────────┘
       │
       │ transitively
       │ trust?
       ▼
┌──────────────┐
│ Friend's     │
│ Friend (D)   │
└──────────────┘

Key principles:

  • You explicitly trust friends by adding their public keys
  • Content is verified against the friend’s key
  • No automatic trust propagation (friend-of-friend is untrusted by default)
  • Each user maintains their own trust decisions

Threat Model

What Mau Protects Against

Eavesdropping: All content is encrypted end-to-end
Impersonation: Signatures verify sender identity
Tampering: Modified content fails signature verification
Man-in-the-middle: TLS + certificate fingerprint validation
Unauthorized access: Only recipients can decrypt files
Data exfiltration: No central server to compromise

What Mau Does NOT Protect Against

Compromised endpoints: If your device is hacked, keys are exposed
Malicious recipients: Recipients can leak content after decryption
Traffic analysis: Metadata (who talks to whom) may be observable
Key compromise: Lost/stolen private keys compromise all past content
Social engineering: Users can be tricked into trusting wrong keys
Quantum computers: RSA and current PGP may be vulnerable in future

Attack Scenarios

Scenario 1: Network Attacker

  • Attack: Intercepts network traffic
  • Defense: TLS encryption + certificate pinning
  • Mitigation: Even if TLS is broken, content is PGP-encrypted

Scenario 2: Malicious Peer

  • Attack: Peer sends fake content claiming to be from Alice
  • Defense: Signature verification fails (doesn’t match Alice’s key)
  • Mitigation: Content is rejected, peer can be blocked

Scenario 3: Storage Access

  • Attack: Attacker gains read access to ~/.mau directory
  • Defense: Private key is encrypted with user’s password
  • Mitigation: Strong password required to use the key

Private Key Protection

Your private key is the crown jewel of your Mau identity. If compromised, attackers can:

  • Decrypt all your past and future messages
  • Impersonate you to your friends
  • Sign content as if it came from you

Password Security

When creating an account, the private key is encrypted with your password:

1# Strong password required
2mau init myaccount
3Password: ************  # At least 12 characters recommended

Password requirements:

  • ✅ Minimum 12 characters (20+ recommended)
  • ✅ Mix of uppercase, lowercase, numbers, symbols
  • ✅ Unique (don’t reuse from other services)
  • ✅ Consider using a password manager
  • ❌ Avoid dictionary words, personal info, patterns

Key Storage

Default location: ~/.mau/<account>/account.pgp

File permissions should be restrictive:

1# Check permissions
2ls -la ~/.mau/myaccount/account.pgp
3# Should be: -rw------- (0600) or -rw-r----- (0640)
4
5# Fix if needed
6chmod 600 ~/.mau/myaccount/account.pgp

Backup strategy:

1# Encrypted backup to external drive
2cp ~/.mau/myaccount/account.pgp /media/backup/mau-backup-$(date +%F).pgp
3
4# Or use tar with encryption
5tar czf - ~/.mau/myaccount | gpg -c > mau-backup.tar.gz.gpg

Key Rotation

If you suspect key compromise:

  1. Generate new account with fresh keys
  2. Notify friends through side channel (email, Signal, in person)
  3. Share new public key with all contacts
  4. Revoke old key (if using external keyserver)
  5. Delete old account after migration
1# Create new account
2mau init myaccount-new
3
4# Export new public key
5mau export-key myaccount-new > new-public-key.asc
6
7# Manually share with friends, then delete old account
8rm -rf ~/.mau/myaccount

File Encryption & Signing

Every file in Mau is both signed and encrypted:

Signature Verification

When receiving content, always verify the signature:

 1// Automatic verification in Mau
 2file, err := account.GetFile(friendFingerprint, "post.json")
 3if err != nil {
 4    log.Fatal(err)
 5}
 6
 7// This automatically verifies:
 8// 1. File is signed
 9// 2. Signature is valid
10// 3. Signer matches expected friend
11err = file.VerifySignature(account, friendFingerprint)
12if err != nil {
13    log.Fatal("Signature verification failed:", err)
14}

What this prevents:

  • Tampering: Modified content invalidates signature
  • Impersonation: Only friend’s private key can produce valid signature
  • Replay attacks: Signature is specific to exact file content

Recipient Control

Files are encrypted only for specified recipients:

1// Encrypt for specific friends
2recipients := []Fingerprint{
3    alice.Fingerprint(),
4    bob.Fingerprint(),
5}
6
7err := account.SaveFile("secret.json", content, recipients)

Best practices:

  • ✅ Minimize recipient list (need-to-know principle)
  • ✅ Review recipients before sharing sensitive data
  • ❌ Don’t encrypt for untrusted or unknown keys
  • ❌ Remember: recipients can always re-share after decryption

Checking Recipients

Verify who can read a file:

1recipients, err := file.Recipients(account)
2if err != nil {
3    log.Fatal(err)
4}
5
6fmt.Println("File is encrypted for:")
7for _, friend := range recipients {
8    fmt.Printf("- %s (%s)\n", friend.Name(), friend.Fingerprint())
9}

Network Security

TLS Certificate Validation

Mau uses self-signed certificates with fingerprint pinning:

1// Automatic in Mau: TLS cert must match PGP key fingerprint
2// This prevents MITM even with compromised CA

How it works:

  1. Each peer generates TLS certificate from their PGP key
  2. Certificate fingerprint must match public key fingerprint
  3. Connection rejected if mismatch detected

This prevents:

  • Certificate authority compromise
  • DNS hijacking
  • Man-in-the-middle attacks

Port Security

Default ports:

  • HTTP server: 8080 (configurable)
  • TLS: Optional (recommended in production)

Firewall configuration:

1# Allow Mau traffic
2sudo ufw allow 8080/tcp
3
4# Or restrict to specific IPs
5sudo ufw allow from 192.168.1.0/24 to any port 8080

Network Exposure

Development:

1# Localhost only (default)
2mau serve --address 127.0.0.1:8080

Production:

1# Public internet (use with TLS!)
2mau serve --address 0.0.0.0:8443 --tls

Best practices:

  • ✅ Use TLS for public servers
  • ✅ Run behind reverse proxy (nginx, Caddy) for additional security
  • ✅ Enable rate limiting to prevent DoS
  • ❌ Don’t expose debug endpoints publicly
  • ❌ Don’t run as root (use dedicated user)

Kademlia DHT Security

The DHT exposes your peer presence:

Information leaked:

  • Your public key fingerprint
  • IP address and port
  • Online/offline status
  • Approximate location (inferred from IP)

Mitigation strategies:

  • Use VPN or Tor for anonymity
  • Run multiple nodes to obfuscate activity
  • Use mDNS only for local networks
  • Disable DHT if privacy is critical:
1// Disable DHT discovery
2client := mau.NewClient(dir)
3client.DisableDHT()

Data Retention & Deletion

Secure File Deletion

Regular rm may leave data recoverable:

1# Use secure deletion (overwrites data)
2shred -u ~/.mau/myaccount/files/sensitive.json.pgp
3
4# Or on whole directory
5find ~/.mau/myaccount/files -type f -exec shred -u {} \;

In code:

1// Delete file versions too
2file, _ := account.GetFile(friendFp, "data.json")
3for _, version := range file.Versions() {
4    os.Remove(version.Path)
5}
6os.Remove(file.Path)
7
8// Optionally securely wipe
9// (requires external tool or library)

Retention Policies

Implement automatic cleanup:

 1// Delete files older than 30 days
 2cutoff := time.Now().AddDate(0, 0, -30)
 3
 4files, _ := account.ListFiles(friendFingerprint)
 5for _, file := range files {
 6    info, _ := os.Stat(file.Path)
 7    if info.ModTime().Before(cutoff) {
 8        os.Remove(file.Path)
 9    }
10}

Forward Secrecy Limitations

⚠️ Mau does not provide forward secrecy

  • If your private key is compromised, all past messages can be decrypted
  • This is a fundamental limitation of PGP-based encryption
  • Consider implementing application-level ephemeral keys for sensitive chats

Alternative for high-security needs:

  • Use Signal Protocol (ratcheting keys)
  • Implement session keys rotated regularly
  • Use Mau for discovery + exchange session keys separately

Privacy Considerations

Metadata Leakage

What’s exposed:

Network observer can see:
- You connected to peer X at time T
- File Y was transferred (size, timing)
- DHT queries reveal interests

What’s hidden:

Encrypted and not observable:
- File contents
- File names (encrypted)
- Number of recipients
- Actual relationships (who is whose friend)

Anonymity vs. Accountability

Mau prioritizes accountability over anonymity:

  • Every action is tied to a PGP key
  • Keys are pseudo-anonymous (not linked to real identity by default)
  • But friends know your key = your identity in the network

For true anonymity:

  • Use anonymous key (no name/email)
  • Access over Tor
  • Never link key to real identity
  • Rotate keys regularly

Privacy-Preserving Applications

Example: Anonymous forums

 1// Create anonymous post
 2post := map[string]interface{}{
 3    "@type": "SocialMediaPosting",
 4    "author": map[string]interface{}{
 5        "@type": "Person",
 6        "identifier": account.Fingerprint().String()[:8], // Short hash
 7        // No name, email, or identifying info
 8    },
 9    "headline": "Anonymous thought...",
10}

Example: Ephemeral messaging

1// Auto-delete after reading
2msg, _ := file.Reader(account)
3content, _ := io.ReadAll(msg)
4fmt.Println(string(content))
5
6// Delete immediately
7os.Remove(file.Path)

Security Checklist

Deployment

  • Use strong password (12+ characters, unique)
  • Set restrictive file permissions (0600 on private keys)
  • Enable TLS for public servers
  • Run service as non-root user
  • Enable firewall rules
  • Keep dependencies updated
  • Monitor logs for suspicious activity
  • Implement rate limiting
  • Set up automated backups (encrypted)
  • Document incident response plan

Development

  • Always verify signatures before processing
  • Validate file names (prevent path traversal)
  • Sanitize user input (prevent injection)
  • Use constant-time comparison for fingerprints
  • Log security events (failed auth, invalid signatures)
  • Handle errors securely (no info leakage)
  • Fuzz test file parsing code
  • Review dependencies for vulnerabilities
  • Implement key rotation mechanism
  • Add integrity checks for backups

User Education

  • Explain key backup importance
  • Warn about key sharing risks
  • Document how to verify friend keys
  • Provide key rotation instructions
  • Explain what metadata is exposed
  • Clarify forward secrecy limitations
  • Guide users on secure deletion
  • Recommend VPN/Tor for sensitive use

Advanced Topics

Auditing & Compliance

For regulated environments:

 1// Log all access
 2func AuditLog(event string, details map[string]string) {
 3    log.Printf("[AUDIT] %s: %v", event, details)
 4}
 5
 6// Track file access
 7file, err := account.GetFile(fp, name)
 8AuditLog("file_access", map[string]string{
 9    "user": account.Fingerprint().String(),
10    "peer": fp.String(),
11    "file": name,
12    "timestamp": time.Now().Format(time.RFC3339),
13})

Compliance with GDPR

If building EU-facing application:

  • Right to erasure: Implement secure deletion
  • Data portability: Provide export functionality
  • Consent: Track and honor encryption preferences
  • Transparency: Document what data is collected
 1// GDPR export
 2func ExportUserData(account *Account) error {
 3    archive := createZip()
 4    
 5    // Include all files
 6    files, _ := account.ListAllFiles()
 7    for _, file := range files {
 8        content, _ := file.Reader(account)
 9        archive.Add(file.Name(), content)
10    }
11    
12    // Include friend list
13    friends, _ := account.ListFriends()
14    archive.Add("friends.json", marshalJSON(friends))
15    
16    return archive.Save("user-data-export.zip")
17}

Vulnerability Disclosure

If you discover a security issue in Mau:

  1. Do not publicly disclose immediately
  2. Contact maintainers privately (see SECURITY.md in repo)
  3. Provide detailed reproduction steps
  4. Allow reasonable time for fix (90 days standard)
  5. Coordinate public disclosure timing

Conclusion

Security is a shared responsibility:

  • Mau provides: Strong cryptographic primitives and secure defaults
  • You must ensure: Proper key management, secure deployment, and user education
  • Users must practice: Good password hygiene, backup discipline, and cautious key sharing

Remember: The most secure system is useless if users don’t trust it. Balance security with usability, and always document the threat model clearly.

For implementation details, see: