Version 2.0 - Enhanced Security Features
This guide explains the security features of the Govee 5075 Monitoring System, covering API key authentication, HTTPS encryption, and additional security improvements in v2.0.
The system implements multiple layers of security:
- API Key Authentication - Verifies that clients are authorized to communicate with the server
- HTTPS/TLS Encryption - Encrypts all data in transit between clients and the server
- Input Validation - Prevents XSS, path traversal, and injection attacks (v2.0)
- Security Headers - Comprehensive HTTP security headers (v2.0)
- Rate Limiting - Per-IP rate limiting to prevent abuse and DoS attacks
- Trusted Proxy Support - Configurable trusted proxy CIDRs for correct client IP extraction behind reverse proxies
For maximum security, all features should be enabled and properly configured.
- Cryptographically Secure API Keys: Generated using
crypto/randfor unpredictability - XSS Prevention: Device names, client IDs, and all inputs are validated and sanitized
- Client ID Validation: Client IDs must match
^[a-zA-Z0-9_\-\.]+$(max 100 chars) - Security Headers: CSP, HSTS, X-Frame-Options, and more
- Trusted Proxy Support: Only trusts
X-Forwarded-Forfrom configured proxy CIDRs (-trusted-proxiesflag) - Request Body Limits: 1MB maximum request body size to prevent resource exhaustion
- Enhanced Health Checks: Monitor security status via
/healthendpoint - Audit Capabilities: Better logging for security events
The Govee Monitoring System uses API keys to control access to server resources:
- Each client must provide a valid API key with every request
- API keys are associated with specific client IDs
- The server validates both the API key and the client ID
The system supports three categories of API keys:
- Admin API Key: Has full access to all server functions including API key management
- Client-Specific API Keys: Tied to specific client IDs, allows clients to send data
- Default API Key: Optional shared key that can be used by all clients (less secure)
When starting the server, enable authentication with these flags:
./govee-server -auth=true -admin-key=YOUR_ADMIN_KEYAvailable authentication flags:
| Flag | Default | Description |
|---|---|---|
-auth |
true | Enable API key authentication |
-admin-key |
auto-generated | Admin API key (generated if empty) |
-default-key |
auto-generated | Default API key for all clients |
-allow-default |
false | Allow the default API key to be used |
You can manage client API keys using the API (requires admin key):
List all API keys:
curl -H "X-API-Key: <admin_key>" http://server:8080/api/keysCreate a new API key:
curl -X POST -H "X-API-Key: <admin_key>" -H "Content-Type: application/json" \
-d '{"client_id": "client-kitchen"}' \
http://server:8080/api/keysDelete an API key:
curl -X DELETE -H "X-API-Key: <admin_key>" \
http://server:8080/api/keys?key=<api_key_to_delete>Clients must provide their API key when sending data:
./govee-client -server=http://server:8080/readings -apikey=YOUR_API_KEY -id=client-kitchenHTTPS (HTTP Secure) uses Transport Layer Security (TLS) to encrypt all communications:
- Prevents eavesdropping on sensitive data (API keys, readings)
- Verifies the identity of the server to prevent man-in-the-middle attacks
- Works alongside API key authentication for a layered security approach
You can use the provided script to generate self-signed certificates:
./generate_cert.sh --name your-server-hostname --ip your-server-ipThis creates:
- A Certificate Authority (CA) certificate (
ca.crt) - A server certificate (
cert.pem) - A private key (
key.pem)
For production, consider obtaining certificates from a trusted certificate authority.
Enable HTTPS on the server:
./govee-server -https=true -cert=./certs/cert.pem -key=./certs/key.pemHTTPS flags:
| Flag | Default | Description |
|---|---|---|
-https |
false | Enable HTTPS |
-cert |
cert.pem | Path to TLS certificate file |
-key |
key.pem | Path to TLS key file |
Clients must be configured to use HTTPS and verify the server's certificate:
./govee-client -server=https://server:8080/readings -ca-cert=./certs/ca.crt -apikey=YOUR_API_KEYHTTPS client flags:
| Flag | Default | Description |
|---|---|---|
-ca-cert |
"" | Path to CA certificate file |
-insecure |
false | Skip certificate verification (NOT recommended for production) |
For maximum security, enable both authentication and HTTPS:
./govee-server -https=true -cert=./certs/cert.pem -key=./certs/key.pem -auth=true./govee-client -server=https://server:8080/readings \
-ca-cert=./certs/ca.crt \
-apikey=YOUR_API_KEY \
-id=client-kitchenFor Docker deployments:
services:
govee-server:
# ...other settings...
volumes:
- ./certs:/app/certs
environment:
- HTTPS=true
- CERT=/app/certs/cert.pem
- KEY=/app/certs/key.pem
- AUTH=true
- ADMIN_KEY=${ADMIN_KEY:-admin-key-here}
govee-client:
# ...other settings...
environment:
- SERVER_URL=https://server:8080/readings
- APIKEY=${CLIENT_APIKEY:-your_api_key_here}
- CA_CERT=/app/certs/ca.crt
volumes:
- ./certs:/app/certs-
Try with invalid API key:
./govee-client -server=http://server:8080/readings -apikey=INVALID_KEY
You should see an "Authentication failed" error.
-
Try with wrong client ID:
./govee-client -server=http://server:8080/readings -apikey=VALID_KEY -id=wrong-client-id
You should see a "Client ID mismatch" error.
-
Verify certificate details:
openssl x509 -in certs/cert.pem -text -noout
Check that the hostname matches your server.
-
Test HTTPS connection:
curl -v --cacert certs/ca.crt https://server:8080/health
You should see "OK" with TLS handshake details.
-
"Unauthorized: API key required"
- Verify API key is being included in the request header
- Check that the
-apikeyflag is set correctly
-
"Unauthorized: Invalid API key"
- Verify the API key exists on the server
- Try regenerating the API key
-
"Unauthorized: Client ID mismatch"
- Ensure client ID matches the one registered with the API key
- Check for typos or case sensitivity issues
-
Certificate verification failure
- Verify server hostname matches the certificate's Common Name or SAN
- Ensure CA certificate is correctly provided to the client
- Check certificate expiration dates
-
"Connection refused" or timeouts
- Verify the server is listening on the correct port
- Check firewall rules for HTTPS port
- Try using curl with
-kto bypass verification for testing
When running behind a reverse proxy (e.g., nginx, Caddy, Traefik), the server needs to know which proxies to trust for extracting real client IPs from X-Forwarded-For headers.
Without trusted proxies configured, the server ignores X-Forwarded-For entirely and uses the direct connection IP for rate limiting. This is the safe default.
To enable trusted proxy support:
# Trust a single proxy
./govee-server -trusted-proxies=10.0.0.1/32
# Trust a subnet
./govee-server -trusted-proxies=10.0.0.0/8
# Trust multiple ranges (comma-separated CIDRs)
./govee-server -trusted-proxies=10.0.0.0/8,172.16.0.0/12,192.168.0.0/16Important: Only configure CIDRs for proxies you control. Trusting arbitrary IPs allows attackers to spoof their source IP via the X-Forwarded-For header, bypassing rate limits.
- Use both authentication and HTTPS for defense in depth
- Generate unique API keys for each client
- Rotate API keys periodically for better security
- Use trusted certificates in production environments
- Keep private keys secure with appropriate permissions
- Monitor authentication logs for unusual activity
- Disable the default API key in production
- Use environment variables for API keys in Docker deployments
- Back up certificates and keys securely
- Implement rate limiting to prevent brute force attacks
| Endpoint | Auth Required | Description |
|---|---|---|
/readings |
Yes | Add/get sensor readings |
/devices |
Yes | Get device information |
/clients |
Yes | Get client information |
/stats |
Yes | Get statistics |
/dashboard/data |
No | Dashboard data (read-only, public) |
/api/keys |
Admin only | Manage API keys |
/health |
No | Health check endpoint |
/ |
No | Static dashboard files |