Skip to content

ServicePulse hard-codes the offline_access scope instead of using the scope ServiceControl provides #3078

Description

@WilliamBZA

Describe the bug

Description

ServicePulse assembles its OIDC scope request client-side, appending a fixed suffix to the configured API scope:

// src/Frontend/src/stores/AuthStore.ts:64
scope: `${apiScope} openid profile email offline_access`,

offline_access is hard-coded here rather than coming from ServiceControl's AuthenticationController.Configuration() response, which is where every other part of the OIDC client configuration (authority, client ID, audience, API scopes) comes from. Not all identity providers permit offline_access for a given client, and there is currently no way to stop ServicePulse requesting it.

Particular/ServiceControl#5633 proposes that ServiceControl compose the full scope string (including whether offline_access is present, controlled by a new Authentication.ServicePulse.OfflineAccessScopeEnabled setting) and expose it as Scopes on AuthConfig. This issue tracks the companion ServicePulse change to consume that value instead of assembling the scope string itself.

Expected behavior

ServicePulse uses the scope string returned by ServiceControl's auth configuration when present. When talking to an older ServiceControl that doesn't return it, ServicePulse falls back to its current behaviour of assembling api_scopes plus openid profile email offline_access, so existing deployments are unaffected.

Actual behavior

offline_access is always requested, with no way for an operator to opt out short of editing ServicePulse's source. When the configured identity provider doesn't permit offline_access for the client, the authorization request is rejected outright and the user never reaches a login page - the failure is total, not degraded, and the resulting error doesn't identify offline_access as the cause.

Versions

Applies to all current ServicePulse versions that use AuthStore.ts for OIDC sign-in. Depends on the corresponding ServiceControl change in #5633 being available before there is a Scopes field to consume.

Steps to reproduce

  1. Configure ServicePulse's identity provider connection against a client/app registration that does not permit the offline_access scope.
  2. Attempt to sign in to ServicePulse.
  3. Observe that the authorization request fails before reaching the identity provider's login page, since offline_access is unconditionally included in the requested scope and there is no configuration option to remove it.

Relevant log output

N/A

Additional Information

Workarounds

None available through configuration. Removing offline_access currently requires a source change to AuthStore.ts.

Possible solutions

Additional information

From #5633: without offline_access, some identity providers don't issue a refresh token, so ServicePulse falls back to a hidden iframe silent-renew against the IdP session cookie. Browsers that restrict third-party cookies (Safari ITP, Brave, Chrome's ongoing restrictions) will fail that request, forcing a full-page re-authentication redirect at every token expiry - with a live IdP session this is a brief round-trip that loses in-app state, and without one the user is dropped back to the login page mid-session. This is a secondary reason to keep offline_access enabled by default and make disabling it an explicit, informed operator choice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions