passbolt/passbolt_api · error · BadRequestException

The authentication token should be a valid UUID.

Error message

The authentication token should be a valid UUID.

What it means

SsoAuthenticationTokenGetService::getOrFail validates that the provided SSO authentication token string is a UUID before querying the sso_authentication_tokens table. Non-UUID tokens are rejected immediately with a 400 BadRequestException instead of a record lookup.

Solutions

  1. Regenerate the SSO authentication token server-side (SsoAuthenticationTokenCreateService) and restart the flow with the fresh token
  2. Inspect the incoming token value in the request/URL; ensure it is a full UUID v4 string
  3. Check client code that constructs the SSO verify URL for truncation/encoding bugs (e.g. missing urlencode or string split)
  4. Ensure callers pass the sso_authentication_tokens id, not a session id or nonce

Example fix

// before
$token = $session->read('sso_token');
$ssoToken = $service->getOrFail($token, SsoAuthenticationToken::TYPE_SSO);

// after
$token = $session->read('sso_token');
if ($token === null || !Validation::uuid($token)) {
    throw new BadRequestException(__('Missing or malformed SSO token.'));
}
$ssoToken = $service->getOrFail($token, SsoAuthenticationToken::TYPE_SSO);
Defensive patterns

Strategy: validation

Validate before calling

use Cake\Validation\Validation;
if (!Validation::uuid($token)) {
    throw new BadRequestException(__('The authentication token should be a valid UUID.'));
}
if (isset($userId) && !Validation::uuid($userId)) {
    throw new BadRequestException(__('The user id should be a valid UUID.'));
}

Type guard

function isUuid(?string $value): bool
{
    return $value !== null && \Cake\Validation\Validation::uuid($value);
}

Try / catch

try {
    $token = $service->getOrFail($token, SsoAuthenticationToken::TYPE_SSO, $userId);
} catch (BadRequestException $e) {
    // token/userId not a UUID: restart the SSO flow with a fresh token
} catch (RecordNotFoundException $e) {
    // token well-formed but unknown/expired
}

Prevention

When it happens

Trigger: Passing a malformed token (truncated string, base64/JWT-like value, empty string, or non-token identifier) to getOrFail, or to its callers getActiveNotExpiredOrFail/get/activate when handling an SSO callback whose token parameter was corrupted or misconstructed.

Common situations: Client-side URL mangling truncating the token in the SSO redirect; passing an SSO session id instead of the authentication token; older client version building the verify URL incorrectly; copy/paste dropping characters; token generated by a different mechanism.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/674dfc4ea4921ee6. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Sso/src/Service/SsoAuthenticationTokens/SsoAuthenticationTokenGetService.php:64

     * Constructor
     */
    public function __construct()
    {
        $this->SsoAuthenticationTokens = $this->fetchTable('Passbolt/Sso.SsoAuthenticationTokens');
    }

    /**
     * @param string $token token
     * @param string $type type
     * @param string|null $userId uuid
     * @throws \Cake\Http\Exception\BadRequestException if the authentication token is invalid
     * @throws \Cake\Datasource\Exception\RecordNotFoundException if the authentication token cannot be found
     * @return \Passbolt\Sso\Model\Entity\SsoAuthenticationToken
     */
    public function getOrFail(string $token, string $type, ?string $userId = null): SsoAuthenticationToken
    {
        if (!Validation::uuid($token)) {
            throw new BadRequestException(__('The authentication token should be a valid UUID.'));
        }
        if (isset($userId) && !Validation::uuid($userId)) {
            throw new BadRequestException(__('The user id should be a valid UUID.'));
        }

        try {
            $where = [
                'token' => $token,
                'type' => $type,
                'active' => true,
            ];
            if (isset($userId)) {
                $where['user_id'] = $userId;
            }

            /** @var \Passbolt\Sso\Model\Entity\SsoAuthenticationToken $tokenEntity */
            $tokenEntity = $this->SsoAuthenticationTokens->find()->where($where)->firstOrFail();
        } catch (RecordNotFoundException $exception) {

View on GitHub (pinned to 31c1bbc10f)