Skip to content

Custom IAM roles hidden when storage-manager-role exists in account #1135

@eve-scality

Description

@eve-scality

Identified by automated analysis of ARTESCA-17287
Confidence: high

What needs to change

File: src/react/ui-elements/SelectAccountIAMRole.tsx
Version: 4.2.15
Remove the storageManagerFiltered logic from both components. The assumption that storage-manager-role is a superset of all other roles is incorrect for custom IAM roles.

In SelectAccountIAMRole.tsx (lines 169-171):
Remove the storageManagerFiltered variable and use unfilteredRoles directly:

// Remove these lines:
// const storageManagerFiltered = unfilteredRoles.some((r) => r.RoleName === STORAGE_MANAGER_ROLE)
//     ? unfilteredRoles.filter((r) => r.RoleName === STORAGE_MANAGER_ROLE)
//     : unfilteredRoles;

const roles = props.filterOutInternalRoles
    ? unfilteredRoles.filter((role) => {
        return (
          role.RoleName === STORAGE_MANAGER_ROLE ||
          SCALITY_IAM_ROLES.includes(role.RoleName) ||
          !role.Arn.includes('role/scality-internal')
        );
      })
    : unfilteredRoles;

In AccountRoleSelectButtonAndModal.tsx (lines 119-122):
Remove the storageManagerRoles filtering and return parsedRoles directly:

// Remove these lines:
// const storageManagerRoles = parsedRoles.filter(
//   (role) => role.roleName === STORAGE_MANAGER_ROLE,
// );
// return storageManagerRoles.length > 0 ? storageManagerRoles : parsedRoles;
return parsedRoles;

If the original intent of ZKUI-475 was to hide only the built-in Scality internal roles (not custom ones) when storage-manager-role is present, the filter should instead only suppress the other Scality internal roles (storage-account-owner-role, data-consumer-role, data-accessor-role) while keeping custom roles visible.

Root Cause

The "Attach IAM Role" modal intentionally filters out all custom roles when the storage-manager-role exists in the account. This was introduced in commit 33e6647 (ZKUI-475) with the rationale that "Storage Manager provides a superset of permissions over every other role." However, this logic is incorrect for custom IAM roles — it assumes all other roles are subsets of storage-manager-role, which is not true for user-created custom roles.

In SelectAccountIAMRole.tsx (line 169-171), the filtering logic is:

const storageManagerFiltered = unfilteredRoles.some((r) => r.RoleName === STORAGE_MANAGER_ROLE)
    ? unfilteredRoles.filter((r) => r.RoleName === STORAGE_MANAGER_ROLE)
    : unfilteredRoles;

This means: "If storage-manager-role exists in the list, keep ONLY storage-manager-role and discard everything else." Since every managed account has storage-manager-role, ALL custom roles are always hidden.

The same pattern exists in AccountRoleSelectButtonAndModal.tsx (lines 119-122):

const storageManagerRoles = parsedRoles.filter((role) => role.roleName === STORAGE_MANAGER_ROLE);
return storageManagerRoles.length > 0 ? storageManagerRoles : parsedRoles;

Both components exhibit the same bug: when storage-manager-role is present, only it is shown.

Evidence

src/react/ui-elements/SelectAccountIAMRole.tsx
├── L169: const storageManagerFiltered = unfilteredRoles.some((r) => r.RoleName === STORAGE_MANAGER_ROLE) ...  — PRIMARY ROOT CAUSE: When storage-manager-role exists in the roles list (which is always the case for managed accounts), ALL other roles are filtered out. Only storage-manager-role survives. This directly causes the 30+ custom roles to be invisible in the Role dropdown.
└── L173: const roles = props.filterOutInternalRoles ...  — The secondary filter (filterOutInternalRoles) operates on the already-filtered storageManagerFiltered array, so even if it's designed to keep custom roles (those without 'scality-internal' in the ARN), it never gets a chance — those roles were already removed by the storageManagerFiltered logic.
src/react/account/AccountRoleSelectButtonAndModal.tsx
└── L119: const storageManagerRoles = parsedRoles.filter( ...  — Same bug in the table-based modal: when storage-manager-role exists, only it is returned. Custom roles are discarded. Both role selection UI components have this filtering issue.
src/react/utils/hooks.ts
└── L138: export const STORAGE_MANAGER_ROLE = 'storage-manager-role';  — The constant used for the filtering comparison. This is the built-in role that every managed account has, ensuring the filter always triggers and always hides custom roles.

Upstream Impact

High severity. All custom IAM roles are completely invisible in the "Attach IAM Role" modal for any account that has the storage-manager-role (which is every managed account). Users cannot attach custom IAM roles to users through the UI at all, defeating the purpose of creating custom roles. This affects all ARTESCA 4.2.0 users who create custom IAM roles via CLI or API.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cerebro-analyzedIssue created by Cerebro automated analysis

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions