# Familiar Production Hardening Guide

**Version:** 1.0  
**Last Updated:** January 31, 2026  
**Audience:** System Administrators, DevOps, Security Engineers

---

## Overview

This guide provides a checklist and detailed instructions for hardening an Familiar deployment. Follow these steps before exposing Familiar to users or processing sensitive data.

**Hardening Levels:**

| Level | Use Case | Time Required |
|-------|----------|---------------|
| **Essential** | Any production deployment | 30 minutes |
| **Recommended** | Multi-user or external-facing | 1-2 hours |
| **Maximum** | Regulated industries (healthcare, finance) | 2-4 hours |

---

## Quick Checklist

Print this and check off each item:

### Essential (Required)

```
[ ] 1.1  Running as non-root user
[ ] 1.2  API keys in environment variables (not config)
[ ] 1.3  .env file permissions set to 600
[ ] 1.4  Firewall enabled
[ ] 1.5  Systemd service configured
[ ] 1.6  Log rotation configured
```

### Recommended (Production)

```
[ ] 2.1  Encryption at rest enabled
[ ] 2.2  PII redaction enabled
[ ] 2.3  Fail2ban installed
[ ] 2.4  Automatic security updates enabled
[ ] 2.5  Backup procedure implemented
[ ] 2.6  Monitoring/alerting configured
[ ] 2.7  SSH key-only authentication
```

### Maximum Security (Regulated)

```
[ ] 3.1  Security mode set to 'paranoid'
[ ] 3.2  Network egress restricted
[ ] 3.3  Audit log retention set (6+ years)
[ ] 3.4  Session timeout configured
[ ] 3.5  Local LLM for sensitive data
[ ] 3.6  Full disk encryption enabled
[ ] 3.7  Intrusion detection configured
```

---

## 1. Essential Hardening

### 1.1 Non-Root User

**Why:** Limits damage if the application is compromised.

Familiar should run as a dedicated user with minimal privileges:

```bash
# Create dedicated user (if not done by installer)
sudo useradd --system --shell /bin/bash --home-dir /opt/familiar --create-home familiar

# Verify service runs as this user
grep "User=" /etc/systemd/system/familiar.service
# Should show: User=familiar
```

**Verify:**
```bash
ps aux | grep familiar
# Should show 'familiar' user, NOT 'root'
```

### 1.2 Environment Variables for Secrets

**Why:** Prevents accidental exposure in logs, version control, or backups.

Move all secrets to `.env`:

```bash
# Check that config.yaml has NO secrets
grep -i "api_key\|token\|secret\|password" /opt/familiar/.familiar/config.yaml
# Should return nothing
```

Ensure `.env` contains:
```bash
# /opt/familiar/.familiar/.env
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...
TELEGRAM_BOT_TOKEN=...
DISCORD_BOT_TOKEN=...
FAMILIAR_WEBHOOK_SECRET=...
FAMILIAR_ENCRYPTION_KEY=...
```

### 1.3 File Permissions

**Why:** Prevents unauthorized access to secrets.

```bash
# Set restrictive permissions
sudo chmod 600 /opt/familiar/.familiar/.env
sudo chmod 640 /opt/familiar/.familiar/config.yaml
sudo chmod 700 /opt/familiar/.familiar
sudo chown -R familiar:familiar /opt/familiar/.familiar

# Verify
ls -la /opt/familiar/.familiar/
# .env should be -rw------- (600)
```

### 1.4 Firewall Configuration

**Why:** Limits network attack surface.

```bash
# Enable UFW
sudo ufw enable

# Default deny incoming
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH (adjust port if needed)
sudo ufw allow ssh

# If dashboard is enabled, restrict to local network
sudo ufw allow from 192.168.0.0/16 to any port 8080 comment 'Familiar Dashboard - LAN only'

# Verify
sudo ufw status verbose
```

**Expected output:**
```
Status: active
Default: deny (incoming), allow (outgoing), disabled (routed)

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
8080                       ALLOW IN    192.168.0.0/16
```

### 1.5 Systemd Service

**Why:** Ensures proper startup, restart on failure, and resource limits.

The service file should include security directives:

```ini
# /etc/systemd/system/familiar.service

[Service]
User=familiar
Group=familiar

# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths=/var/lib/familiar /var/log/familiar /opt/familiar/.familiar

# Resource limits
MemoryMax=1G
CPUQuota=80%
```

Apply changes:
```bash
sudo systemctl daemon-reload
sudo systemctl restart familiar
```

### 1.6 Log Rotation

**Why:** Prevents disk exhaustion; manages log retention.

```bash
# Create logrotate config
sudo tee /etc/logrotate.d/familiar << 'EOF'
/var/log/familiar/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 640 familiar familiar
    sharedscripts
    postrotate
        systemctl reload familiar > /dev/null 2>&1 || true
    endscript
}
EOF

# Test configuration
sudo logrotate -d /etc/logrotate.d/familiar
```

---

## 2. Recommended Hardening

### 2.1 Encryption at Rest

**Why:** Protects data if storage media is stolen or improperly disposed.

Generate encryption key:
```bash
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
```

Add to `.env`:
```bash
FAMILIAR_ENCRYPTION_KEY=<generated-key>
```

Enable in config:
```yaml
# config.yaml
security:
  encrypt_sessions: true
  encrypt_memory: true
  encrypt_history: true
  encryption_key_env: FAMILIAR_ENCRYPTION_KEY
```

**Important:** Back up this key securely. Lost key = lost data.

### 2.2 PII Redaction

**Why:** Reduces exposure of sensitive data in logs.

```yaml
# config.yaml
observability:
  pii_redaction: true
```

This redacts:
- API keys (`sk-ant-...` → `[REDACTED_API_KEY]`)
- Credit card numbers
- Social Security numbers
- Passwords in URLs/strings

### 2.3 Fail2ban

**Why:** Blocks brute-force attempts.

```bash
# Install
sudo apt install fail2ban

# Configure SSH protection
sudo tee /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
EOF

# Start
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Verify
sudo fail2ban-client status sshd
```

### 2.4 Automatic Security Updates

**Why:** Ensures critical patches are applied promptly.

```bash
# Install unattended-upgrades
sudo apt install unattended-upgrades

# Enable automatic security updates
sudo dpkg-reconfigure -plow unattended-upgrades

# Verify configuration
cat /etc/apt/apt.conf.d/20auto-upgrades
```

Should show:
```
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
```

### 2.5 Backup Procedure

**Why:** Enables recovery from data loss or corruption.

Create backup script:
```bash
sudo tee /opt/familiar/backup.sh << 'EOF'
#!/bin/bash
set -e

BACKUP_DIR="/var/backups/familiar"
DATE=$(date +%Y%m%d-%H%M%S)
BACKUP_FILE="$BACKUP_DIR/familiar-$DATE.tar.gz"

mkdir -p "$BACKUP_DIR"

# Stop service for consistent backup
systemctl stop familiar

# Create backup
tar -czf "$BACKUP_FILE" \
    /opt/familiar/.familiar \
    /var/lib/familiar

# Restart service
systemctl start familiar

# Keep only last 30 days
find "$BACKUP_DIR" -name "familiar-*.tar.gz" -mtime +30 -delete

echo "Backup created: $BACKUP_FILE"
EOF

sudo chmod +x /opt/familiar/backup.sh
```

Schedule daily backup:
```bash
echo "0 2 * * * root /opt/familiar/backup.sh >> /var/log/familiar-backup.log 2>&1" | sudo tee /etc/cron.d/familiar-backup
```

**Test restore procedure:**
```bash
# Stop service
sudo systemctl stop familiar

# Restore from backup
sudo tar -xzf /var/backups/familiar/familiar-YYYYMMDD-HHMMSS.tar.gz -C /

# Start service
sudo systemctl start familiar
```

### 2.6 Monitoring & Alerting

**Why:** Detects issues before they become incidents.

**Option A: Simple monitoring with systemd**

```bash
# Check service health
systemctl is-active familiar

# Watch for failures
journalctl -u familiar -f
```

**Option B: Prometheus + Grafana**

Add to config.yaml:
```yaml
observability:
  metrics_enabled: true
  metrics_port: 9090
```

**Option C: Log-based alerting**

Create alert script:
```bash
sudo tee /opt/familiar/alert-check.sh << 'EOF'
#!/bin/bash

# Check for errors in last hour
ERRORS=$(grep -c "ERROR\|CRITICAL" /var/log/familiar/familiar.log 2>/dev/null || echo 0)

if [ "$ERRORS" -gt 10 ]; then
    echo "ALERT: $ERRORS errors in Familiar logs" | mail -s "Familiar Alert" admin@example.com
fi

# Check service status
if ! systemctl is-active --quiet familiar; then
    echo "ALERT: Familiar service is not running" | mail -s "Familiar Down" admin@example.com
fi
EOF

sudo chmod +x /opt/familiar/alert-check.sh

# Run every 15 minutes
echo "*/15 * * * * root /opt/familiar/alert-check.sh" | sudo tee /etc/cron.d/familiar-alerts
```

### 2.7 SSH Key-Only Authentication

**Why:** Eliminates password brute-force attacks.

```bash
# Generate key on your local machine (if needed)
ssh-keygen -t ed25519 -C "familiar-admin"

# Copy to server
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@familiar-server

# Disable password authentication
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config

# Restart SSH
sudo systemctl restart sshd
```

**Verify:**
```bash
grep PasswordAuthentication /etc/ssh/sshd_config
# Should show: PasswordAuthentication no
```

---

## 3. Maximum Security Hardening

### 3.1 Paranoid Security Mode

**Why:** Minimizes risk for highly sensitive environments.

```yaml
# config.yaml
agent:
  security_mode: paranoid
  
  # Limit agent capabilities
  max_iterations: 5
  max_tokens: 1024
  
  # Strict sandboxing
  sandboxed_directories:
    - /var/lib/familiar/sandbox
    # Remove home directory access

resilience:
  # Strict cost controls
  max_cost_per_request: 0.10
  max_cost_per_day: 1.00
```

### 3.2 Network Egress Restrictions

**Why:** Limits data exfiltration paths.

```bash
# Allow only specific outbound destinations
sudo ufw default deny outgoing

# Allow DNS
sudo ufw allow out 53/udp

# Allow HTTPS to specific hosts
sudo ufw allow out to 104.18.0.0/16 port 443 comment 'Anthropic API'
sudo ufw allow out to 13.107.0.0/16 port 443 comment 'OpenAI API (Azure)'

# Allow NTP
sudo ufw allow out 123/udp

# Reload
sudo ufw reload
```

**Alternative: Use a proxy**
```yaml
# config.yaml
network:
  proxy: http://your-proxy:8080
```

### 3.3 Extended Audit Retention

**Why:** HIPAA requires 6 years; other regulations vary.

```yaml
# config.yaml
observability:
  log_retention_days: 2190  # 6 years
```

Update logrotate:
```bash
sudo tee /etc/logrotate.d/familiar << 'EOF'
/var/log/familiar/*.log {
    daily
    rotate 2190
    compress
    delaycompress
    missingok
    notifempty
    create 640 familiar familiar
}
EOF
```

**Storage consideration:** 6 years of logs requires significant storage. Consider:
- Log shipping to S3/GCS with lifecycle policies
- Compression (enabled by default)
- External log aggregation

### 3.4 Session Timeout

**Why:** Limits window for session hijacking.

```yaml
# config.yaml
security:
  session_timeout_minutes: 15  # Auto-logout after 15 min inactivity
  require_reauth_for_sensitive: true  # Re-confirm for high-risk actions
```

### 3.5 Local LLM for Sensitive Data

**Why:** PHI/PII never leaves your network.

Install Ollama:
```bash
curl -fsSL https://ollama.com/install.sh | sh
ollama pull llama3.2:8b-q4
```

Configure hybrid routing:
```yaml
# config.yaml
llm:
  default_provider: ollama
  ollama_model: llama3.2:8b-q4
  ollama_base_url: http://localhost:11434
  
  # Optional: Use cloud for non-sensitive tasks
  # fallback_provider: anthropic
```

### 3.6 Full Disk Encryption

**Why:** Protects data if device is stolen.

**Raspberry Pi with LUKS:**
```bash
# This must be done during OS installation or with careful planning
# See: https://rpi-developer.io/pi-full-disk-encryption/

# For existing installations, consider encrypting just the data partition:
sudo cryptsetup luksFormat /dev/sda2  # DATA PARTITION ONLY
sudo cryptsetup open /dev/sda2 familiar-data
sudo mkfs.ext4 /dev/mapper/familiar-data
sudo mount /dev/mapper/familiar-data /var/lib/familiar
```

**Server with LUKS:**
Most server OS installers support full disk encryption during installation.

### 3.7 Intrusion Detection

**Why:** Detects unauthorized access attempts.

**Install AIDE (file integrity monitoring):**
```bash
sudo apt install aide

# Initialize database
sudo aideinit

# Schedule daily checks
echo "0 5 * * * root /usr/bin/aide --check" | sudo tee /etc/cron.d/aide
```

**Install rkhunter (rootkit detection):**
```bash
sudo apt install rkhunter

# Update and scan
sudo rkhunter --update
sudo rkhunter --check --skip-keypress
```

---

## 4. Verification

### 4.1 Security Scan

Run these checks after hardening:

```bash
#!/bin/bash
echo "=== Familiar Security Verification ==="

echo -n "1. Running as non-root: "
if ps aux | grep -v grep | grep familiar | grep -q "^familiar"; then
    echo "PASS"
else
    echo "FAIL"
fi

echo -n "2. .env permissions (600): "
if [ "$(stat -c %a /opt/familiar/.familiar/.env)" = "600" ]; then
    echo "PASS"
else
    echo "FAIL"
fi

echo -n "3. Firewall enabled: "
if sudo ufw status | grep -q "Status: active"; then
    echo "PASS"
else
    echo "FAIL"
fi

echo -n "4. No secrets in config.yaml: "
if ! grep -qiE "sk-ant|sk-[a-z]|api_key.*=" /opt/familiar/.familiar/config.yaml 2>/dev/null; then
    echo "PASS"
else
    echo "FAIL - Found potential secrets"
fi

echo -n "5. SSH password auth disabled: "
if grep -q "PasswordAuthentication no" /etc/ssh/sshd_config; then
    echo "PASS"
else
    echo "WARN - Password auth may be enabled"
fi

echo -n "6. Service has security directives: "
if grep -q "NoNewPrivileges=true" /etc/systemd/system/familiar.service; then
    echo "PASS"
else
    echo "FAIL"
fi

echo -n "7. Log rotation configured: "
if [ -f /etc/logrotate.d/familiar ]; then
    echo "PASS"
else
    echo "FAIL"
fi

echo -n "8. Encryption at rest enabled: "
if grep -q "encrypt_sessions: true" /opt/familiar/.familiar/config.yaml 2>/dev/null; then
    echo "PASS"
else
    echo "WARN - Not enabled"
fi
```

### 4.2 Penetration Testing Checklist

If conducting a security assessment:

```
[ ] Port scan shows only expected ports (22, optionally 8080)
[ ] SSH rejects password authentication
[ ] No sensitive data in application logs (check PII redaction)
[ ] Path traversal attempts blocked (try ../../../etc/passwd)
[ ] Shell injection attempts blocked (try `whoami` or $(id))
[ ] API endpoints require authentication
[ ] Rate limiting prevents abuse
[ ] Session tokens are sufficiently random
[ ] Encryption keys not exposed in memory dumps
```

---

## 5. Ongoing Maintenance

### 5.1 Weekly Tasks

- [ ] Review security alerts/logs
- [ ] Check for failed login attempts
- [ ] Verify backups completed
- [ ] Check disk space

### 5.2 Monthly Tasks

- [ ] Apply OS security updates
- [ ] Update Familiar to latest patch version
- [ ] Review user trust levels
- [ ] Test backup restoration
- [ ] Review firewall rules

### 5.3 Quarterly Tasks

- [ ] Rotate API keys
- [ ] Rotate encryption keys (re-encrypt data)
- [ ] Review access permissions
- [ ] Audit log review
- [ ] Update this hardening checklist

### 5.4 Annual Tasks

- [ ] Full security assessment
- [ ] Penetration test (if applicable)
- [ ] Disaster recovery test
- [ ] Review and update incident response plan
- [ ] Security training refresh

---

## Appendix: Quick Commands Reference

```bash
# Service management
sudo systemctl start familiar
sudo systemctl stop familiar
sudo systemctl restart familiar
sudo systemctl status familiar

# View logs
sudo journalctl -u familiar -f
tail -f /var/log/familiar/familiar.log

# Check configuration
cat /opt/familiar/.familiar/config.yaml

# Firewall status
sudo ufw status verbose

# Backup manually
sudo /opt/familiar/backup.sh

# Check disk usage
df -h /var/lib/familiar
du -sh /var/log/familiar

# Update Familiar
cd /opt/familiar/familiar
sudo -u familiar git pull
sudo -u familiar /opt/familiar/venv/bin/pip install -r requirements.txt
sudo systemctl restart familiar
```

---

## Document History

| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2026-01-31 | Initial release |

---

*This guide complements the Security Whitepaper. For threat model and architecture details, see SECURITY_WHITEPAPER.md.*
