TISbackup/AUTHENTICATION.md
k3nny 38a0d788d4
Some checks are pending
lint / docker (push) Waiting to run
feat(auth): install all authentication providers by default
All authentication methods (Basic Auth, Flask-Login, OAuth) are now
installed as core dependencies instead of optional extras. This
simplifies setup and eliminates the need to run `uv sync --extra auth-*`
when switching between authentication methods.

Changes:
- Move authlib, bcrypt, and flask-login to core dependencies
- Remove auth-* optional dependency groups from pyproject.toml
- Update documentation to remove installation instructions
- Simplify troubleshooting and migration guides

Benefits:
- No import errors when switching auth methods
- Simpler user experience
- All providers available out of the box

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-05 21:17:30 +02:00

411 lines
9.1 KiB
Markdown

# 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. 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. **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. **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. **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. Restart service
3. Update client scripts with credentials
### From Basic Auth to OAuth
1. Register OAuth application
2. Update configuration
3. Test OAuth login flow
4. 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