Refactor auth and monitoring docs to be concise

This commit is contained in:
courtmanr@gmail.com 2025-11-25 00:26:00 +00:00
parent 21a489cbec
commit ff18ed4064
4 changed files with 178 additions and 1487 deletions

View file

@ -1,256 +1,72 @@
# Proxy Authentication
# 🛡️ 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.
Authenticate users via your existing reverse proxy (Authentik, Authelia, Cloudflare Zero Trust, etc.).
> **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
## Quick Start
1. **Generate Secret**: Create a strong random string.
2. **Configure Pulse**:
```bash
PROXY_AUTH_SECRET=your-random-secret
PROXY_AUTH_USER_HEADER=X-Authentik-Username
```
3. **Configure Proxy**: Set the proxy to send `X-Proxy-Secret` and the user header.
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
## Configuration
| Variable | Description | Default |
| :--- | :--- | :--- |
| `PROXY_AUTH_SECRET` | **Required**. Shared secret to verify requests. | - |
| `PROXY_AUTH_USER_HEADER` | **Required**. Header containing the username. | - |
| `PROXY_AUTH_ROLE_HEADER` | Header containing user groups/roles. | - |
| `PROXY_AUTH_ADMIN_ROLE` | Role name that grants admin access. | `admin` |
| `PROXY_AUTH_LOGOUT_URL` | URL to redirect to after logout. | - |
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
## 📦 Examples
### Authentik (with Traefik)
**docker-compose.yml**:
```yaml
# docker-compose.yml environment variables
environment:
- PROXY_AUTH_SECRET=your-secure-secret-here
- PROXY_AUTH_SECRET=secure-secret
- 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:
**Traefik Middleware**:
```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
headers:
customRequestHeaders:
X-Proxy-Secret: "secure-secret"
```
### 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:
### Authelia (Nginx)
```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_set_header X-Proxy-Secret "secure-secret";
proxy_set_header Remote-User $upstream_http_remote_user;
proxy_pass http://pulse:7655;
}
```
### Caddy with Forward Auth
### Cloudflare Tunnel
1. **Zero Trust Dashboard**: Applications → Add Application.
2. **Settings**: HTTP Settings → HTTP Headers.
3. **Add Header**: `X-Proxy-Secret` = `your-secret`.
4. **Pulse Config**: `PROXY_AUTH_USER_HEADER=Cf-Access-Authenticated-User-Email`.
```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
}
```
## 🔧 Troubleshooting
### Nginx Proxy Manager
| Issue | Check |
| :--- | :--- |
| **401 Unauthorized** | Verify `X-Proxy-Secret` matches `PROXY_AUTH_SECRET`. Check if headers are being stripped by intermediate proxies. |
| **Not Admin** | Verify `PROXY_AUTH_ROLE_HEADER` is set and contains `PROXY_AUTH_ADMIN_ROLE`. |
| **Logout Fails** | Ensure `PROXY_AUTH_LOGOUT_URL` is set to your IdP's logout endpoint. |
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:
### Verify Headers
Use `curl` to simulate a proxy request:
```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.