# TISBackup Authentication System TISBackup provides a pluggable authentication system for securing the Flask web interface. You can choose between multiple authentication methods based on your security requirements. ## Supported Authentication Methods 1. **None** - No authentication (default, NOT recommended for production) 2. **Basic Auth** - HTTP Basic Authentication with username/password 3. **Flask-Login** - Session-based authentication with username/password 4. **OAuth2** - OAuth authentication (Google, GitHub, GitLab, or generic provider) ## Quick Start ### 1. Choose Authentication Method Add an `[authentication]` section to `/etc/tis/tisbackup_gui.ini`: ```ini [authentication] type = basic username = admin password = $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyYWv.5qVQK6 use_bcrypt = True ``` ### 2. Install Dependencies ```bash # For Basic Auth uv sync --extra auth-basic # For Flask-Login uv sync --extra auth-login # For OAuth uv sync --extra auth-oauth # For all auth methods uv sync --extra auth-all ``` ### 3. Restart TISBackup ```bash docker compose restart tisbackup_gui ``` ## Configuration Guide ### Basic Authentication Simple HTTP Basic Auth with username and password. **Pros:** - Easy to set up - Works with all HTTP clients - No session management needed **Cons:** - Credentials sent with every request - No logout functionality - Browser password prompt can be confusing **Configuration:** ```ini [authentication] type = basic username = admin # Use bcrypt hash (recommended) password = $2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyYWv.5qVQK6 use_bcrypt = True realm = TISBackup Admin ``` **Generate bcrypt hash:** ```bash python3 -c "import bcrypt; print(bcrypt.hashpw(b'yourpassword', bcrypt.gensalt()).decode())" ``` **Docker environment:** ```yaml services: tisbackup_gui: environment: - TISBACKUP_SECRET_KEY=your-secret-key # Optional: Pass credentials via env vars # Then reference in config with ${AUTH_PASSWORD} ``` --- ### Flask-Login Authentication Session-based authentication with login page and user management. **Pros:** - Clean login/logout workflow - Session-based (no credentials in each request) - Multiple users supported - Password hashing with bcrypt **Cons:** - Requires custom login page - Session management overhead - Cookies must be enabled **Configuration:** ```ini [authentication] type = flask-login users_file = /etc/tis/users.txt use_bcrypt = True login_view = login ``` **Create users file** (`/etc/tis/users.txt`): ``` admin:$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5GyYWv.5qVQK6 operator:$2b$12$abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNO viewer:$2b$12$ANOTHERBCRYPTHASHHERE1234567890ABCDEFGHIJKLMNOPQRS ``` **Generate user entry:** ```bash USERNAME="admin" PASSWORD="yourpassword" HASH=$(python3 -c "import bcrypt; print(bcrypt.hashpw(b'$PASSWORD', bcrypt.gensalt()).decode())") echo "$USERNAME:$HASH" >> /etc/tis/users.txt ``` **Permissions:** ```bash chmod 600 /etc/tis/users.txt chown root:root /etc/tis/users.txt ``` --- ### OAuth2 Authentication Delegate authentication to external OAuth providers (Google, GitHub, GitLab, etc.) **Pros:** - No password management - Leverage existing identity providers - Support for SSO - Can restrict by domain or specific users **Cons:** - Requires OAuth app registration - Internet connectivity required - More complex setup - External dependency #### Google OAuth **Setup:** 1. Go to [Google Cloud Console](https://console.cloud.google.com/apis/credentials) 2. Create OAuth 2.0 Client ID 3. Add authorized redirect URI: `http://your-server:8080/oauth/callback` 4. Note the Client ID and Client Secret **Configuration:** ```ini [authentication] type = oauth provider = google client_id = 123456789-abcdefghijklmnop.apps.googleusercontent.com client_secret = GOCSPX-your-client-secret-here redirect_uri = http://your-server:8080/oauth/callback # Restrict to specific domain(s) authorized_domains = example.com,mycompany.com # Or restrict to specific users authorized_users = admin@example.com,backup-admin@example.com ``` #### GitHub OAuth **Setup:** 1. Go to GitHub Settings > Developer settings > [OAuth Apps](https://github.com/settings/developers) 2. Register a new application 3. Set Authorization callback URL: `http://your-server:8080/oauth/callback` 4. Note the Client ID and Client Secret **Configuration:** ```ini [authentication] type = oauth provider = github client_id = your-github-client-id client_secret = your-github-client-secret redirect_uri = http://your-server:8080/oauth/callback authorized_users = admin@example.com,devops@example.com ``` #### GitLab OAuth **Setup:** 1. Go to GitLab User Settings > [Applications](https://gitlab.com/-/profile/applications) 2. Create application with scopes: `read_user`, `email` 3. Set Redirect URI: `http://your-server:8080/oauth/callback` 4. Note the Application ID and Secret **Configuration:** ```ini [authentication] type = oauth provider = gitlab client_id = your-gitlab-application-id client_secret = your-gitlab-secret redirect_uri = http://your-server:8080/oauth/callback authorized_domains = example.com ``` #### Generic OAuth Provider For custom OAuth providers: ```ini [authentication] type = oauth provider = generic client_id = your-client-id client_secret = your-client-secret redirect_uri = http://your-server:8080/oauth/callback # Custom endpoints authorization_endpoint = https://auth.example.com/oauth/authorize token_endpoint = https://auth.example.com/oauth/token userinfo_endpoint = https://auth.example.com/oauth/userinfo scopes = openid,email,profile # Authorization rules authorized_domains = example.com ``` --- ## Security Best Practices ### 1. Use HTTPS in Production Always use a reverse proxy with TLS: ```nginx server { listen 443 ssl http2; server_name tisbackup.example.com; ssl_certificate /etc/letsencrypt/live/tisbackup.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/tisbackup.example.com/privkey.pem; location / { proxy_pass http://localhost:8080/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto https; } } ``` ### 2. Set Strong Flask Secret Key ```bash # Generate secret python3 -c "import secrets; print(secrets.token_hex(32))" # Set in environment export TISBACKUP_SECRET_KEY=your-generated-secret-key ``` ### 3. Protect Configuration Files ```bash chmod 600 /etc/tis/tisbackup_gui.ini chmod 600 /etc/tis/users.txt # if using Flask-Login chown root:root /etc/tis/*.ini ``` ### 4. Use Environment Variables for Secrets Instead of hardcoding secrets in config files: ```ini [authentication] type = oauth client_id = ${OAUTH_CLIENT_ID} client_secret = ${OAUTH_CLIENT_SECRET} ``` Then set in Docker Compose: ```yaml services: tisbackup_gui: environment: - OAUTH_CLIENT_ID=your-client-id - OAUTH_CLIENT_SECRET=your-client-secret - TISBACKUP_SECRET_KEY=your-secret-key ``` ### 5. Regularly Rotate Credentials - Change passwords/secrets every 90 days - Rotate OAuth client secrets annually - Review authorized users/domains regularly ### 6. Monitor Authentication Logs Check logs for failed authentication attempts: ```bash docker logs tisbackup_gui | grep -i "auth" ``` ## Troubleshooting ### Basic Auth Not Working 1. **Check bcrypt installation:** ```bash uv sync --extra auth-basic ``` 2. **Verify password hash:** ```bash python3 -c "import bcrypt; print(bcrypt.checkpw(b'yourpassword', b'$2b$12$your-hash'))" ``` 3. **Check browser credentials:** - Clear browser cache - Try incognito/private mode ### Flask-Login Issues 1. **Users file not found:** ```bash ls -la /etc/tis/users.txt chmod 600 /etc/tis/users.txt ``` 2. **Module not found:** ```bash uv sync --extra auth-login ``` 3. **Session problems:** - Check `TISBACKUP_SECRET_KEY` is set - Ensure cookies are enabled ### OAuth Problems 1. **Redirect URI mismatch:** - Ensure redirect URI in config matches OAuth app settings exactly - Check for http vs https mismatch 2. **Unauthorized domain/user:** - Verify email matches `authorized_users` or domain matches `authorized_domains` - Check OAuth provider returns email in user info 3. **Module not found:** ```bash uv sync --extra auth-oauth ``` 4. **Token errors:** - Verify client ID and secret are correct - Check OAuth app is enabled - Ensure scopes are correct ## API Access with Authentication ### Basic Auth ```bash curl -u admin:password http://localhost:8080/api/backups ``` ### OAuth (with access token) ```bash # Not recommended for API access - use service account or API keys instead ``` ### Recommendation for API Access For programmatic API access, use Basic Auth with a dedicated API user: ```ini [authentication] type = basic username = api-user password = $2b$12$... ``` Or implement API key authentication separately for API endpoints. ## Migration Guide ### From No Auth to Basic Auth 1. Add authentication section to config 2. Install bcrypt: `uv sync --extra auth-basic` 3. Restart service 4. Update client scripts with credentials ### From Basic Auth to OAuth 1. Register OAuth application 2. Update configuration 3. Install dependencies: `uv sync --extra auth-oauth` 4. Test OAuth login flow 5. Update redirect URI if needed ### From Flask-Login to OAuth 1. Register OAuth application 2. Map user emails to OAuth provider 3. Update configuration 4. Test migration with test users first ## Support For issues or questions: - Check logs: `docker logs tisbackup_gui` - Review configuration syntax - Verify dependencies are installed - See [SECURITY_IMPROVEMENTS.md](../SECURITY_IMPROVEMENTS.md) for security context