Header-only control token, masked secrets, loopback default (v0.9.9)

Finishes the small items of the security audit in
docs/prs/2026-07-08-PR#000: TODO 3, 4 and 7.

The three mutating endpoints of BuildsApiController no longer accept the
control token as a `token` query parameter — only the X-GitTally-Token
header, which the bundled UI has always used. URLs end up in access logs,
proxy logs, browser history and Referer headers, and the token never
expires, so a historical log capture would yield a valid credential.

`config:print` masks git.token as `***` on both the raw and the --full
path and names the new --show-secrets flag in a leading YAML comment, so
the output stays parseable when piped. The setup script points at
--show-secrets where it used to steer the operator to the plain token.

`server.bindAddress` now defaults to 127.0.0.1: neither the UI nor the
API authenticates read access, so reaching GitTally should require the
host's reverse proxy. Existing .gittally.yml files keep their explicit
value; the managed nginx container needs `0.0.0.0` set deliberately,
which is noted in the release notes, docs/configuration.md and
docs/deployment.md.

Released as v0.9.9, which also carries the previous two commits.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
mhoennig
2026-08-11 07:38:33 +02:00
co-authored by Claude
parent dea6770998
commit a4c995592f
12 changed files with 180 additions and 29 deletions
+13 -2
View File
@@ -38,6 +38,9 @@ java -jar build/libs/gittally.jar config:print # only explicitly set val
java -jar build/libs/gittally.jar config:print --full # all values including defaults
```
`git.token` is masked as `***` by default, so the output can safely be shared or pasted.
Add `--show-secrets` to print it in clear text.
## `.gittally.yml`
Values shown are the defaults.
@@ -48,8 +51,9 @@ server:
publicBaseUrl: https://ci.example.org/
# HTTP port of the `server` subcommand (default 18080, like legacy)
port: 18080
# bind address of the `server` subcommand
bindAddress: 0.0.0.0
# bind address of the `server` subcommand; loopback only, because the UI and the API
# are unauthenticated — set 0.0.0.0 only deliberately (see the note below)
bindAddress: 127.0.0.1
# optional Impressum (legal disclosure) link in the web UI footer; empty hides the link
impressumUrl: ""
# Opt-in managed nginx+certbot Docker container for HTTPS, for hosts without
@@ -172,6 +176,13 @@ branches:
- "04:00"
```
### Notes on `server.bindAddress`
The default is `127.0.0.1`.
Neither the web UI nor the JSON API authenticates read access, and every page carries the control token that unlocks the build controls, so GitTally is meant to sit behind the host's reverse proxy rather than on a public interface.
Set `0.0.0.0` only deliberately — for the managed nginx container (which reaches GitTally over the Docker bridge, not over loopback), or when the proxy runs on another host.
Installations created before v0.9.9 have `bindAddress: 0.0.0.0` written into their `.gittally.yml` and keep it; the new default only applies where the key is absent or `init` writes a fresh file.
### Notes on `server.nginx`
With `nginx.enabled`, the `server` subcommand also starts a managed nginx Docker container that serves GitTally over HTTPS (ADR 0005).