Before: with AUTH_USER empty (the default), anyone on the network could read every log, change the sources and purge everything (ALLOW_PURGE=true), with no warning in the UI. Every logged-in user had full rights. There were no security headers, a third-party page could send changes from the browser (CSRF), and syslog TCP accepted unlimited connections that never timed out.
After: purge is off unless ALLOW_PURGE=true. Without authentication, the UI shows a warning banner (it can be closed). A read-only role can search, follow the live view and export, but cannot change tags, sources or purge: the API answers 403 and those settings are greyed out. Answers carry a CSP and the usual security headers, and cross-site changes are refused. Syslog TCP keeps at most 512 connections and closes one after 30 minutes of silence.
How:
guard.go: secure() adds the headers, rejects non-GET requests whose Sec-Fetch-Site or Origin shows another site (curl and scripts send neither and keep working), and answers /auth/me with mode: none when there is no auth. readOnly() refuses API changes from viewers. The CSP allows the inline scripts of index.html and login.html by hash, computed at startup from the embedded files.
Local mode: optional AUTH_VIEWER_USER / AUTH_VIEWER_PASS, also usable with Basic auth. OIDC: OIDC_ADMIN_GROUP (+ OIDC_GROUPS_CLAIM, default groups, Keycloak's leading / ignored). The role is stored in the signed session cookie; existing sessions stay admin.
SYSLOG_TCP_MAX_CONNS (512) and SYSLOG_TCP_IDLE (30m, a sliding read deadline); HTTP IdleTimeout of 2 min.
.env.example, docker-compose.yml and both READMEs updated.
Tests: headers and cross-site cases, CSP hashes, local viewer (session and Basic), OIDC admin group, TCP idle deadline. go test -race passes.
Note: ALLOW_PURGE now defaults to false. A deployment that relied on the old default must set ALLOW_PURGE=true in .env.
<!-- ccr-projects-attribution: {"github_login":"vblogio"} -->
_Requested by **Cédric**_
Before: with `AUTH_USER` empty (the default), anyone on the network could read every log, change the sources and purge everything (`ALLOW_PURGE=true`), with no warning in the UI. Every logged-in user had full rights. There were no security headers, a third-party page could send changes from the browser (CSRF), and syslog TCP accepted unlimited connections that never timed out.
After: purge is off unless `ALLOW_PURGE=true`. Without authentication, the UI shows a warning banner (it can be closed). A read-only role can search, follow the live view and export, but cannot change tags, sources or purge: the API answers 403 and those settings are greyed out. Answers carry a CSP and the usual security headers, and cross-site changes are refused. Syslog TCP keeps at most 512 connections and closes one after 30 minutes of silence.
How:
- `guard.go`: `secure()` adds the headers, rejects non-GET requests whose `Sec-Fetch-Site` or `Origin` shows another site (curl and scripts send neither and keep working), and answers `/auth/me` with `mode: none` when there is no auth. `readOnly()` refuses API changes from viewers. The CSP allows the inline scripts of `index.html` and `login.html` by hash, computed at startup from the embedded files.
- Local mode: optional `AUTH_VIEWER_USER` / `AUTH_VIEWER_PASS`, also usable with Basic auth. OIDC: `OIDC_ADMIN_GROUP` (+ `OIDC_GROUPS_CLAIM`, default `groups`, Keycloak's leading `/` ignored). The role is stored in the signed session cookie; existing sessions stay admin.
- `SYSLOG_TCP_MAX_CONNS` (512) and `SYSLOG_TCP_IDLE` (30m, a sliding read deadline); HTTP `IdleTimeout` of 2 min.
- `.env.example`, `docker-compose.yml` and both READMEs updated.
- Tests: headers and cross-site cases, CSP hashes, local viewer (session and Basic), OIDC admin group, TCP idle deadline. `go test -race` passes.
Note: `ALLOW_PURGE` now defaults to false. A deployment that relied on the old default must set `ALLOW_PURGE=true` in `.env`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- ALLOW_PURGE is now false by default; the UI shows a banner when there is
no authentication.
- Read-only role: AUTH_VIEWER_USER/AUTH_VIEWER_PASS in local mode, or
OIDC_ADMIN_GROUP in OIDC mode; changes get 403 and the admin settings
are greyed out.
- Content-Security-Policy (inline scripts allowed by hash) and other
security headers; cross-site changes are refused.
- Syslog TCP: at most SYSLOG_TCP_MAX_CONNS connections, closed after
SYSLOG_TCP_IDLE of silence; HTTP idle timeout.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
claudeBot
marked the pull request as ready for review 2026-10-03 16:39:31 +02:00
claudeBot
merged commit 2f84bc8deb into main2026-10-03 16:39:50 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Requested by Cédric
Before: with
AUTH_USERempty (the default), anyone on the network could read every log, change the sources and purge everything (ALLOW_PURGE=true), with no warning in the UI. Every logged-in user had full rights. There were no security headers, a third-party page could send changes from the browser (CSRF), and syslog TCP accepted unlimited connections that never timed out.After: purge is off unless
ALLOW_PURGE=true. Without authentication, the UI shows a warning banner (it can be closed). A read-only role can search, follow the live view and export, but cannot change tags, sources or purge: the API answers 403 and those settings are greyed out. Answers carry a CSP and the usual security headers, and cross-site changes are refused. Syslog TCP keeps at most 512 connections and closes one after 30 minutes of silence.How:
guard.go:secure()adds the headers, rejects non-GET requests whoseSec-Fetch-SiteorOriginshows another site (curl and scripts send neither and keep working), and answers/auth/mewithmode: nonewhen there is no auth.readOnly()refuses API changes from viewers. The CSP allows the inline scripts ofindex.htmlandlogin.htmlby hash, computed at startup from the embedded files.AUTH_VIEWER_USER/AUTH_VIEWER_PASS, also usable with Basic auth. OIDC:OIDC_ADMIN_GROUP(+OIDC_GROUPS_CLAIM, defaultgroups, Keycloak's leading/ignored). The role is stored in the signed session cookie; existing sessions stay admin.SYSLOG_TCP_MAX_CONNS(512) andSYSLOG_TCP_IDLE(30m, a sliding read deadline); HTTPIdleTimeoutof 2 min..env.example,docker-compose.ymland both READMEs updated.go test -racepasses.Note:
ALLOW_PURGEnow defaults to false. A deployment that relied on the old default must setALLOW_PURGE=truein.env.🤖 Generated with Claude Code