# Styrene Backend Deployment Examples

This directory contains production-ready deployment artifacts for the Styrene backend RPC services.

## Contents

### Configuration Files

- **`auth.yaml`** - Authorization configuration template
  - Define authorized operator identities
  - Set permissions per identity (status_request, exec, reboot, update_config)
  - Configure command allowlist and security settings

### Service Files

- **`styrene-device-agent.py`** - Device agent service (headless RPC server)
  - Runs on remote devices
  - Handles RPC commands from authorized operators
  - Authorization enforcement with audit logging

- **`styrene-agent.service`** - Systemd service unit file
  - Automatic startup on boot
  - Restart on failure
  - Security hardening (restricted permissions, resource limits)

### Smoke Tests

- **`test_authorization.py`** - Verify authorization is working
  - Tests that unauthorized access is denied
  - Verifies authorized users can execute commands

- **`test_status.py`** - Verify status requests work
  - Queries device uptime, IP, disk usage, services
  - Validates response format and content

- **`test_exec.py`** - Verify command execution works
  - Tests echo command with various arguments
  - Validates exit codes and output capture

## Quick Start

### 1. Device Setup

On the target device:

```bash
# Install dependencies
pip install -r requirements.txt

# Create config directory
mkdir -p ~/.config/styrene-bond-rpc

# Copy and customize auth config
cp auth.yaml ~/.config/styrene-bond-rpc/
nano ~/.config/styrene-bond-rpc/auth.yaml  # Add operator identity hashes

# Get device identity hash (add to operator's device list)
rnstatus -i

# Test run (foreground)
./styrene-device-agent.py

# For production, install as systemd service:
sudo cp styrene-agent.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable styrene-agent
sudo systemctl start styrene-agent

# Check logs
sudo journalctl -u styrene-agent -f
```

### 2. Operator Setup

On operator workstation:

```bash
# Install styrene package
pip install -e packages/styrene-bond-rpc

# Get your operator identity hash
rnstatus -i

# Add your hash to device's auth.yaml (on device)

# Run smoke tests
./test_authorization.py <DEVICE_HASH>
./test_status.py <DEVICE_HASH>
./test_exec.py <DEVICE_HASH>
```

### 3. Get Identity Hashes

**On device:**
```bash
rnstatus -i
# Copy the hex hash (e.g., "a1b2c3d4e5f6...")
```

**On operator workstation:**
```bash
rnstatus -i
# Copy the hex hash to add to device's auth.yaml
```

### 4. Authorization Configuration

Edit `~/.config/styrene-bond-rpc/auth.yaml` on the device:

```yaml
identities:
  - hash: "PASTE_OPERATOR_HASH_HERE"  # From rnstatus -i on operator
    name: "Your Name"
    permissions:
      - status_request
      - exec
```

Then reload the agent:
```bash
sudo systemctl reload styrene-agent
```

## Security Notes

1. **Protect auth.yaml**: Set restrictive permissions
   ```bash
   chmod 600 ~/.config/styrene-bond-rpc/auth.yaml
   ```

2. **Review command allowlist**: Only allow necessary commands
   - Default: echo, ls, cat, df, free, uptime, systemctl status, journalctl
   - Add/remove based on operational needs

3. **Monitor auth logs**: Check for unauthorized access attempts
   ```bash
   tail -f /var/log/styrene-agent/auth.log
   ```

4. **Use principle of least privilege**: Grant minimum permissions needed
   - Monitoring users: `status_request` only
   - Operators: `status_request` + `exec`
   - Admins: All permissions

## Troubleshooting

### Device agent won't start

**Check systemd status:**
```bash
sudo systemctl status styrene-agent
sudo journalctl -u styrene-agent -n 50
```

**Common issues:**
- Missing auth.yaml: Create from template
- Invalid YAML syntax: Validate with `yamllint auth.yaml`
- Python import errors: Reinstall dependencies

### RPC timeout errors

**Verify network connectivity:**
```bash
rnstatus
# Should show peers and paths
```

**Check device is reachable:**
```bash
rnprobe <DEVICE_HASH>
```

**Increase timeout in smoke tests:**
```python
# Change timeout=10.0 to timeout=30.0
result = await client.call_status(device_hash, timeout=30.0)
```

### Authorization failures

**Verify identity hash is correct:**
```bash
# On operator:
rnstatus -i

# Should match hash in device's auth.yaml
```

**Check auth logs on device:**
```bash
tail -f /var/log/styrene-agent/auth.log
# Look for "Unauthorized" messages
```

**Reload config after changes:**
```bash
sudo systemctl reload styrene-agent
```

## Production Deployment

See full deployment guide: `docs/BACKEND_DEPLOYMENT.md`

See production checklist: `docs/PRODUCTION_READINESS_CHECKLIST.md`

## Test Status

**Backend Services:**
- ✅ RPC Client: 36/36 tests passing
- ✅ RPC Server: 11/11 tests passing
- ✅ RPC Handlers: 11/11 tests passing
- ✅ Authorization: 11/11 tests passing
- ✅ LXMF Service: 16/16 tests passing
- ✅ Integration: 6/8 tests passing (2 roundtrip tests timeout, non-blocking)

**Total: 120+ backend tests passing ✅**

## Support

For issues or questions, see:
- Deployment guide: `docs/BACKEND_DEPLOYMENT.md`
- Test coverage: `docs/TEST_COVERAGE_ASSESSMENT.md`
- Troubleshooting: Check device logs and smoke test output
