Skip to content

Conversation

@foch01
Copy link

@foch01 foch01 commented Oct 17, 2025

Overview

This PR fixes a critical bug in the DeleteRoleScopeMapping function where deleting a single client role from a scope would inadvertently delete all client roles from that scope due to an empty request body being sent to the Keycloak API.

Description

When using keycloak_generic_role_mapper to manage client roles in scopes, deleting one mapper resource would cause all other client role mappers in the same scope to be removed from Keycloak, even though Terraform only showed one resource being deleted.

Root Cause

The issue was in the DeleteRoleScopeMapping function in role_scope_mapping.go. For client roles (role.ClientRole = true), the DELETE request was sent with an empty body (nil), while the Keycloak API expects the specific roles to be deleted in the request body as an array.

// Before (buggy behavior)
if role.ClientRole {
    return keycloakClient.delete(ctx, roleUrl, nil) // ← Empty body causes cascade deletion
}

This contrasted with realm roles, which correctly included the role data in the request body.

Solution

This PR standardizes the deletion behavior by ensuring both client roles and realm roles include the role data in the DELETE request body:

// After (fixed behavior)
body := [1]RealmRoleRepresentation{
    {
        Id:          role.Id,
        Name:        role.Name,
        Description: role.Description,
        Composite:   role.Composite,
        ClientRole:  role.ClientRole,
        ContainerId: role.ContainerId,
    },
}
return keycloakClient.delete(ctx, roleUrl, body)

Changes Made

  • Modified DeleteRoleScopeMapping function in role_scope_mapping.go
  • Removed the conditional logic that treated client roles differently from realm roles
  • Unified the deletion approach to always include role data in the request body
  • Maintains backward compatibility with existing configurations

Testing

  • ✅ Individual client role deletion now works correctly
  • ✅ Other roles in the scope remain untouched
  • ✅ Realm role deletion continues to work as before
  • ✅ No breaking changes to existing functionality

Impact

Before

  • Deleting one client role mapper → All client roles removed from scope
  • Required two terraform apply cycles to achieve intended result
  • Unpredictable behavior and potential data loss

After

  • Deleting one client role mapper → Only that specific role is removed
  • Single terraform apply achieves intended result
  • Predictable and granular role management

Backward Compatibility

This change is fully backward compatible:

  • Existing Terraform configurations will work without modification
  • No changes to resource schemas or attributes
  • Only the internal API call behavior is corrected

Related Issues

Test Scenarios

Scenario 1: Single Role Deletion

# Before: Commenting out one mapper deleted all mappers
# After: Commenting out one mapper deletes only that mapper
resource "keycloak_generic_role_mapper" "customers_read" { ... }
resource "keycloak_generic_role_mapper" "customers_write" { ... } # Deleted

Scenario 2: Multiple Client Scopes

# Before: Deletion in one scope affected other scopes unpredictably
# After: Deletion is isolated to the specific scope and role

Verification Steps

  1. Create multiple keycloak_generic_role_mapper resources for client roles
  2. Apply the configuration
  3. Remove one mapper from the configuration
  4. Run terraform plan - should show only one deletion
  5. Run terraform apply - should remove only the intended role
  6. Verify in Keycloak admin console that other roles remain

Files Changed

  • keycloak/role_scope_mapping.go - Fixed DeleteRoleScopeMapping function

Breaking Changes

None. This is a bug fix that corrects unintended behavior.

Additional Notes

This fix brings consistency between client role and realm role deletion behavior, making the provider more predictable and reliable for managing Keycloak role scope mappings.

Signed-off-by: Thomas Sanceo <[email protected]>
Signed-off-by: foch01 <[email protected]>
@foch01 foch01 force-pushed the fix/delete-single-client-scope branch from 4be1789 to ad894de Compare October 17, 2025 13:05
@thomasdarimont
Copy link
Contributor

Thanks @foch01! This looks like a good fix. Would you mind adding a test for this as well?

@foch01 foch01 force-pushed the fix/delete-single-client-scope branch 2 times, most recently from d33c726 to 84c2f99 Compare October 20, 2025 10:19
@foch01
Copy link
Author

foch01 commented Oct 20, 2025

Hello @thomasdarimont,

Thank you for your quick response!
I just added some tests. Is this okay for you ?

@foch01
Copy link
Author

foch01 commented Nov 7, 2025

Hello @thomasdarimont,

Do you think you can merge this issue 🙏 ?
Other people are encountering the problem on the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants