diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java index 6ef2441011e6a..235264c8889de 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java @@ -54,6 +54,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; +import static org.elasticsearch.TransportVersions.ROLE_REMOTE_CLUSTER_PRIVS; import static org.elasticsearch.transport.RemoteClusterPortSettings.TRANSPORT_VERSION_ADVANCED_REMOTE_CLUSTER_SECURITY; import static org.elasticsearch.xcontent.ConstructingObjectParser.constructorArg; import static org.elasticsearch.xcontent.ConstructingObjectParser.optionalConstructorArg; @@ -1319,6 +1320,24 @@ private static Map maybeRewriteMetadataForApiKeyRoleDescriptors( ) ); } + + if (authentication.getEffectiveSubject().getTransportVersion().onOrAfter(ROLE_REMOTE_CLUSTER_PRIVS) + && streamVersion.before(ROLE_REMOTE_CLUSTER_PRIVS)) { + metadata = new HashMap<>(metadata); + metadata.put( + AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, + maybeRemoveRemoteClusterFromRoleDescriptors( + (BytesReference) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY) + ) + ); + metadata.put( + AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, + maybeRemoveRemoteClusterFromRoleDescriptors( + (BytesReference) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY) + ) + ); + } + if (authentication.getEffectiveSubject().getTransportVersion().onOrAfter(VERSION_API_KEY_ROLES_AS_BYTES) && streamVersion.before(VERSION_API_KEY_ROLES_AS_BYTES)) { metadata = new HashMap<>(metadata); @@ -1397,6 +1416,32 @@ private static BytesReference convertRoleDescriptorsMapToBytes(Map roleDescriptorsMap = convertRoleDescriptorsBytesToMap(roleDescriptorsBytes); + final AtomicBoolean removedAtLeastOne = new AtomicBoolean(false); + roleDescriptorsMap.forEach((key, value) -> { + if (value instanceof Map) { + @SuppressWarnings("unchecked") + Map roleDescriptor = (Map) value; + boolean removed = roleDescriptor.remove(RoleDescriptor.Fields.REMOTE_CLUSTER.getPreferredName()) != null; + if (removed) { + removedAtLeastOne.set(true); + } + } + }); + + if (removedAtLeastOne.get()) { + return convertRoleDescriptorsMapToBytes(roleDescriptorsMap); + } else { + // No need to serialize if we did not remove anything. + return roleDescriptorsBytes; + } + } + static BytesReference maybeRemoveRemoteIndicesFromRoleDescriptors(BytesReference roleDescriptorsBytes) { if (roleDescriptorsBytes == null || roleDescriptorsBytes.length() == 0) { return roleDescriptorsBytes;