28Hus opened a new pull request, #1061: URL: https://github.com/apache/dubbo-go-pixiu/pull/1061
# fix(admin): replace the shared JWT fallback with a process-local key Fixes #976. PR #978 added an environment override and rejected non-HMAC signing methods, but an unset or empty override still selected the source-published shared key. This PR removes that remaining default-key path while preserving a zero-configuration single-instance startup. ## Threat model and scope The attacker must be able to reach the Pixiu admin HTTP listener, and the deployment must have left `DUBBOGO_PIXIU_JWT_SIGN_KEY` unset or empty. Before this change, those deployments used the same publicly known signing key. The admin router places configuration endpoints behind `JWTAuth()`, which validates the JWT signature and applicable time claims but does not bind the token to a server-side session or look up the token's username before allowing the request through. A token signed with the shared key could therefore pass this middleware without being issued by the application's login flow. The effect of reaching any particular handler depends on that handler's additional checks; this PR does not claim that every endpoint grants administrator privileges. `/register` is also public; a newly registered account can obtain a legitimately issued token through `/login`. Removing the shared signing key does not address registration policy, handler-level user/role authorization, or token-to-request identity binding. Those are separate trust boundaries and are not changed here. ## Changes - When `DUBBOGO_PIXIU_JWT_SIGN_KEY` is unset or empty, generate 32 random bytes with `crypto/rand` once per process and keep the resulting key in memory only. - Use an explicitly configured key when present. Reject short keys and the former shared default before initializing the server; propagate generation/configuration errors through JWT creation and verification. - Accept only HS256 for admin JWTs, matching the algorithm used to issue them. - Allow a blank key in Docker Compose, provide an empty example, and document the persistence tradeoff and optional external key configuration. - Add regression coverage for stable per-process generation under concurrent calls, unsafe configured keys, legacy-signed tokens, unexpected HMAC algorithms, and the protected-route boundary. ## Deployment and compatibility Single-instance deployments can continue starting without a configured key, but their admin JWTs become invalid on backend restart because the automatically generated key is not persisted. Existing JWTs signed with the former default are also invalidated on upgrade. Multiple replicas must receive the same unique random key of at least 32 bytes through an environment variable or secret manager; otherwise each replica generates its own key and cannot verify tokens issued by another. An explicitly configured former-default or short key is rejected rather than silently replaced. No default key is written to a local file; deployments that supply their own key remain responsible for protecting it. This change does not defend against process-memory compromise. This PR changes the admin JWT key and signing-method checks only. It does not alter user/role authorization decisions in individual handlers. ## Verification - `GOMAXPROCS=2 go test -p 1 -count=1 ./admin/controller/auth` — passed. - `GOMAXPROCS=2 go test -p 1 -count=1 ./admin/core -run '^TestRunServerRejectsUnsafeConfiguredJWTKeyBeforeInitialization$'` — passed. - `GOMAXPROCS=2 go test -p 1 -run '^$' -count=1 ./admin/controller/account ./cmd/admin` — passed (compile-only). - `GOMAXPROCS=2 go test -p 1 ./admin/initialize -run '^TestOPARoutes_(NoTokenRejected|PutUsesBootstrapDefaults)$' -count=1` — passed with an in-memory OPA server. - `docker compose config --quiet` — accepts both an unset key and a configured key. The `pkg/config/xds` compile-only check was stopped when it began downloading a large set of unrelated dependencies; it is not counted as passed. No full multi-container deployment or live-service test was run; the security boundary is covered by targeted unit and in-memory router tests. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
