Hi everyone,
I’m trying to use JWT Authentication but I consistently receive 404:
{
"header": {
"id": "e9139c26-4c6f-4e52-bf7e-05d11f7401c7",
"status": "error",
"servertime": 1758029601,
"action": "28c0972b-e6a2-5d44-a5cb-bc2d11799cc1",
"message": "The user does not exist or is not active or has been deleted.",
"url": "/auth/jwt/login.json",
"code": 404
},
"body": ""
}
Server log:
2025-09-16 13:33:21 error: [Cake\Http\Exception\NotFoundException]
The user does not exist or is not active or has been deleted.
in /usr/share/php/passbolt/plugins/PassboltCe/JwtAuthentication/src/Controller/JwtLoginController.php on line 77
Environment
- Passbolt CE 5.4.1
What I have verified
- User exists and is active in the database
SELECT id, username, active, deleted FROM users
WHERE id = '<USER_UUID>';
-- returns: active=1, deleted=0
SELECT user_id, fingerprint, deleted FROM gpgkeys
WHERE user_id = '<USER_UUID>';
-- returns: fingerprint = 58E98A725953255F37AF622B4B903A6E7B2AA0E6, deleted=0
- PGP challenge is correct (sign-then-encrypt)
-
Encrypted to the server public key from
GET /auth/verify.json(recipient keyid matches). -
Signed with the user’s private key (GnuPG shows Good signature) with fingerprint:
58E9 8A72 5953 255F 37AF 622B 4B90 3A6E 7B2A A0E6. -
Decrypting locally (for debugging) shows this inner JSON:
{
"version": "1.0.0",
"domain": "https://<my-passbolt-domain>",
"verify_token": "9640cd11-b6ed-4246-9774-61625b1660d7",
"verify_token_expiry": 1757705719
}
(Expiry is an integer epoch in the future; token is UUID with hyphens.)
- HTTP flow / CSRF
-
I request
csrfTokenviaGET /auth/verify.jsonand send it back on the POST (cookie +X-CSRF-Token), withContent-Type: application/json. -
Minimal repro:
# 1) get csrf + cookies
curl -sS -c cookies.txt https://<my-passbolt-domain>/auth/verify.json >/dev/null
CSRF=$(awk '/csrfToken/ {print $7}' cookies.txt)
# 2) send the armored PGP challenge
CH=$(jq -Rs . < challenge.asc)
# 3) POST login
curl -i -b cookies.txt \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: $CSRF" \
-d "{\"user_id\":\"<USER_UUID>\",\"challenge\":$CH}" \
https://<my-passbolt-domain>/auth/jwt/login.json
# → consistently returns 404 (same message)
Ask
Given the validations above (user active, GPG key present and matching, PGP challenge valid, CSRF handled), what else should I check to understand why /auth/jwt/login.json returns 404 (FAILURE_IDENTITY_NOT_FOUND) in this scenario?
Thanks!