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]

Reply via email to