# API Authentication Guide

WLED Screen Controller **requires** API key authentication for all API endpoints. This ensures your server is secure and all access is properly authenticated and audited.

## Configuration

Authentication is configured in `config/default_config.yaml`. **API keys are mandatory** - the server will not start without at least one configured key.

### Configure API Keys

```yaml
auth:
  enabled: true
  api_keys:
    home_assistant: "your-secure-api-key-1"
    web_dashboard: "your-secure-api-key-2"
    monitoring_script: "your-secure-api-key-3"
```

**Format:** API keys are defined as `label: "key"` pairs where:
- **Label**: Identifier for the client (e.g., `home_assistant`, `web_ui`, `admin`)
- **Key**: The actual API key (generate strong, random keys)

**Critical Requirements:**
- ⚠️ **At least one API key must be configured** - server will not start without keys
- Generate strong, random API keys (use `openssl rand -hex 32`)
- Never commit API keys to version control
- Use environment variables or secure secret management for production
- Each client/service gets its own labeled API key for audit trails
- Labels appear in server logs to track which client made requests

### Server Startup Validation

If no API keys are configured, the server will fail to start with this error:

```
CRITICAL: No API keys configured!
Authentication is REQUIRED for all API requests.
Please add API keys to your configuration:
  1. Generate keys: openssl rand -hex 32
  2. Add to config/default_config.yaml under auth.api_keys
  3. Format: label: "your-generated-key"
```

## Using API Keys

### Web UI

The web dashboard automatically handles authentication:

1. When you first load the UI with auth enabled, you'll be prompted for an API key
2. Enter your API key - it's stored in browser localStorage
3. Click the 🔑 **API Key** button in the header to update or remove the key

### REST API Clients

Include the API key in the `Authorization` header:

```bash
curl -H "Authorization: Bearer your-api-key-here" \
     http://localhost:8080/api/v1/devices
```

### Home Assistant Integration

The integration will prompt for an API key during setup if authentication is enabled. You can also configure it in `configuration.yaml`:

```yaml
wled_screen_controller:
  server_url: "http://192.168.1.100:8080"
  api_key: "your-api-key-here"  # Optional, only if auth is enabled
```

### Python Client Example

```python
import requests

API_KEY = "your-api-key-here"
BASE_URL = "http://localhost:8080/api/v1"

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

# List devices
response = requests.get(f"{BASE_URL}/devices", headers=headers)
devices = response.json()

# Start processing
response = requests.post(
    f"{BASE_URL}/devices/device_001/start",
    headers=headers
)
```

## Error Responses

### 401 Unauthorized

**Missing API Key:**
```json
{
  "detail": "Missing API key"
}
```

**Invalid API Key:**
```json
{
  "detail": "Invalid API key"
}
```

### 500 Internal Server Error

**Auth enabled but no keys configured:**
```json
{
  "detail": "Server authentication not configured"
}
```

## Endpoints

### Public Endpoints (No Auth Required)
- `GET /` - Web UI dashboard (static files)
- `GET /health` - Health check (for monitoring/health checks)
- `GET /docs` - API documentation
- `GET /redoc` - Alternative API docs
- `/static/*` - Static files (CSS, JS, images)

### Protected Endpoints (Auth ALWAYS Required)
All `/api/v1/*` endpoints **require authentication**:
- Device management (`/api/v1/devices/*`)
- Processing control (`/api/v1/devices/*/start`, `/api/v1/devices/*/stop`)
- Settings and calibration (`/api/v1/devices/*/settings`, `/api/v1/devices/*/calibration`)
- Metrics (`/api/v1/devices/*/metrics`)
- Display configuration (`/api/v1/config/displays`)

## Best Practices

### Development
```yaml
auth:
  enabled: false  # Disabled for local development
```

### Production
```yaml
auth:
  enabled: true
  api_keys:
    - "${WLED_API_KEY_1}"  # Use environment variables
    - "${WLED_API_KEY_2}"
```

Set environment variables:
```bash
export WLED_API_KEY_1="$(openssl rand -hex 32)"
export WLED_API_KEY_2="$(openssl rand -hex 32)"
```

### Docker
```yaml
# docker-compose.yml
services:
  wled-controller:
    environment:
      - WLED_AUTH__ENABLED=true
      - WLED_AUTH__API_KEYS__0=your-key-here
```

Or use Docker secrets for better security.

## Generating Secure API Keys

### OpenSSL
```bash
openssl rand -hex 32
# Output: 64-character hex string
```

### Python
```python
import secrets
print(secrets.token_hex(32))
```

### Node.js
```javascript
require('crypto').randomBytes(32).toString('hex')
```

## Logging

When authentication is enabled, the server logs:
- Auth status on startup
- Invalid API key attempts (with truncated key for security)
- Number of configured keys

Example startup logs:
```
INFO: API authentication: ENABLED (2 keys configured)
WARNING: Authentication is enabled - API requests require valid API key
```

Invalid attempts:
```
WARNING: Invalid API key attempt: 1234abcd...
```

## Security Considerations

1. **HTTPS**: Use HTTPS in production to protect API keys in transit
2. **Key Rotation**: Periodically rotate API keys
3. **Monitoring**: Monitor logs for invalid key attempts
4. **Least Privilege**: Use separate keys for different clients
5. **Storage**: Never log or display full API keys
6. **Rate Limiting**: Consider adding rate limiting for production (not implemented yet)

## Troubleshooting

### Web UI shows "API Key Required" repeatedly
- Verify the key is correct
- Check browser console for errors
- Clear localStorage and re-enter key

### Home Assistant can't connect
- Ensure API key is configured in integration settings
- Check server logs for authentication errors
- Verify `auth.enabled = true` in server config

### "Server authentication not configured" error
- You enabled auth but didn't add any API keys
- Add at least one key to `auth.api_keys` array
