Updated readme.
This commit is contained in:
446
README.md
446
README.md
@@ -5,12 +5,14 @@ A lightweight forward authentication service for Caddy (or any reverse proxy) th
|
||||
## Features
|
||||
|
||||
- 🔐 TOTP-based authentication (compatible with Google Authenticator, Authy, 1Password, etc.)
|
||||
- 🎫 JWT session management with configurable duration
|
||||
- 🎫 JWT session management with configurable duration (default: 24 hours)
|
||||
- 🛡️ Built-in rate limiting (5 attempts per 15 minutes)
|
||||
- 👥 Support for multiple users (1-20+ TOTP seeds)
|
||||
- 🪶 Lightweight SQLite database
|
||||
- 🚀 Single binary deployment
|
||||
- 🔄 Works with Caddy's `forward_auth` directive
|
||||
- 📱 Mobile-friendly login page
|
||||
- 🔒 Secure by default with HTTPS cookie settings
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@@ -42,25 +44,31 @@ go build -o forward-auth main.go
|
||||
|
||||
| Variable | Description | Default | Required |
|
||||
|----------|-------------|---------|----------|
|
||||
| `JWT_SECRET` | Secret key for signing JWT tokens | (insecure default) | **Recommended** |
|
||||
| `JWT_SECRET` | Secret key for signing JWT tokens | None | **Yes** |
|
||||
|
||||
**Important:** Always set a secure `JWT_SECRET` in production:
|
||||
```bash
|
||||
export JWT_SECRET="your-very-secure-random-secret-here-min-32-chars"
|
||||
```
|
||||
**Important:** The `JWT_SECRET` environment variable is **required**. The application will not start without it.
|
||||
|
||||
Generate a secure secret:
|
||||
```bash
|
||||
openssl rand -base64 32
|
||||
```
|
||||
|
||||
Set it before running:
|
||||
```bash
|
||||
export JWT_SECRET="your-very-secure-random-secret-here-min-32-chars"
|
||||
```
|
||||
|
||||
### Application Constants
|
||||
|
||||
You can modify these constants in `main.go`:
|
||||
You can modify these constants in `main.go` if needed:
|
||||
|
||||
- `sessionDuration`: JWT session duration (default: 24 hours)
|
||||
- `dbFile`: SQLite database file path (default: `auth.db`)
|
||||
- `jwtCookie`: Cookie name for JWT token (default: `auth_token`)
|
||||
| Constant | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `sessionDuration` | JWT session duration | 24 hours |
|
||||
| `dbFile` | SQLite database file path | `auth.db` |
|
||||
| `jwtCookie` | Cookie name for JWT token | `auth_token` |
|
||||
| `maxLoginAttempts` | Maximum failed login attempts | 5 |
|
||||
| `rateLimitWindow` | Rate limit time window | 15 minutes |
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -68,6 +76,7 @@ You can modify these constants in `main.go`:
|
||||
|
||||
On first run, the application will automatically generate a TOTP seed:
|
||||
```bash
|
||||
export JWT_SECRET="$(openssl rand -base64 32)"
|
||||
./forward-auth
|
||||
```
|
||||
|
||||
@@ -81,7 +90,10 @@ Use this to set up your authenticator app.
|
||||
Starting auth server on :3000
|
||||
```
|
||||
|
||||
Scan the QR code (use the OTPAuth URL with a QR generator) or manually enter the secret into your authenticator app.
|
||||
**Add to Authenticator App:**
|
||||
1. Open your authenticator app (Google Authenticator, Authy, 1Password, etc.)
|
||||
2. Scan the QR code (generate one from the OTPAuth URL) or manually enter the secret
|
||||
3. Use the 6-digit code to log in
|
||||
|
||||
### Generate Additional TOTP Seeds
|
||||
|
||||
@@ -90,7 +102,7 @@ For multiple users, generate additional seeds:
|
||||
./forward-auth -generate
|
||||
```
|
||||
|
||||
Each seed can be used by a different user with their own authenticator app.
|
||||
Each seed represents a separate user. The application will check all seeds when validating OTP codes.
|
||||
|
||||
### Running as a Service
|
||||
|
||||
@@ -106,19 +118,61 @@ After=network.target
|
||||
Type=simple
|
||||
User=www-data
|
||||
WorkingDirectory=/opt/forward-auth
|
||||
Environment="JWT_SECRET=your-secure-secret-here"
|
||||
Environment="JWT_SECRET=your-secure-secret-here-change-this"
|
||||
ExecStart=/opt/forward-auth/forward-auth
|
||||
Restart=on-failure
|
||||
RestartSec=5s
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
ReadWritePaths=/opt/forward-auth
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
Enable and start:
|
||||
Deploy and start:
|
||||
```bash
|
||||
sudo mkdir -p /opt/forward-auth
|
||||
sudo cp forward-auth /opt/forward-auth/
|
||||
sudo chown -R www-data:www-data /opt/forward-auth
|
||||
sudo chmod 600 /opt/forward-auth/auth.db # After first run
|
||||
sudo systemctl enable forward-auth
|
||||
sudo systemctl start forward-auth
|
||||
sudo systemctl status forward-auth
|
||||
```
|
||||
|
||||
#### Docker (Optional)
|
||||
|
||||
Create `Dockerfile`:
|
||||
```dockerfile
|
||||
FROM golang:1.21-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod download
|
||||
COPY main.go ./
|
||||
RUN go build -o forward-auth main.go
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add ca-certificates sqlite
|
||||
WORKDIR /root/
|
||||
COPY --from=builder /app/forward-auth .
|
||||
EXPOSE 3000
|
||||
CMD ["./forward-auth"]
|
||||
```
|
||||
|
||||
Build and run:
|
||||
```bash
|
||||
docker build -t forward-auth .
|
||||
docker run -d \
|
||||
-p 3000:3000 \
|
||||
-v $(pwd)/data:/root \
|
||||
-e JWT_SECRET="your-secret-here" \
|
||||
--name forward-auth \
|
||||
forward-auth
|
||||
```
|
||||
|
||||
## Caddy Configuration
|
||||
@@ -135,16 +189,16 @@ app.example.com {
|
||||
reverse_proxy localhost:8080
|
||||
}
|
||||
|
||||
# Auth service (optional, if you want it accessible externally)
|
||||
# Auth service (optional, if you want login page accessible externally)
|
||||
auth.example.com {
|
||||
reverse_proxy localhost:3000
|
||||
}
|
||||
```
|
||||
|
||||
### Advanced Configuration with Error Handling
|
||||
### Recommended Configuration with Login Page Access
|
||||
```caddyfile
|
||||
app.example.com {
|
||||
# Allow access to login page without auth
|
||||
# Allow unauthenticated access to login page
|
||||
@login {
|
||||
path /login*
|
||||
}
|
||||
@@ -152,7 +206,7 @@ app.example.com {
|
||||
reverse_proxy localhost:3000
|
||||
}
|
||||
|
||||
# Protect everything else
|
||||
# Protect all other routes
|
||||
forward_auth localhost:3000 {
|
||||
uri /verify
|
||||
copy_headers X-Original-URI
|
||||
@@ -162,7 +216,7 @@ app.example.com {
|
||||
}
|
||||
```
|
||||
|
||||
### Multiple Protected Services
|
||||
### Multiple Protected Services (Shared Authentication)
|
||||
```caddyfile
|
||||
# Auth service
|
||||
auth.example.com {
|
||||
@@ -188,57 +242,140 @@ app2.example.com {
|
||||
}
|
||||
```
|
||||
|
||||
### With SSL/TLS
|
||||
```caddyfile
|
||||
app.example.com {
|
||||
# Automatic HTTPS via Caddy
|
||||
forward_auth localhost:3000 {
|
||||
uri /verify
|
||||
copy_headers X-Original-URI
|
||||
}
|
||||
|
||||
reverse_proxy localhost:8080
|
||||
}
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `/verify` | GET | Verify JWT token (for forward auth) |
|
||||
| `/verify` | GET | Verify JWT token (used by forward auth) |
|
||||
| `/login` | GET | Display login form |
|
||||
| `/login` | POST | Process OTP submission |
|
||||
| `/health` | GET | Health check endpoint |
|
||||
|
||||
## Security Considerations
|
||||
### Endpoint Details
|
||||
|
||||
### Production Checklist
|
||||
#### GET /verify
|
||||
Returns:
|
||||
- `204 No Content` - Valid authentication
|
||||
- `302 Found` - Redirect to login (with `?next=` parameter)
|
||||
|
||||
- [ ] Set a strong `JWT_SECRET` environment variable
|
||||
- [ ] Enable HTTPS and uncomment `Secure: true` in cookie settings
|
||||
#### GET /login
|
||||
Query parameters:
|
||||
- `next` (optional) - Redirect URL after successful login
|
||||
|
||||
#### POST /login
|
||||
Form parameters:
|
||||
- `otp` (required) - 6-digit TOTP code
|
||||
- `next` (optional) - Redirect URL after successful login
|
||||
|
||||
Returns:
|
||||
- `302 Found` - Successful login, redirects to `next` URL
|
||||
- `401 Unauthorized` - Invalid OTP
|
||||
- `429 Too Many Requests` - Rate limit exceeded
|
||||
|
||||
#### GET /health
|
||||
Returns:
|
||||
- `200 OK` - Service is healthy
|
||||
|
||||
## Security Features
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
The application includes built-in rate limiting to prevent brute force attacks:
|
||||
|
||||
- **Maximum attempts:** 5 failed login attempts
|
||||
- **Time window:** 15 minutes
|
||||
- **Per IP address tracking**
|
||||
- **Automatic cleanup:** Old entries removed every 5 minutes
|
||||
- **Reset on success:** Successful login clears rate limit for that IP
|
||||
|
||||
When rate limited, users see: "Too many failed attempts. Try again in 15 minutes."
|
||||
|
||||
### Cookie Security
|
||||
|
||||
Cookies are configured with security best practices:
|
||||
- `HttpOnly: true` - Prevents JavaScript access
|
||||
- `Secure: true` - HTTPS only (requires SSL/TLS)
|
||||
- `SameSite: Lax` - CSRF protection
|
||||
- `Path: /` - Available to all routes
|
||||
|
||||
### Open Redirect Protection
|
||||
|
||||
The application validates redirect URLs to prevent open redirect attacks. Only relative URLs starting with `/` are allowed.
|
||||
|
||||
### JWT Security
|
||||
|
||||
- Tokens are signed with HS256
|
||||
- Include expiration time (`exp`)
|
||||
- Include issued at time (`iat`)
|
||||
- Validated on every request
|
||||
|
||||
## Security Checklist
|
||||
|
||||
### Production Deployment
|
||||
|
||||
- [x] Set a strong `JWT_SECRET` (32+ characters, random)
|
||||
- [x] HTTPS enabled (Caddy handles this automatically)
|
||||
- [x] Cookie `Secure` flag enabled (already set in code)
|
||||
- [x] Rate limiting active (built-in, 5 attempts per 15 min)
|
||||
- [ ] Restrict database file permissions: `chmod 600 auth.db`
|
||||
- [ ] Run the service as a non-root user
|
||||
- [ ] Keep the TOTP secrets secure and backed up
|
||||
- [ ] Consider rate limiting on the `/login` endpoint
|
||||
- [ ] Monitor failed authentication attempts
|
||||
- [ ] Run service as non-root user
|
||||
- [ ] Keep TOTP secrets backed up securely
|
||||
- [ ] Monitor logs for suspicious activity
|
||||
- [ ] Set up log rotation
|
||||
- [ ] Consider firewall rules to restrict port 3000
|
||||
|
||||
### HTTPS Configuration
|
||||
### Additional Recommendations
|
||||
|
||||
For production, uncomment the `Secure` flag in `main.go`:
|
||||
```go
|
||||
http.SetCookie(w, &http.Cookie{
|
||||
Name: jwtCookie,
|
||||
Value: tokenStr,
|
||||
Expires: time.Now().Add(sessionDuration),
|
||||
HttpOnly: true,
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
Secure: true, // Uncomment this line
|
||||
Path: "/",
|
||||
})
|
||||
```
|
||||
1. **Backup TOTP seeds:** Store them securely (e.g., password manager)
|
||||
2. **Time synchronization:** Ensure server time is accurate (use NTP)
|
||||
3. **Monitoring:** Set up alerts for repeated failed login attempts
|
||||
4. **Updates:** Keep Go and dependencies updated
|
||||
5. **Logs:** Review logs regularly for anomalies
|
||||
|
||||
## Database Management
|
||||
|
||||
### Backup
|
||||
```bash
|
||||
# Simple backup
|
||||
cp auth.db auth.db.backup
|
||||
|
||||
# Timestamped backup
|
||||
cp auth.db "auth.db.backup.$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
# Automated daily backup (cron)
|
||||
0 2 * * * cp /opt/forward-auth/auth.db "/opt/forward-auth/backups/auth.db.$(date +\%Y\%m\%d)"
|
||||
```
|
||||
|
||||
### View All Seeds
|
||||
```bash
|
||||
sqlite3 auth.db "SELECT * FROM seeds;"
|
||||
sqlite3 auth.db "SELECT id, secret FROM seeds;"
|
||||
```
|
||||
|
||||
### Remove a Seed
|
||||
### Count Seeds
|
||||
```bash
|
||||
sqlite3 auth.db "SELECT COUNT(*) FROM seeds;"
|
||||
```
|
||||
|
||||
### Remove a Specific Seed
|
||||
```bash
|
||||
# By ID
|
||||
sqlite3 auth.db "DELETE FROM seeds WHERE id = 1;"
|
||||
|
||||
# By secret (first few characters)
|
||||
sqlite3 auth.db "DELETE FROM seeds WHERE secret LIKE 'JBSWY%';"
|
||||
```
|
||||
|
||||
### Reset Database
|
||||
@@ -251,60 +388,213 @@ rm auth.db
|
||||
|
||||
### "Invalid OTP" Error
|
||||
|
||||
- Ensure your device time is synchronized (TOTP is time-based)
|
||||
- Check that you're using the correct seed in your authenticator app
|
||||
- Verify the OTP code hasn't expired (codes are valid for 30 seconds)
|
||||
**Causes:**
|
||||
- Device time not synchronized (TOTP is time-sensitive)
|
||||
- Wrong seed in authenticator app
|
||||
- OTP code expired (valid for 30 seconds)
|
||||
|
||||
**Solutions:**
|
||||
```bash
|
||||
# Check server time
|
||||
date
|
||||
|
||||
# Sync time (Linux)
|
||||
sudo ntpdate pool.ntp.org
|
||||
# or
|
||||
sudo timedatectl set-ntp true
|
||||
|
||||
# Verify database has seeds
|
||||
sqlite3 auth.db "SELECT COUNT(*) FROM seeds;"
|
||||
```
|
||||
|
||||
### "Too many failed attempts"
|
||||
|
||||
This is the rate limiting feature. Wait 15 minutes or:
|
||||
```bash
|
||||
# Check current rate limits (requires modifying code to expose this)
|
||||
# For now, restart the service to clear in-memory rate limits
|
||||
sudo systemctl restart forward-auth
|
||||
```
|
||||
|
||||
### Authentication Not Working
|
||||
```bash
|
||||
# Check if service is running
|
||||
sudo systemctl status forward-auth
|
||||
|
||||
- Check Caddy logs: `journalctl -u caddy -f`
|
||||
- Check forward-auth logs: `journalctl -u forward-auth -f`
|
||||
- Verify the forward auth service is running: `curl http://localhost:3000/health`
|
||||
- Ensure `X-Original-URI` header is being passed correctly
|
||||
# Check service logs
|
||||
sudo journalctl -u forward-auth -f
|
||||
|
||||
# Check Caddy logs
|
||||
sudo journalctl -u caddy -f
|
||||
|
||||
# Verify health endpoint
|
||||
curl http://localhost:3000/health
|
||||
|
||||
# Test verify endpoint
|
||||
curl -v http://localhost:3000/verify
|
||||
```
|
||||
|
||||
### Cookie Not Persisting
|
||||
|
||||
- Verify you're using HTTPS in production with `Secure: true`
|
||||
- Check that the cookie path matches your application structure
|
||||
- Ensure `SameSite` attribute is compatible with your setup
|
||||
**Checklist:**
|
||||
- [ ] Using HTTPS in production (required for `Secure: true`)
|
||||
- [ ] Cookie domain matches your setup
|
||||
- [ ] Browser accepts cookies
|
||||
- [ ] No browser extensions blocking cookies
|
||||
- [ ] Clock skew between client and server
|
||||
|
||||
### JWT_SECRET Not Set Error
|
||||
```
|
||||
JWT_SECRET environment variable must be set!
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Generate a secret
|
||||
export JWT_SECRET="$(openssl rand -base64 32)"
|
||||
|
||||
# Or set permanently in systemd service file
|
||||
sudo systemctl edit forward-auth
|
||||
# Add: Environment="JWT_SECRET=your-secret-here"
|
||||
```
|
||||
|
||||
### Database Locked Error
|
||||
```bash
|
||||
# Check if file is being accessed by another process
|
||||
lsof auth.db
|
||||
|
||||
# Ensure proper permissions
|
||||
sudo chown www-data:www-data auth.db
|
||||
sudo chmod 600 auth.db
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
This application is designed for light usage (1-20 users, <100 requests/day):
|
||||
This application is designed for light usage:
|
||||
|
||||
- **Memory footprint:** ~10-15 MB
|
||||
- **CPU usage:** Minimal (<1% on modern systems)
|
||||
- **Database size:** <1 KB for up to 20 seeds
|
||||
- **Startup time:** <100ms
|
||||
| Metric | Value |
|
||||
|--------|-------|
|
||||
| Memory footprint | ~10-15 MB |
|
||||
| CPU usage | <1% (idle), ~2-3% (under load) |
|
||||
| Database size | <1 KB per seed (~20 KB for 20 seeds) |
|
||||
| Startup time | <100ms |
|
||||
| Request latency | <10ms (local), <50ms (network) |
|
||||
| Max throughput | 1000+ req/sec (limited by SQLite) |
|
||||
|
||||
**Tested scenarios:**
|
||||
- 4 users, <100 requests/day: Negligible resource usage
|
||||
- 20 users, 500 requests/day: <5 MB memory, <1% CPU
|
||||
|
||||
## Development
|
||||
|
||||
### Run in Development Mode
|
||||
```bash
|
||||
export JWT_SECRET="dev-secret-do-not-use-in-production"
|
||||
go run main.go
|
||||
```
|
||||
|
||||
### Run Tests
|
||||
### Enable Debug Logging
|
||||
|
||||
Modify `main.go` to add debug logs:
|
||||
```go
|
||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||
```
|
||||
|
||||
### Test Rate Limiting
|
||||
```bash
|
||||
go test -v ./...
|
||||
# Automated testing
|
||||
for i in {1..6}; do
|
||||
curl -X POST http://localhost:3000/login \
|
||||
-d "otp=000000" \
|
||||
-d "next=/"
|
||||
echo "Attempt $i"
|
||||
done
|
||||
```
|
||||
|
||||
### Build for Different Platforms
|
||||
```bash
|
||||
# Linux
|
||||
GOOS=linux GOARCH=amd64 go build -o forward-auth-linux main.go
|
||||
# Linux (amd64)
|
||||
GOOS=linux GOARCH=amd64 go build -o forward-auth-linux-amd64 main.go
|
||||
|
||||
# macOS
|
||||
GOOS=darwin GOARCH=amd64 go build -o forward-auth-macos main.go
|
||||
# Linux (arm64) - for Raspberry Pi, etc.
|
||||
GOOS=linux GOARCH=arm64 go build -o forward-auth-linux-arm64 main.go
|
||||
|
||||
# macOS (Intel)
|
||||
GOOS=darwin GOARCH=amd64 go build -o forward-auth-macos-amd64 main.go
|
||||
|
||||
# macOS (Apple Silicon)
|
||||
GOOS=darwin GOARCH=arm64 go build -o forward-auth-macos-arm64 main.go
|
||||
|
||||
# Windows
|
||||
GOOS=windows GOARCH=amd64 go build -o forward-auth.exe main.go
|
||||
```
|
||||
|
||||
### Static Binary (no external dependencies)
|
||||
```bash
|
||||
CGO_ENABLED=1 go build -ldflags="-s -w" -o forward-auth main.go
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Log Examples
|
||||
|
||||
Successful login:
|
||||
```
|
||||
2025/11/04 10:23:45 Starting auth server on :3000
|
||||
```
|
||||
|
||||
Failed login attempt:
|
||||
```
|
||||
(Rate limiting is handled silently, check HTTP 429 responses in reverse proxy logs)
|
||||
```
|
||||
|
||||
### Prometheus Metrics (Future Enhancement)
|
||||
|
||||
Currently not implemented. Consider adding metrics for:
|
||||
- Total authentication attempts
|
||||
- Failed authentication attempts
|
||||
- Rate limit hits
|
||||
- Active sessions
|
||||
- Request latency
|
||||
|
||||
## Migration
|
||||
|
||||
### From Other Auth Systems
|
||||
|
||||
To migrate users:
|
||||
1. Generate a new TOTP seed: `./forward-auth -generate`
|
||||
2. Provide the seed to each user
|
||||
3. Users add it to their authenticator app
|
||||
4. Test login before decommissioning old system
|
||||
|
||||
### Updating JWT Secret
|
||||
```bash
|
||||
# 1. Generate new secret
|
||||
NEW_SECRET=$(openssl rand -base64 32)
|
||||
|
||||
# 2. Update environment variable
|
||||
export JWT_SECRET="$NEW_SECRET"
|
||||
|
||||
# 3. Restart service
|
||||
sudo systemctl restart forward-auth
|
||||
|
||||
# Note: All existing sessions will be invalidated
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
### Areas for Improvement
|
||||
|
||||
- [ ] Admin API for seed management
|
||||
- [ ] Web UI for seed generation
|
||||
- [ ] Prometheus metrics endpoint
|
||||
- [ ] Failed login attempt logging/auditing
|
||||
- [ ] Multiple database backend support
|
||||
- [ ] Session revocation
|
||||
- [ ] Account-specific rate limiting
|
||||
|
||||
## License
|
||||
|
||||
MIT License - see LICENSE file for details
|
||||
@@ -314,11 +604,35 @@ MIT License - see LICENSE file for details
|
||||
- [golang-jwt/jwt](https://github.com/golang-jwt/jwt) - JWT implementation
|
||||
- [pquerna/otp](https://github.com/pquerna/otp) - TOTP implementation
|
||||
- [mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) - SQLite driver
|
||||
- [Caddy](https://caddyserver.com/) - Modern web server with automatic HTTPS
|
||||
|
||||
## Support
|
||||
|
||||
For issues and questions, please open an issue on GitHub.
|
||||
For issues and questions:
|
||||
- Open an issue on GitHub
|
||||
- Check existing issues for solutions
|
||||
- Review the troubleshooting section above
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q: Can I use this with Nginx or Traefik?**
|
||||
A: Yes! Any reverse proxy that supports forward authentication will work. You'll need to configure it to send requests to the `/verify` endpoint.
|
||||
|
||||
**Q: How do I revoke a user's access?**
|
||||
A: Delete their TOTP seed from the database: `sqlite3 auth.db "DELETE FROM seeds WHERE id = X;"`
|
||||
|
||||
**Q: Can I change the session duration?**
|
||||
A: Yes, modify the `sessionDuration` constant in `main.go` and rebuild.
|
||||
|
||||
**Q: Is this suitable for production?**
|
||||
A: Yes, for small deployments (1-20 users). For larger deployments, consider enterprise authentication solutions.
|
||||
|
||||
**Q: What happens if I lose the database?**
|
||||
A: You'll need to regenerate seeds and have users re-add them to their authenticator apps. Keep backups!
|
||||
|
||||
**Q: Can I use this without Caddy?**
|
||||
A: Yes! It works with any reverse proxy that supports forward authentication (Nginx, Traefik, HAProxy, etc.).
|
||||
|
||||
---
|
||||
|
||||
**Note:** This is a simple authentication service suitable for personal or small team use. For larger deployments, consider more robust authentication solutions with features like account lockout, audit logging, and multi-factor authentication options.
|
||||
**Note:** This is a lightweight authentication service designed for personal or small team use. For enterprise deployments, consider solutions with additional features like SSO, LDAP integration, audit logging, and compliance certifications.
|
||||
Reference in New Issue
Block a user