Your webcam security system now has automatic credential management. Users authenticate via Tailscale, and their credentials (WebRTC, MinIO, PostgreSQL) are stored encrypted in a local SQLite database and auto-populated.
No more repeatedly entering passwords! π
./generate-encryption-key.shThis will output something like:
CREDENTIALS_ENCRYPTION_KEY="Ab3dEf7gHi9jKl2mNoPqRs4tUvWxYz1A2b4C6d8="
Copy this key and save it securely!
Add to your shell profile (~/.bashrc or ~/.zshrc):
export CREDENTIALS_ENCRYPTION_KEY="Ab3dEf7gHi9jKl2mNoPqRs4tUvWxYz1A2b4C6d8="Then reload:
source ~/.zshrc # or source ~/.bashrc./start-all.shThe script will automatically use your encryption key. You'll see:
β Credential database initialized at ~/.webcam2/credentials.db
β Tailscale manager initialized for user authentication
-
First Visit (one-time setup):
- User connects to
http://localhost:8080/config.htmlvia Tailscale - Frontend detects: "No credentials stored"
- UI shows message: "First-time Setup: Please enter your credentials once."
- User fills in credentials:
- WebRTC username/password
- MinIO access key/secret
- PostgreSQL username/password
- User clicks "Save Configuration"
- Backend:
- Identifies user via Tailscale WhoIs (gets email)
- Encrypts passwords with AES-256
- Stores in SQLite database
- Success message: "Credentials saved securely!"
- User connects to
-
Subsequent Visits (automatic):
- User connects to
http://localhost:8080/config.html - Frontend detects: "Credentials found!"
- UI hides credential fields
- Shows message: "β Credentials loaded from secure storage"
- Backend auto-populates config with decrypted credentials
- User never sees passwords again
- User connects to
If Tailscale is not enabled, the system falls back gracefully:
- Credential management endpoints will return warnings
- Config UI will show all fields (no auto-hide)
- Users enter credentials normally
- No automatic storage/retrieval
-
Enable Tailscale in config:
{ "tailscale": { "enabled": true, "hostname": "webcam-security" } } -
Start system:
./start-all.sh
-
From browser (on Tailscale network):
- Visit
http://<tailscale-ip>:8080/config.html - First time: Enter credentials
- Second time: Credentials auto-filled
- Visit
-
Check backend logs:
tail -f logs/go-camera.log | grep -i credentialYou should see:
β Credential database initialized at ~/.webcam2/credentials.db β Tailscale manager initialized for user authentication [APIServer] Credential management endpoints registered β Loaded credentials for user user@example.com from secure storage
curl http://localhost:8081/api/credentials/statusResponse:
{
"has_credentials": false,
"user_email": "user@example.com"
}curl -X POST http://localhost:8081/api/credentials \
-H "Content-Type: application/json" \
-d '{
"webrtc_username": "myuser",
"webrtc_password": "mypass123",
"minio_access_key": "minioadmin",
"minio_secret_key": "minioadmin",
"postgres_username": "recorder",
"postgres_password": "recorder"
}'Response:
{
"success": true,
"message": "Credentials saved successfully"
}curl -X DELETE http://localhost:8081/api/credentials| File | Purpose |
|---|---|
~/.webcam2/credentials.db |
SQLite database with encrypted credentials |
~/.webcam2/config.json |
Application configuration (no passwords) |
logs/go-camera.log |
Backend logs (includes credential system messages) |
- Algorithm: AES-256-GCM (Galois/Counter Mode)
- Key derivation: Argon2id (memory-hard KDF) with per-installation salt
- Unique nonce: Generated per encryption (prevents replay attacks)
- Authenticated encryption: GCM provides both confidentiality and integrity
- WebRTC password β
- MinIO secret key β
- PostgreSQL password β
- WebRTC username
- MinIO access key
- PostgreSQL username
Usernames are not considered sensitive (they're not authentication secrets)
CREDENTIALS_ENCRYPTION_KEY, you cannot decrypt stored credentials!
Production Recommendations:
- Store key in secure secrets manager (HashiCorp Vault, AWS Secrets Manager, etc.)
- Add to systemd EnvironmentFile with restricted permissions (
chmod 600) - Rotate key periodically (requires re-encrypting all user credentials)
- Never commit key to git (add to
.gitignore)
Solution: Enable Tailscale in config:
{
"tailscale": {
"enabled": true
}
}And ensure Tailscale is running:
tailscale statusCauses:
- Encryption key changed
- Database corrupted
Solution: Delete and recreate credentials:
rm ~/.webcam2/credentials.db
# Re-enter credentials in UIDebug steps:
# 1. Check database exists
ls -la ~/.webcam2/credentials.db
# 2. Check Tailscale can identify user
tailscale whois $(tailscale ip -4)
# 3. Check backend logs
tail -f logs/go-camera.log | grep -i credentialPossible causes:
- No credentials stored yet (first visit)
- Tailscale not enabled
- JavaScript not loaded
Solution:
- Open browser console (F12)
- Look for errors in Console tab
- Check Network tab for failed requests to
/api/credentials/status
-
Create environment file:
sudo mkdir -p /etc/webcam2 sudo bash -c 'cat > /etc/webcam2/credentials.env << EOF CREDENTIALS_ENCRYPTION_KEY="your-generated-key-here" EOF' sudo chmod 600 /etc/webcam2/credentials.env
-
Create systemd service:
[Unit] Description=Webcam Security Camera After=network.target docker.service tailscaled.service [Service] Type=simple User=webcam WorkingDirectory=/opt/webcam2 EnvironmentFile=/etc/webcam2/credentials.env ExecStart=/opt/webcam2/security-camera Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target
-
Enable and start:
sudo systemctl daemon-reload sudo systemctl enable webcam-security sudo systemctl start webcam-security
Add to your docker-compose.yml:
services:
webcam-backend:
image: webcam-security:latest
environment:
- CREDENTIALS_ENCRYPTION_KEY=${CREDENTIALS_ENCRYPTION_KEY}
env_file:
- /etc/webcam2/credentials.env # Alternatively
volumes:
- ~/.webcam2:/root/.webcam2Then run:
export CREDENTIALS_ENCRYPTION_KEY="your-key"
docker compose up -dThe system supports multiple users automatically:
| User | Stored Credentials | |
|---|---|---|
| Alice | alice@company.com | Her WebRTC/MinIO/PostgreSQL creds |
| Bob | bob@company.com | His WebRTC/MinIO/PostgreSQL creds |
| Carol | carol@company.com | Her WebRTC/MinIO/PostgreSQL creds |
How it works:
- Each user is identified by their Tailscale email
- Each user has a separate row in the database
- Backend auto-loads the correct credentials based on who's making the request
- Users never see each other's credentials
- Documentation: See
CREDENTIALS_SYSTEM.mdfor full technical details - Logs: Check
logs/go-camera.logfor backend errors - Database: Inspect with
sqlite3 ~/.webcam2/credentials.db
β One-time setup: Generate key, set environment variable β User experience: Enter credentials once, auto-filled forever β Security: AES-256 encrypted, Tailscale-authenticated β Multi-user: Each user has their own encrypted credentials β Zero maintenance: Automatic load/save, no manual management
You're done! π