Pulse/docs/PROXY_AUTH.md
rcourtman c91b7874ac docs: comprehensive v4.24.0 documentation audit and updates
Complete documentation overhaul for Pulse v4.24.0 release covering all new
features and operational procedures.

Documentation Updates (19 files):

P0 Release-Critical:
- Operations: Rewrote ADAPTIVE_POLLING_ROLLOUT.md as GA operations runbook
- Operations: Updated ADAPTIVE_POLLING_MANAGEMENT_ENDPOINTS.md with DEFERRED status
- Operations: Enhanced audit-log-rotation.md with scheduler health checks
- Security: Updated proxy hardening docs with rate limit defaults
- Docker: Added runtime logging and rollback procedures

P1 Deployment & Integration:
- KUBERNETES.md: Runtime logging config, adaptive polling, post-upgrade verification
- PORT_CONFIGURATION.md: Service naming, change tracking via update history
- REVERSE_PROXY.md: Rate limit headers, error pass-through, v4.24.0 verification
- PROXY_AUTH.md, OIDC.md, WEBHOOKS.md: Runtime logging integration
- TROUBLESHOOTING.md, VM_DISK_MONITORING.md, zfs-monitoring.md: Updated workflows

Features Documented:
- X-RateLimit-* headers for all API responses
- Updates rollback workflow (UI & CLI)
- Scheduler health API with rich metadata
- Runtime logging configuration (no restart required)
- Adaptive polling (GA, enabled by default)
- Enhanced audit logging
- Circuit breakers and dead-letter queue

Supporting Changes:
- Discovery service enhancements
- Config handlers updates
- Sensor proxy installer improvements

Total Changes: 1,626 insertions(+), 622 deletions(-)
Files Modified: 24 (19 docs, 5 code)

All documentation is production-ready for v4.24.0 release.
2025-10-20 17:20:13 +00:00

256 lines
8.1 KiB
Markdown

# Proxy Authentication
Pulse supports proxy-based authentication for integration with SSO providers like Authentik, Authelia, Caddy, and others. This allows you to authenticate users via your existing reverse proxy authentication system while maintaining security.
> **When to use this**: If you already have an authentication proxy (Authentik, Authelia, etc.) protecting your services and want Pulse to trust that authentication instead of requiring its own login.
## Quick Start
1. Set `PROXY_AUTH_SECRET` to a random secret string
2. Configure your proxy to send this secret in the `X-Proxy-Secret` header
3. Set `PROXY_AUTH_USER_HEADER` to match your proxy's username header
4. (Optional) Configure role-based access control with `PROXY_AUTH_ROLE_HEADER`
## Configuration
Set the following environment variables to enable proxy authentication:
### Required Settings
```bash
# Shared secret between proxy and Pulse (required)
PROXY_AUTH_SECRET=your-secure-secret-here
# Header containing the authenticated username (optional but recommended)
PROXY_AUTH_USER_HEADER=X-Authentik-Username
```
### Optional Settings
```bash
# Header containing user roles/groups
PROXY_AUTH_ROLE_HEADER=X-Authentik-Groups
# Separator for multiple roles (default: |)
PROXY_AUTH_ROLE_SEPARATOR=|
# Role name that grants admin access (default: admin)
PROXY_AUTH_ADMIN_ROLE=admin
# URL to redirect users to for logout
PROXY_AUTH_LOGOUT_URL=/outpost.goauthentik.io/sign_out
```
## How It Works
1. **User visits Pulse** → Your proxy intercepts the request
2. **Proxy authenticates user** → Via its own login page/SSO
3. **Proxy adds headers** to the request:
- `X-Proxy-Secret`: Shared secret (prevents spoofing)
- Username header (e.g., `X-Authentik-Username`)
- Roles header (e.g., `X-Authentik-Groups`)
4. **Pulse validates** the secret and trusts the user identity
5. **No Pulse login required** → User sees the dashboard immediately
## Example Configurations
### Authentik with Traefik
```yaml
# docker-compose.yml environment variables
environment:
- PROXY_AUTH_SECRET=your-secure-secret-here
- PROXY_AUTH_USER_HEADER=X-Authentik-Username
- PROXY_AUTH_ROLE_HEADER=X-Authentik-Groups
- PROXY_AUTH_ROLE_SEPARATOR=|
- PROXY_AUTH_ADMIN_ROLE=admin
- PROXY_AUTH_LOGOUT_URL=/outpost.goauthentik.io/sign_out
```
Traefik middleware configuration:
```yaml
http:
middlewares:
proxy-header-secret:
headers:
customRequestHeaders:
X-Proxy-Secret: "your-secure-secret-here"
authentik-auth:
forwardAuth:
address: http://authentik:9000/outpost.goauthentik.io/auth/traefik
trustForwardHeader: true
authResponseHeaders:
- X-Authentik-Username
- X-Authentik-Groups
- X-Authentik-Email
routers:
pulse:
rule: Host(`pulse.example.com`)
entryPoints:
- websecure
middlewares:
- authentik-auth
- proxy-header-secret
service: pulse-service
pulse-auth:
rule: Host(`pulse.example.com`) && PathPrefix(`/outpost.goauthentik.io/`)
entryPoints:
- websecure
service: authentik-outpost
```
### Authelia Example
```yaml
# docker-compose.yml environment variables
environment:
- PROXY_AUTH_SECRET=your-secure-secret-here
- PROXY_AUTH_USER_HEADER=Remote-User
- PROXY_AUTH_ROLE_HEADER=Remote-Groups
- PROXY_AUTH_ROLE_SEPARATOR=,
- PROXY_AUTH_ADMIN_ROLE=admins
- PROXY_AUTH_LOGOUT_URL=/logout
```
Nginx configuration:
```nginx
location / {
# Authelia authorization
auth_request /authelia;
auth_request_set $user $upstream_http_remote_user;
auth_request_set $groups $upstream_http_remote_groups;
# Pass headers to Pulse
proxy_set_header X-Proxy-Secret "your-secure-secret-here";
proxy_set_header Remote-User $user;
proxy_set_header Remote-Groups $groups;
proxy_pass_header X-RateLimit-Limit;
proxy_pass_header X-RateLimit-Remaining;
proxy_pass_header X-RateLimit-Reset;
proxy_pass_header Retry-After;
proxy_pass http://pulse:7655;
}
```
### Caddy with Forward Auth
```caddyfile
pulse.example.com {
forward_auth authelia:9091 {
uri /api/verify?rd=https://auth.example.com
copy_headers Remote-User Remote-Groups
}
header_downstream X-Proxy-Secret "your-secure-secret-here"
reverse_proxy pulse:7655
}
```
### Nginx Proxy Manager
In NPM's Advanced tab for your Pulse proxy host:
```nginx
# Custom Nginx Configuration
proxy_set_header X-Proxy-Secret "your-secure-secret-here";
proxy_set_header X-Authentik-Username $http_x_authentik_username;
proxy_set_header X-Authentik-Groups $http_x_authentik_groups;
```
## Security Considerations
1. **Use a strong secret**: Generate a secure random string for `PROXY_AUTH_SECRET`
2. **HTTPS only**: Always use HTTPS between the proxy and Pulse in production
3. **Network isolation**: Ensure Pulse is not directly accessible, only through the proxy
4. **Header validation**: Pulse validates all headers and the proxy secret on every request
5. **Preserve rate-limit headers**: Do not strip `X-RateLimit-*` or `Retry-After`. Clients rely on them when Pulse throttles requests.
## Combining with Other Auth Methods
Proxy authentication can work alongside other authentication methods:
- If `PROXY_AUTH_SECRET` is set, proxy auth takes precedence
- API tokens (`API_TOKENS` or legacy `API_TOKEN`) still work for programmatic access
- Basic auth (`PULSE_AUTH_USER`/`PULSE_AUTH_PASS`) can be used as fallback
## Troubleshooting
### Users can't access Pulse (401 Unauthorized)
1. **Check the secret header**:
```bash
# Test with curl
curl -H "X-Proxy-Secret: your-secret" \
-H "X-Authentik-Username: testuser" \
http://pulse:7655/api/state
```
2. **Verify headers are being sent**:
- Temporarily raise logging to debug via **Settings → System → Logging** (or set `LOG_LEVEL=debug` and restart). Remember to return to `info` when finished.
- Check Pulse logs: `docker logs pulse` or `journalctl -u pulse`
- Look for "Invalid proxy secret" or "Proxy auth user header not found"
3. **Common issues**:
- Typo in `PROXY_AUTH_SECRET`
- Header names are case-sensitive in configuration
- Proxy not forwarding headers correctly
### Admin features not available
Check if user is recognized as admin:
```bash
curl -H "X-Proxy-Secret: your-secret" \
-H "X-Authentik-Username: admin" \
-H "X-Authentik-Groups: users|admin" \
http://pulse:7655/api/security/status | jq '.proxyAuthIsAdmin'
```
- Ensure the roles header contains the admin role
- Verify `PROXY_AUTH_ADMIN_ROLE` matches your configuration
- Check the role separator matches your proxy's format (default: `|`)
### Logout doesn't work
- Verify `PROXY_AUTH_LOGOUT_URL` points to your proxy's logout endpoint
- Ensure the logout URL is accessible from the user's browser
- For Authentik: `/outpost.goauthentik.io/sign_out`
- For Authelia: `/logout` or custom path
### Testing your configuration
Test proxy auth without a reverse proxy:
```bash
# Should return 401
curl http://localhost:7655/api/state
# Should return 200 with state data
curl -H "X-Proxy-Secret: your-secret-here" \
-H "X-Your-User-Header: testuser" \
http://localhost:7655/api/state
```
## FAQ
**Q: Do I still need to set up Pulse authentication?**
A: No, when proxy auth is configured, Pulse trusts your proxy's authentication. Users won't see Pulse's login page.
**Q: Can I use this with Cloudflare Access or Tailscale?**
A: Yes, any service that can add custom headers after authentication will work.
**Q: What happens if someone bypasses my proxy?**
A: They can't authenticate. Without the correct `X-Proxy-Secret` header, all requests are rejected with 401.
**Q: Can I have some users with read-only access?**
A: Currently, Pulse has admin and non-admin roles. Non-admin users have read-only access to monitoring data.
**Q: Is the username displayed in Pulse?**
A: Yes, the authenticated username appears in the top-right corner of the UI.
**Q: Can I use both proxy auth and API tokens?**
A: Yes! API tokens still work for automation/scripts. Proxy auth is for human users via the web UI.