docs(apiserver): document security defaults changed by bug-1945..1952

deployment.md: auth.yaml now holds bcrypt hashes of the (still public)
dev credentials with startup warnings; JWT secret from XCE_JWT_SECRET or a
random per-process secret; logout revocation is per process;
security.trusted_proxies for reverse proxies.
security.md steering: JWT parsing, revocation, secret resolution,
trusted proxies, middleware abort rule, bcrypt and role-change rule.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Rongsong Shen 2026-10-10 08:43:31 +00:00
parent a80768f31d
commit 27ef506058
Signed by untrusted user: rshen
GPG key ID: 80533536B0EB651C
2 changed files with 13 additions and 4 deletions

View file

@ -33,11 +33,17 @@ Permissions are defined in `config/rbac.yaml`. Roles support inheritance via `in
Token flow:
1. `POST /auth/logon` → validates credentials via configured auth backend → issues JWT with `{username, IP, expiry}` claims
2. Every subsequent request: `Authorization: Bearer <token>` header
3. `middleware/validatehandler.go` strips the prefix, parses with golang-jwt, **validates the IP claim against the request IP**
3. `middleware/validatehandler.go` strips the prefix, parses with golang-jwt via `controllers.ParseTokenClaims` (HS256 only, revocation checked), **validates the IP claim against the request IP**
IP-bound tokens prevent token theft across network boundaries. Do not remove the IP validation.
IP-bound tokens prevent token theft across network boundaries. Do not remove the IP validation. The request IP is `ctx.ClientIP()`, which honours `X-Forwarded-For`/`X-Real-IP` only from `app.yaml` `security.trusted_proxies` (default none, bug-1948).
Token secret is loaded from `config/auth.yaml` at startup. It must never appear in source code or logs.
Every parse path uses `controllers.JWTKeyFunc` + `JWTValidMethods()` (pinned to `JWTSigningMethod`, HS256, bug-1950). Logout revokes the token's `jti` until its expiry in an in-memory set (`controllers/token_revocation.go`, bug-1946): per process, not persisted, not shared between apiservers.
Token secret: `XCE_JWT_SECRET`, else `app.yaml` `authentication.token.secretKey` (shipped empty). Empty or the old public default `xce-api-key` means unset: a random per-process secret is generated with a startup warning (bug-1945). It must never appear in source code or logs.
Middleware that rejects a request must call `ctx.Abort()` after `ReturnError` (which only writes the response, bug-1949).
Config-file auth (`backend/auth/config_file.go`) accepts bcrypt hashes (recommended) or plaintext (compared in constant time); startup warns for plaintext entries and for shipped default credentials (bug-1947). Only `rbac:control` with scope `all` may grant or revoke user roles (bug-1952).
## Auth Backends