passbolt/passbolt_api · error · SsoEgressBlockedException

Single sign-on failed. The provider address is not allowed.

Error message

Single sign-on failed. The provider address is not allowed.

What it means

SsoEgressGuardMiddleware validates every outgoing SSO provider request (and redirect hop) against the SsoEgressGuard allowlist. If the destination host is not allowed and passbolt.security.sso.egress.block is true, it throws SsoEgressBlockedException with this message; in warn-only mode (block=false) it only logs a warning and lets the request through. This is an SSRF mitigation: it prevents a user-supplied provider URL from pointing the server at internal addresses.

Solutions

  1. Check the error log for 'SSO egress guard blocked a request.' plus the reason to see which host and why it was blocked.
  2. Add the provider's hostname to the SSO egress allowlist in passbolt configuration (passbolt.security.sso.egress settings).
  3. Fix the SSO provider URL configured in passbolt if it was mistyped or points to an internal address.
  4. Ensure redirect targets of your IdP are also allowed — every redirect hop is re-validated.
  5. Temporarily set passbolt.security.sso.egress.block=false to run warn-only while diagnosing, then re-enable blocking once the allowlist is correct.

Example fix

// before (config/passbolt.php)
'egress' => ['block' => true, 'allow' => ['login.microsoftonline.com']],
// after: allowlist the self-hosted ADFS host
'egress' => ['block' => true, 'allow' => ['login.microsoftonline.com', 'adfs.corp.example.com']],
Defensive patterns

Strategy: try-catch

Validate before calling

$host = (new Uri($providerUrl))->getHost();
if ((new SsoEgressGuard())->getBlockReason($host) !== null) {
    // refuse to configure/use this provider URL before any HTTP call is made
}

Try / catch

try {
    $client = SsoHttpClientFactory::create();
    $response = $client->send($request);
} catch (\Passbolt\Sso\Error\Exception\SsoEgressBlockedException $e) {
    $this->log($e->getMessage() . ' (check egress allowlist for the provider host)');
    return $this->renderError('sso', 'Provider address is not allowed by server policy.');
}

Prevention

When it happens

Trigger: Any SSO provider HTTP call (Azure/Google OAuth2, ADFS, PingOne) whose request host fails SsoEgressGuard::getBlockReason() — e.g. an ADFS/PingOne endpoint URL set to an internal host or IP, a redirect to a disallowed host, or a allowlist in passbolt.php that does not cover the configured provider domain.

Common situations: Admin configuring a self-hosted ADFS server but forgetting to allowlist its hostname in the SSO egress settings; provider redirecting to a different domain not on the allowlist; hardened installs (block=true) in air-gapped networks; DNS or URL typos pointing at internal addresses.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at plugins/PassboltEe/Sso/src/Utility/Http/SsoEgressGuardMiddleware.php:65

    /**
     * Block the request (or warn) when its destination is not allowed by the egress guard.
     *
     * @param \Psr\Http\Message\RequestInterface $request The outgoing request.
     * @return void
     * @throws \Passbolt\Sso\Error\Exception\SsoEgressBlockedException When blocking is enabled and the host is blocked.
     */
    private function assertAllowed(RequestInterface $request): void
    {
        $host = $request->getUri()->getHost();
        $reason = (new SsoEgressGuard())->getBlockReason($host);
        if ($reason === null) {
            return;
        }

        if ((bool)Configure::read(self::CONFIG_BLOCK, false)) {
            Log::error('SSO egress guard blocked a request. ' . $reason);
            throw new SsoEgressBlockedException(
                __('Single sign-on failed.') . ' ' . __('The provider address is not allowed.')
            );
        }

        // Warn-only mode: log and let the request through.
        Log::warning('SSO egress guard (warn-only) flagged a request. ' . $reason);
    }
}

View on GitHub (pinned to 31c1bbc10f)