dimas-b commented on code in PR #2523: URL: https://github.com/apache/polaris/pull/2523#discussion_r2331300283
########## runtime/service/src/main/java/org/apache/polaris/service/identity/AwsIamServiceIdentityConfiguration.java: ########## @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.service.identity; + +import java.util.Optional; +import org.apache.polaris.core.identity.resolved.ResolvedAwsIamServiceIdentity; + +/** + * Configuration for an AWS IAM service identity used by Polaris to access AWS services. + * + * <p>This includes the IAM ARN and optionally, static credentials (access key, secret key, and + * session token). If credentials are provided, they will be used to construct a {@link + * ResolvedAwsIamServiceIdentity}; otherwise, the AWS default credential provider chain is used. + */ +public interface AwsIamServiceIdentityConfiguration extends ResolvableServiceIdentityConfiguration { + + /** The IAM role or user ARN representing the service identity. */ + String iamArn(); + + /** + * Optional AWS access key ID associated with the IAM identity. If not provided, the AWS default + * credential chain will be used. + */ + Optional<String> accessKeyId(); Review Comment: Mixing credentials with service _identity_ does not feel right me... on a conceptual level. Since we already have a `ServiceSecretReference` in `ResolvedAwsIamServiceIdentity`, why do we need credentials here? A quick search through usages in current code leads to `ResolvedAwsIamServiceIdentity.stsClientSupplier()`, which itself is not called anywhere. However, the most recent version of `AwsCredentialsStorageIntegration` uses separate `AwsCredentialsProvider` and `StsClientProvider`... so that `stsClientSupplier()` method does not appear to fix well with `AwsCredentialsStorageIntegration`. Could you clarify the intended use case for credentials in this class? ########## polaris-core/src/main/java/org/apache/polaris/core/identity/registry/ServiceIdentityRegistryFactory.java: ########## @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.core.identity.registry; + +import org.apache.polaris.core.context.RealmContext; + +/** + * Factory for creating {@link ServiceIdentityRegistry} instances. + * + * <p>Each {@link ServiceIdentityRegistry} instance is associated with a {@link RealmContext} and is + * responsible for managing the service identities for the user in that realm. + */ +public interface ServiceIdentityRegistryFactory { + ServiceIdentityRegistry getOrCreateServiceIdentityRegistry(RealmContext realmContext); Review Comment: Is this factory interface really necessary? Could we leverage CDI (producers) directly? E.g. https://github.com/apache/polaris/blob/cd8294949c4114256c37c330d224fc9b345b6c2f/runtime/service/src/main/java/org/apache/polaris/service/config/ServiceProducers.java#L174 ########## polaris-core/src/main/java/org/apache/polaris/core/identity/resolved/ResolvedAwsIamServiceIdentity.java: ########## @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.polaris.core.identity.resolved; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import jakarta.annotation.Nonnull; +import org.apache.polaris.core.identity.ServiceIdentityType; +import org.apache.polaris.core.identity.dpo.AwsIamServiceIdentityInfoDpo; +import org.apache.polaris.core.identity.dpo.ServiceIdentityInfoDpo; +import org.apache.polaris.core.secrets.ServiceSecretReference; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.services.sts.StsClient; +import software.amazon.awssdk.services.sts.StsClientBuilder; + +/** + * Represents a fully resolved AWS IAM service identity, including the associated IAM ARN and + * credentials. This class is used internally by Polaris to access AWS services on behalf of a + * configured service identity. + * + * <p>It contains AWS credentials (access key, secret, and optional session token) and provides a + * lazily initialized {@link StsClient} for performing role assumptions or identity verification. + * + * <p>The resolved identity can be converted back into its persisted DPO form using {@link + * #asServiceIdentityInfoDpo()}. + */ +public class ResolvedAwsIamServiceIdentity extends ResolvedServiceIdentity { + + /** IAM role or user ARN representing the Polaris service identity. */ + private final String iamArn; + + /** AWS access key ID of the AWS credential associated with the identity. */ + private final String accessKeyId; + + /** AWS secret access key of the AWS credential associated with the identity. */ + private final String secretAccessKey; + + /** The AWS session token of the AWS credential associated with the identity. */ + private final String sessionToken; + + public ResolvedAwsIamServiceIdentity( + String iamArn, String accessKeyId, String secretAccessKey, String sessionToken) { + this(null, iamArn, accessKeyId, secretAccessKey, sessionToken); + } + + public ResolvedAwsIamServiceIdentity( + ServiceSecretReference serviceSecretReference, Review Comment: The only difference in this class from `AwsIamServiceIdentityConfiguration` is the `serviceSecretReference`, but the latter appears to be always `null`? ########## polaris-core/src/main/java/org/apache/polaris/core/identity/resolved/ResolvedAwsIamServiceIdentity.java: ########## @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.polaris.core.identity.resolved; + +import com.google.common.base.Supplier; +import com.google.common.base.Suppliers; +import jakarta.annotation.Nonnull; +import org.apache.polaris.core.identity.ServiceIdentityType; +import org.apache.polaris.core.identity.dpo.AwsIamServiceIdentityInfoDpo; +import org.apache.polaris.core.identity.dpo.ServiceIdentityInfoDpo; +import org.apache.polaris.core.secrets.ServiceSecretReference; +import software.amazon.awssdk.auth.credentials.AwsBasicCredentials; +import software.amazon.awssdk.auth.credentials.AwsSessionCredentials; +import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider; +import software.amazon.awssdk.services.sts.StsClient; +import software.amazon.awssdk.services.sts.StsClientBuilder; + +/** + * Represents a fully resolved AWS IAM service identity, including the associated IAM ARN and + * credentials. This class is used internally by Polaris to access AWS services on behalf of a + * configured service identity. + * + * <p>It contains AWS credentials (access key, secret, and optional session token) and provides a + * lazily initialized {@link StsClient} for performing role assumptions or identity verification. + * + * <p>The resolved identity can be converted back into its persisted DPO form using {@link + * #asServiceIdentityInfoDpo()}. + */ +public class ResolvedAwsIamServiceIdentity extends ResolvedServiceIdentity { + + /** IAM role or user ARN representing the Polaris service identity. */ + private final String iamArn; + + /** AWS access key ID of the AWS credential associated with the identity. */ + private final String accessKeyId; Review Comment: I believe the approach of binding a service identity to specific credentials is too limiting. I can imaging a service using cloud-based workload identity to represent the Polaris "service". Currently this is only possible by not setting credentials in this class and thus implicitly defaulting to the system-level AWS identity (discovered by the AWS SDK)... that can work, but then this class become misleading because its fields support only one possible sub-case of AWS credentials, while many are supported by the SDK. Could we use something like current `AwsCredentialsProvider` (currently used by `AwsCredentialsStorageIntegration`)? ########## runtime/service/src/main/java/org/apache/polaris/service/identity/RealmServiceIdentityConfiguration.java: ########## @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.service.identity; + +import io.smallrye.config.WithName; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + +/** + * Represents service identity configuration for a specific realm. + * + * <p>Supports multiple identity types, such as AWS IAM. This interface allows each realm to define + * the credentials and metadata needed to resolve service-managed identities. + */ +public interface RealmServiceIdentityConfiguration { + /** + * Returns the AWS IAM service identity configuration for this realm, if present. + * + * @return an optional AWS IAM configuration + */ + @WithName("aws-iam") + Optional<AwsIamServiceIdentityConfiguration> awsIamServiceIdentity(); + + /** + * Aggregates all configured service identity types into a list. This includes AWS IAM and + * potentially other types in the future. + * + * @return a list of configured service identity definitions + */ + default List<? extends ResolvableServiceIdentityConfiguration> serviceIdentityConfigurations() { + return Stream.of(awsIamServiceIdentity()).flatMap(Optional::stream).toList(); Review Comment: Why not simply `awsIamServiceIdentity().stream().toList()`? ########## runtime/service/src/main/java/org/apache/polaris/service/identity/ServiceIdentityRegistryConfiguration.java: ########## @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.service.identity; + +import io.quarkus.runtime.annotations.StaticInitSafe; +import io.smallrye.config.ConfigMapping; +import org.apache.polaris.core.identity.registry.ServiceIdentityRegistryFactory; + +@StaticInitSafe +@ConfigMapping(prefix = "polaris.service-identity.registry") +public interface ServiceIdentityRegistryConfiguration { + + /** + * The type of the ServiceIdentityRegistryFactory to use. This is the {@link + * ServiceIdentityRegistryFactory} identifier. + */ + String type(); Review Comment: Unless we're planning to have multiple types in Apache Polaris code, this config seems redundant. Downstream project can use `@Alternative` + `@Priority` to override the default service identity implementations. ########## runtime/defaults/src/main/resources/application.properties: ########## @@ -209,6 +215,7 @@ quarkus.arc.ignored-split-packages=\ org.apache.polaris.service.auth.external.tenant,\ org.apache.polaris.service.auth.internal,\ org.apache.polaris.service.events,\ + org.apache.polaris.service.identity,\ Review Comment: Would it be possible to refactor this (new) packages into multiple sub-packages to avoid splitting the same package across multiple jars (rather than ignoring the split package warning)? ########## runtime/service/src/main/java/org/apache/polaris/service/config/ProductionReadinessChecks.java: ########## @@ -232,6 +233,24 @@ public ProductionReadinessCheck checkPolarisEventListener( return ProductionReadinessCheck.OK; } + @Produces + public ProductionReadinessCheck checkServiceIdentities( + ServiceIdentityConfiguration configuration) { + List<ProductionReadinessCheck.Error> errors = new ArrayList<>(); + configuration + .realms() + .forEach( + (realm, config) -> { + if (config.awsIamServiceIdentity().isEmpty()) { + errors.add( + Error.of( + "AWS IAM Service identity is not configured.", Review Comment: Why is this an error? What if Polaris is deployed only for Azure storage? ########## runtime/defaults/src/main/resources/application.properties: ########## @@ -198,6 +198,12 @@ polaris.oidc.principal-roles-mapper.type=default # polaris.storage.gcp.token=token # polaris.storage.gcp.lifespan=PT1H +# Polaris Service Identity Config +polaris.service-identity.registry.type=default +# polaris.service-identity.aws-iam.iam-arn=arn:aws:iam::123456789012:user/polaris-iam-user +polaris.service-identity.aws-iam.iam-arn=arn:aws:iam::174739373489:user/managed/rxing +polaris.service-identity.my-realm.aws-iam.iam-arn=arn:aws:iam::123456789012:user/polaris-iam-user Review Comment: Do we need these settings (lines 203-205) to be in the _default_ config / properties? ########## polaris-core/src/main/java/org/apache/polaris/core/identity/registry/ServiceIdentityRegistry.java: ########## @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.polaris.core.identity.registry; + +import org.apache.polaris.core.identity.ServiceIdentityType; +import org.apache.polaris.core.identity.dpo.ServiceIdentityInfoDpo; +import org.apache.polaris.core.identity.resolved.ResolvedServiceIdentity; + +/** + * A registry interface for managing and resolving service identities in Polaris. + * + * <p>In a multi-tenant Polaris deployment, each catalog or tenant may be associated with a distinct + * service identity that represents the Polaris service itself when accessing external systems + * (e.g., cloud services like AWS or GCP). This registry provides a central mechanism to manage + * those identities and resolve them at runtime. + * + * <p>The registry helps abstract the configuration and retrieval of service-managed credentials + * from the logic that uses them. It ensures a consistent and secure way to handle identity + * resolution across different deployment models, including SaaS and self-managed environments. + */ +public interface ServiceIdentityRegistry { + /** + * Assigns a new {@link ServiceIdentityInfoDpo} for the given service identity type. Typically + * used during entity creation to associate a default or generated identity. + * + * @param serviceIdentityType The type of service identity (e.g., AWS_IAM). + * @return A new {@link ServiceIdentityInfoDpo} representing the assigned service identity. + */ + ServiceIdentityInfoDpo assignServiceIdentity(ServiceIdentityType serviceIdentityType); Review Comment: Why "assign"? It does not look like current implementations assign anything :thinking: they just "discover" `ServiceIdentityInfoDpo` based on `serviceIdentityType` :thinking: ########## runtime/service/src/main/java/org/apache/polaris/service/identity/registry/DefaultServiceIdentityRegistryFactory.java: ########## @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.polaris.service.identity.registry; + +import com.google.common.annotations.VisibleForTesting; +import io.smallrye.common.annotation.Identifier; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.EnumMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.polaris.core.context.RealmContext; +import org.apache.polaris.core.identity.ServiceIdentityType; +import org.apache.polaris.core.identity.registry.DefaultServiceIdentityRegistry; +import org.apache.polaris.core.identity.registry.ServiceIdentityRegistry; +import org.apache.polaris.core.identity.registry.ServiceIdentityRegistryFactory; +import org.apache.polaris.core.identity.resolved.ResolvedServiceIdentity; +import org.apache.polaris.core.secrets.ServiceSecretReference; +import org.apache.polaris.service.identity.RealmServiceIdentityConfiguration; +import org.apache.polaris.service.identity.ResolvableServiceIdentityConfiguration; +import org.apache.polaris.service.identity.ServiceIdentityConfiguration; + +@ApplicationScoped +@Identifier("default") +public class DefaultServiceIdentityRegistryFactory implements ServiceIdentityRegistryFactory { + private static final String DEFAULT_REALM_KEY = ServiceIdentityConfiguration.DEFAULT_REALM_KEY; + private static final String DEFAULT_REALM_NSS = "system:default"; + private static final String IDENTITY_INFO_REFERENCE_URN_FORMAT = + "urn:polaris-secret:default-identity-registry:%s:%s"; + + private final Map<String, DefaultServiceIdentityRegistry> realmServiceIdentityRegistries; + + @Inject + public DefaultServiceIdentityRegistryFactory( + ServiceIdentityConfiguration serviceIdentityConfiguration) { + realmServiceIdentityRegistries = + serviceIdentityConfiguration.realms().entrySet().stream() + .collect( + Collectors.toMap( + Map.Entry::getKey, // realm identifier + entry -> { + RealmServiceIdentityConfiguration realmConfig = entry.getValue(); + + // Resolve all the service identities for the realm + EnumMap<ServiceIdentityType, ResolvedServiceIdentity> resolvedIdentities = + realmConfig.serviceIdentityConfigurations().stream() + .map(ResolvableServiceIdentityConfiguration::resolve) + .flatMap(Optional::stream) + .peek( + // Set the identity info reference for each resolved identity + identity -> + identity.setIdentityInfoReference( + buildIdentityInfoReference( + entry.getKey(), identity.getIdentityType()))) Review Comment: It feels like this belongs to `ResolvableServiceIdentityConfiguration::resolve()`, such as `.resolve(buildIdentityInfoReference(...))`. WDYT? ########## runtime/service/src/main/java/org/apache/polaris/service/config/ServiceProducers.java: ########## @@ -402,6 +414,20 @@ public OidcTenantResolver oidcTenantResolver( return resolvers.select(Identifier.Literal.of(config.tenantResolver())).get(); } + @Produces + @RequestScoped + public RealmServiceIdentityConfiguration realmServiceIdentityConfig( Review Comment: Who needs this for injection? I did not find any bean that might need this producer :thinking: ########## runtime/service/src/main/java/org/apache/polaris/service/identity/registry/DefaultServiceIdentityRegistryFactory.java: ########## @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.polaris.service.identity.registry; + +import com.google.common.annotations.VisibleForTesting; +import io.smallrye.common.annotation.Identifier; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import java.util.EnumMap; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import org.apache.polaris.core.context.RealmContext; +import org.apache.polaris.core.identity.ServiceIdentityType; +import org.apache.polaris.core.identity.registry.DefaultServiceIdentityRegistry; +import org.apache.polaris.core.identity.registry.ServiceIdentityRegistry; +import org.apache.polaris.core.identity.registry.ServiceIdentityRegistryFactory; +import org.apache.polaris.core.identity.resolved.ResolvedServiceIdentity; +import org.apache.polaris.core.secrets.ServiceSecretReference; +import org.apache.polaris.service.identity.RealmServiceIdentityConfiguration; +import org.apache.polaris.service.identity.ResolvableServiceIdentityConfiguration; +import org.apache.polaris.service.identity.ServiceIdentityConfiguration; + +@ApplicationScoped +@Identifier("default") +public class DefaultServiceIdentityRegistryFactory implements ServiceIdentityRegistryFactory { + private static final String DEFAULT_REALM_KEY = ServiceIdentityConfiguration.DEFAULT_REALM_KEY; + private static final String DEFAULT_REALM_NSS = "system:default"; + private static final String IDENTITY_INFO_REFERENCE_URN_FORMAT = + "urn:polaris-secret:default-identity-registry:%s:%s"; + + private final Map<String, DefaultServiceIdentityRegistry> realmServiceIdentityRegistries; + + @Inject + public DefaultServiceIdentityRegistryFactory( + ServiceIdentityConfiguration serviceIdentityConfiguration) { + realmServiceIdentityRegistries = + serviceIdentityConfiguration.realms().entrySet().stream() Review Comment: If we go with a CDI producer for `ServiceIdentityRegistry` (as commented in another thread), we can certainly still keep this class and pre-compute `realmServiceIdentityRegistries` on startup (although I personally think this data is not worth pre-computing), however, I think we can operate without the extra core interface: `ServiceIdentityRegistryFactory`. ########## runtime/service/src/main/java/org/apache/polaris/service/config/ServiceProducers.java: ########## @@ -402,6 +414,20 @@ public OidcTenantResolver oidcTenantResolver( return resolvers.select(Identifier.Literal.of(config.tenantResolver())).get(); } + @Produces + @RequestScoped + public RealmServiceIdentityConfiguration realmServiceIdentityConfig( + ServiceIdentityConfiguration config, RealmContext realmContext) { + return config.forRealm(realmContext); + } + + @Produces + @RequestScoped + public ServiceIdentityRegistry serviceIdentityRegistry( + ServiceIdentityRegistryFactory serviceIdentityRegistryFactory, RealmContext realmContext) { + return serviceIdentityRegistryFactory.getOrCreateServiceIdentityRegistry(realmContext); Review Comment: As I commented in other threads, I think this producer is fine, but I do not think we need the factory interface in core. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: issues-unsubscr...@polaris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org