jfrog / jfrog/jfrog-cli-security
jf audit fails with 401 Unauthorized on SCA scan against an Xray HA cluster (regression since 2.103.0)
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 13
- Forks
- 50
- Avg merge
- 3d 48m
- Merged PRs (30d)
- 26
Description
Describe the bug
When running jf audit (SCA scan) against a JFrog Platform deployed in HA (multiple Xray nodes behind a load balancer), the scan fails with 401 Unauthorized / Authentication failed. The CLI authenticates correctly on the initial POST /api/v1/scan/graph call, but loses its authentication on the follow-up GET /api/v1/scan/graph/{scanId} polling call, which reaches the server as anonymous and is rejected with 401.
This looks like a regression introduced between 2.96.0 and 2.103.0.
Current behavior
failed to execute SCA scan: scanning NuGet dependencies failed with error: server response: 401 Unauthorized
{
"error": "Authentication failed"
}
Server-side xray-request-log for a single failing run (same trace ID, user xxxxx_rw):
xray-node-B | xxxxx_rw | POST /api/v1/scan/graph?watch=<watch>&scan_type=dependency | 201
xray-node-D | anonymous | GET /api/v1/scan/graph/<scanId> | 401
At the exact same time, another project on the same cluster using CLI 2.96.0 performs the same POST + GET sequence and stays authenticated on every node (including node-D), returning 202/200:
xray-node-C | yyyyy_rw | POST /api/v1/scan/graph | 201
xray-node-D | yyyyy_rw | GET /api/v1/scan/graph/<scanId> | 202 <- stays authenticated
xray-node-A | yyyyy_rw | GET /api/v1/scan/graph/<scanId> | 200
So the failure correlates with the CLI version, not with the server or the user.
On the Xray node that returns 401, the server log shows the auth-header login being rejected before falling back to anonymous:
[tokens] Failed to get LoginByAuthHeaderWithFallback. err:statusCode: 400
[authorization_filter] Failed to authenticate. err:Error: Authentication failed, StatusCode: 401
The POST /scan/graph succeeds (201); only the polling GET /scan/graph/{id} is anonymous. It fails whenever the load balancer routes the GET to a different Xray node than the one that served the POST — deterministic for versions >= 2.103.0, but appears "intermittent" because of normal HA load-balancer routing.
Reproduction steps
- JFrog Platform deployed in HA: Artifactory HA + multiple Xray nodes behind a load balancer without sticky sessions / session affinity.
- Configure the CLI server with user/password (or access token):
jf config add eul --url=https://<platform>/ --user=<user> --password=<pass> --interactive=false jf config use eul - Run an SCA audit that triggers Xray scan-graph polling:
jf audit --watches <watch> --extended-table --nuget=true - Repeat until the polling
GETis routed to a different Xray node than thePOST->failed to execute SCA scan: ... 401 Unauthorized.
Expected behavior
The polling GET /api/v1/scan/graph/{scanId} request must carry the same credentials / access token as the initial POST, so the scan result can be retrieved regardless of which node in an HA cluster the request is routed to (as was the case in 2.96.0).
JFrog CLI-Security version: bundled with JFrog CLI 2.103.0 / 2.105.0
JFrog CLI version (if applicable): 2.103.0 and 2.105.0 fail; 2.96.0 works
Operating system type and version: Linux amd64 (running inside a Jenkins agent container)
JFrog Artifactory version: 7.146.8 (HA, 3 primary nodes)
JFrog Xray version: 3.143.10 (HA cluster, 4 nodes behind a load balancer)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the jf audit SCA scan flow and trace the POST /api/v1/scan/graph request followed by polling GET /api/v1/scan/graph/{scanId}. Reproduce against the described Xray HA setup, comparing CLI 2.96.0 with 2.103.0 or later. Done means the polling request remains authenticated and retrieves scan results when routed to another Xray node.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, security
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100