mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-15 00:21:57 +00:00
Refactor auth and monitoring docs to be concise
This commit is contained in:
parent
21a489cbec
commit
ff18ed4064
4 changed files with 178 additions and 1487 deletions
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue