Security Configuration
Configure security settings for Imagor Studio.
Authentication
JWT Configuration
Flag | Environment Variable | Default | Description |
---|---|---|---|
--jwt-secret | JWT_SECRET | Auto-generated | Secret key for JWT signing (optional) |
--jwt-expiration | JWT_EXPIRATION | 168h | Token expiration (7 days) |
# Optionally set a JWT secret (auto-generated if not provided)
export JWT_SECRET=your-very-strong-secret-key-here
export JWT_EXPIRATION=168h # 7 days
JWT Secret Resolution
The JWT secret is optional and follows this resolution order:
- CLI/Environment Variable - If provided, uses the specified secret
- Database Registry - If exists, retrieves the encrypted secret from database
- Auto-generate - If neither exists, generates a secure random secret and stores it encrypted in the database
If you don't provide a JWT_SECRET
, Imagor Studio automatically generates a cryptographically secure secret (48 bytes, base64-encoded) on first startup and stores it encrypted in the database. This secret persists across restarts, so your users' sessions remain valid.
The JWT secret is encrypted using the master key, which is derived from your database path. This ensures the secret can be decrypted during bootstrap before the database is fully initialized.
When to Set JWT_SECRET Manually
You should explicitly set JWT_SECRET
via CLI/environment when:
- Multi-instance deployments - All instances must share the same secret for session consistency
- Explicit control - You want to manage the secret yourself
- Secret rotation - You need to rotate secrets as part of security policy
- Disaster recovery - You want to backup the secret separately
For single-instance deployments, the auto-generated secret is secure and convenient.
Guest Mode
Allow unauthenticated access to the gallery:
export ALLOW_GUEST_MODE=true
Guest mode allows anyone to view your images without authentication. Only enable if appropriate for your use case.
Encryption
Imagor Studio uses a sophisticated two-tier encryption system to protect sensitive configuration data stored in the database registry.
How Encryption Works
Bootstrap Sequence
1. Server starts with DATABASE_URL
↓
2. Master key derived from database path (PBKDF2)
↓
3. JWT secret decrypted/generated using master key
↓
4. JWT key derived from JWT secret (PBKDF2)
↓
5. Other secrets (S3, imagor, license) encrypted/decrypted with JWT key
Master Key Encryption
The master key is the foundation of the encryption system:
- Derived from: Database path (from
DATABASE_URL
) + salt - Algorithm: PBKDF2 with 4096 iterations
- Used for: Encrypting/decrypting JWT secrets only
- Purpose: Enables JWT secret decryption during bootstrap before the database is fully initialized
Why Database Path?
The database path is used as the master key source because:
- Available at startup - Known before database connection
- Deterministic - Same path always produces same key
- Persistent - Doesn't change across restarts
- Unique per deployment - Different databases = different keys
Changing your DATABASE_URL
will change the master key, making existing encrypted JWT secrets unreadable. Plan your database configuration carefully before initial deployment.
If you must change the database URL:
- Note your current JWT secret (if auto-generated, retrieve from database)
- Change the database URL
- Set the JWT secret explicitly via environment variable
- Restart the application
JWT Key Encryption
The JWT key provides a second layer of encryption:
- Derived from: JWT secret + salt
- Algorithm: PBKDF2 with 4096 iterations
- Used for: Encrypting/decrypting S3 credentials, imagor secrets, license keys
- Purpose: Additional security layer for general sensitive configuration
Encryption Algorithm Details
- Algorithm: AES-256-GCM (Galois/Counter Mode)
- Key size: 256 bits (32 bytes)
- Key derivation: PBKDF2 with 4096 iterations
- Nonce: Random 12-byte nonce for each encryption (ensures same plaintext produces different ciphertext)
- Authentication: Built-in authentication tag prevents tampering
- Encoding: Base64 for safe database storage
What Gets Encrypted
Master Key Encrypted (Tier 1)
config.jwt_secret
- JWT signing secret
JWT Key Encrypted (Tier 2)
config.s3_access_key_id
- S3 access credentialsconfig.s3_secret_access_key
- S3 secret credentialsconfig.s3_session_token
- S3 session tokensconfig.imagor_secret
- Imagor signing secretconfig.license_key
- License activation key
Not Encrypted
- Database URL (used to derive master key)
- Port, storage type, file paths
- Boolean flags and non-sensitive settings
License Management
License Key
Activate Imagor Studio with a license key:
export LICENSE_KEY=your-license-key-here
License keys are encrypted when stored in the system registry.
License Validation
The license system validates:
- License signature
- Expiration date
- Feature entitlements
- Instance limits
Security Best Practices
1. Strong Secrets
Use strong, random secrets for all security-sensitive settings:
# Generate strong secrets
openssl rand -base64 32
# Use in configuration
export JWT_SECRET=$(openssl rand -base64 32)
export IMAGOR_SECRET=$(openssl rand -base64 32)
2. HTTPS/TLS
Always use HTTPS in production:
services:
nginx:
image: nginx:alpine
ports:
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/nginx/ssl:ro
depends_on:
- imagor-studio
3. Network Isolation
Isolate services using Docker networks:
services:
postgres:
networks:
- backend
imagor-studio:
networks:
- backend
- frontend
networks:
backend:
internal: true
frontend:
4. Read-Only Mounts
Mount image directories as read-only:
volumes:
- ~/Pictures:/app/gallery:ro
5. Regular Updates
Keep Imagor Studio and dependencies updated:
docker pull shumc/imagor-studio:latest
6. Secure Database
- Use strong database passwords
- Enable SSL/TLS for database connections
- Restrict database network access
- Regular backups
7. Environment Variables
Never commit secrets to version control:
# Use .env file (add to .gitignore)
echo "JWT_SECRET=..." > .env
echo ".env" >> .gitignore
# Or use Docker secrets
docker secret create jwt_secret jwt_secret.txt
Access Control
Admin Setup
On first launch, create an admin account:
- Navigate to
http://localhost:8000
- Complete admin setup wizard
- Set strong password
- Configure initial settings
User Management
Manage users through the web interface:
- Log in as admin
- Navigate to User Management
- Create/edit/delete users
- Assign roles and permissions
Audit Logging
Monitor system access and changes:
- Authentication attempts
- Configuration changes
- User actions
- System events
Logs are available through:
- Docker logs:
docker logs imagor-studio
- System logs in the database
- External logging services (if configured)
Security Headers
Imagor Studio sets secure HTTP headers:
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Strict-Transport-Security
(when using HTTPS)
Vulnerability Reporting
Report security vulnerabilities:
- Do not create public GitHub issues
- Email security concerns to the maintainers
- Include detailed reproduction steps
- Allow time for patch development
Next Steps
- Docker Deployment - Secure deployment practices
- Migration Guide - Database security
- Configuration Overview - All configuration options