Skip to content

App visible to all users regardless of roles (starting from 8.8) #31600

@hilalbursalii

Description

@hilalbursalii

Description

Starting in 8.8, the app switcher no longer checks user permissions before displaying available applications. As a result, Optimize is now visible to all users, even if they lack the appropriate access rights. For instance, Developer role can view Optimize even though they do not have the permissions.

Here is the conversation thread.

Steps to reproduce

  1. Use a user account with Developer role
  2. Observe that Optimize appears in the app switcher
  3. Click Optimize and observe user can access the app.

Current behavior

Optimize appears in the app switcher and is accessible to all users, regardless of their roles.

Expected behavior

Optimize should validate user permissions or roles independently before granting access.

Environment

SaaS

Version

8.8 SNAPHOST

Rootcause

No response

Solution ideas

Approach Overview

  • Whenever a user requests access to Optimize, parse their org membership and roles from the JWT claims (https://camunda.com/orgs).
  • Allow access if the user holds at least one valid role (such as "admin", "analyst") in any org. The valid roles list can be hardcoded initially, then made configurable.
  • Implement validation within the Optimize backend, preferably as part of the JWT decoding/request filtering (not in the app switcher or frontend).
  • Follow the validator pattern already present in Optimize (e.g., AudienceValidator, ScopeValidator) or as seen in the OrganizationValidator of the authentication module.

Key Classes and Locations to Update

  • Update authentication and JWT config in:
    optimize/backend/src/main/java/io/camunda/optimize/rest/security/ccsm/CCSMSecurityConfigurerAdapter.java. This is the main class for Spring Security config, including JWT decoder setup.
  • Add a new role validator (e.g., OptimizeRoleValidator) or extend validation logic in the existing hasAccess() method in this class.
  • (Optional) If you have recurring role/group extraction or want reusable logic, add a utility or helper in:
    optimize/backend/src/main/java/io/camunda/optimize/service/security/

JWT Claims Parsing and Validation Flow

Use the JwtDecoder (configured in CCSMSecurityConfigurerAdapter) to decode incoming JWTs.
Extract the https://camunda.com/orgs claim, which is a list of org objects. Each org object contains:

  • "id" (string)
  • "roles" (array of strings, e.g., ["admin"], ["analyst", "developer"])

Sample Java extraction:

JwtAuthenticationToken auth = (JwtAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
Jwt jwt = auth.getToken();
Object orgsClaim = jwt.getClaims().get("https://camunda.com/orgs");
List<String> allowedRoles = Arrays.asList("admin", "analyst"); // Make this configurable later
boolean hasAccess = false;

if (orgsClaim instanceof List<?>) {
    for (Object entry : (List<?>) orgsClaim) {
        if (entry instanceof Map<?, ?>) {
            List<String> roles = (List<String>) ((Map<?, ?>) entry).get("roles");
            if (roles != null && roles.stream().anyMatch(allowedRoles::contains)) {
                hasAccess = true;
                break;
            }
        }
    }
}
if (!hasAccess) {
    throw new ForbiddenException("Missing required organization role for Optimize access");
}

Place this logic as:

A custom validator in the JWT pipeline (preferred for consistency), or

An explicit check inside hasAccess(), which intercepts or authorizes all routes.

Validator Implementation Pattern

  • Create an OptimizeRoleValidator class, similar to OrganizationValidator in the authentication module, to handle parsing and validation of org roles.
  • Register and wire up this validator so it's executed as part of the JWT decoding or access filter pipeline in CCSMSecurityConfigurerAdapter.

Configuration and Extensibility Notes

  • For now, the valid roles list (e.g., "admin", "analyst") can be specified as a static List in the validator.
  • To make the list dynamic, fetch it from configuration (application properties, environment variable, or central platform config).

Example:

@Value("${optimize.allowed-org-roles:admin,analyst}")
private List<String> allowedRoles;

Now we can update roles without redeploying code.

Dev -> QA handover

The Optimize tests here should work

  • Resources:
  • Versions to validate:
  • Release version (in which version this feature will be released):

Links

No response

Metadata

Metadata

Labels

affects/8.8Issue is affecting 8.8 minor versionscomponent/optimizeRelated to Optimize component/teamkind/bugCategorizes an issue or PR as a buglikelihood/highA recurring issueqa/automation-foundThis bug was caught by an automated regression test suiteseverity/highMarks a bug as having a noticeable impact on the user with no known workaroundversion:8.8.0-alpha8version:8.8.0-alpha8-rc1

Type

Projects

Status

In Progress

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions