Skip to content

Commit db0f8c9

Browse files
committed
Add more comments and reorganize the structure
1 parent e1244a3 commit db0f8c9

30 files changed

+347
-14
lines changed

polaris-core/src/main/java/org/apache/polaris/core/connection/ConnectionConfigInfoDpo.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
*/
1919
package org.apache.polaris.core.connection;
2020

21-
import com.fasterxml.jackson.annotation.*;
21+
import com.fasterxml.jackson.annotation.JsonIgnore;
22+
import com.fasterxml.jackson.annotation.JsonInclude;
23+
import com.fasterxml.jackson.annotation.JsonProperty;
24+
import com.fasterxml.jackson.annotation.JsonSubTypes;
25+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
2226
import com.fasterxml.jackson.core.JsonProcessingException;
2327
import com.fasterxml.jackson.databind.DeserializationFeature;
2428
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -195,7 +199,7 @@ public static ConnectionConfigInfoDpo fromConnectionConfigInfoModelWithSecrets(
195199
}
196200

197201
public abstract ConnectionConfigInfoDpo withServiceIdentity(
198-
ServiceIdentityInfoDpo serviceIdentityInfo);
202+
@Nonnull ServiceIdentityInfoDpo serviceIdentityInfo);
199203

200204
/**
201205
* Produces the correponding API-model ConnectionConfigInfo for this persistence object; many

polaris-core/src/main/java/org/apache/polaris/core/connection/SigV4AuthenticationParametersDpo.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,24 @@
3939
*/
4040
public class SigV4AuthenticationParametersDpo extends AuthenticationParametersDpo {
4141

42+
// The aws IAM role arn assumed by polaris userArn when signing requests
4243
@JsonProperty(value = "roleArn")
4344
private final String roleArn;
4445

46+
// The session name used when assuming the role
4547
@JsonProperty(value = "roleSessionName")
4648
private final String roleSessionName;
4749

50+
// An optional external id used to establish a trust relationship with AWS in the trust policy
4851
@JsonProperty(value = "externalId")
4952
private final String externalId;
5053

54+
// Region to be used by the SigV4 protocol for signing requests
5155
@JsonProperty(value = "signingRegion")
5256
private final String signingRegion;
5357

58+
// The service name to be used by the SigV4 protocol for signing requests, the default signing
59+
// name is "execute-api" is if not provided
5460
@JsonProperty(value = "signingName")
5561
private final String signingName;
5662

polaris-core/src/main/java/org/apache/polaris/core/connection/hadoop/HadoopConnectionConfigInfoDpo.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public String toString() {
6565
.add("uri", getUri())
6666
.add("warehouse", getWarehouse())
6767
.add("authenticationParameters", getAuthenticationParameters().toString())
68+
.add("serviceIdentity", getServiceIdentity())
6869
.toString();
6970
}
7071

polaris-core/src/main/java/org/apache/polaris/core/connection/iceberg/IcebergRestConnectionConfigInfoDpo.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ public String getRemoteCatalogName() {
8080
}
8181

8282
@Override
83-
public ConnectionConfigInfoDpo withServiceIdentity(ServiceIdentityInfoDpo serviceIdentityInfo) {
83+
public ConnectionConfigInfoDpo withServiceIdentity(
84+
@Nonnull ServiceIdentityInfoDpo serviceIdentityInfo) {
8485
return new IcebergRestConnectionConfigInfoDpo(
8586
getUri(), getAuthenticationParameters(), serviceIdentityInfo, getRemoteCatalogName());
8687
}

polaris-core/src/main/java/org/apache/polaris/core/credentials/DefaultPolarisCredentialManager.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.apache.polaris.core.credentials;
2121

2222
import com.google.common.annotations.VisibleForTesting;
23+
import jakarta.annotation.Nonnull;
2324
import java.util.EnumMap;
2425
import java.util.Optional;
2526
import org.apache.polaris.core.connection.AuthenticationParametersDpo;
@@ -35,6 +36,17 @@
3536
import software.amazon.awssdk.services.sts.model.AssumeRoleRequest;
3637
import software.amazon.awssdk.services.sts.model.AssumeRoleResponse;
3738

39+
/**
40+
* Default implementation of {@link PolarisCredentialManager} responsible for retrieving credentials
41+
* used by Polaris to access external systems such as remote catalogs or cloud storage.
42+
*
43+
* <p>It resolves a {@link ServiceIdentityInfoDpo} into a {@link ResolvedServiceIdentity} using the
44+
* {@link ServiceIdentityRegistry}, then uses the provided authentication parameters to generate
45+
* temporary access credentials (e.g., via AWS STS AssumeRole).
46+
*
47+
* <p>This implementation currently supports AWS IAM service identities and can be extended to
48+
* support other identity types or external services beyond catalogs, such as cloud storage.
49+
*/
3850
public class DefaultPolarisCredentialManager implements PolarisCredentialManager {
3951
private final ServiceIdentityRegistry serviceIdentityRegistry;
4052

@@ -43,7 +55,7 @@ public DefaultPolarisCredentialManager(ServiceIdentityRegistry serviceIdentityRe
4355
}
4456

4557
@Override
46-
public EnumMap<ConnectionCredentialProperty, String> getConnectionCredentials(
58+
public @Nonnull EnumMap<ConnectionCredentialProperty, String> getConnectionCredentials(
4759
ServiceIdentityInfoDpo serviceIdentity,
4860
AuthenticationParametersDpo authenticationParameters) {
4961
EnumMap<ConnectionCredentialProperty, String> credentialMap =

polaris-core/src/main/java/org/apache/polaris/core/credentials/PolarisCredentialManager.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,36 @@
1919

2020
package org.apache.polaris.core.credentials;
2121

22+
import jakarta.annotation.Nonnull;
2223
import java.util.EnumMap;
2324
import org.apache.polaris.core.connection.AuthenticationParametersDpo;
2425
import org.apache.polaris.core.credentials.connection.ConnectionCredentialProperty;
2526
import org.apache.polaris.core.credentials.connection.PolarisConnectionCredsVendor;
2627
import org.apache.polaris.core.identity.dpo.ServiceIdentityInfoDpo;
2728

29+
/**
30+
* PolarisCredentialManager is responsible for retrieving the credentials Polaris needs to access
31+
* remote services such as federated catalogs or cloud storage.
32+
*
33+
* <p>It combines service-managed identity information (e.g., an IAM user Polaris uses) with
34+
* user-defined authentication parameters (e.g., roleArn) to generate the credentials required for
35+
* authentication with external systems.
36+
*
37+
* <p>Typical flow:
38+
*
39+
* <ol>
40+
* <li>Resolve the service identity and locate its associated credential (e.g., from a secret
41+
* manager via the service identity registry).
42+
* <li>Use the resolved identity together with the authentication parameters to obtain the final
43+
* access credentials.
44+
* </ol>
45+
*
46+
* <p>This design supports both SaaS and self-managed deployments, ensuring a clear separation
47+
* between user-provided configuration and Polaris-managed identity.
48+
*/
2849
public interface PolarisCredentialManager extends PolarisConnectionCredsVendor {
2950
@Override
51+
@Nonnull
3052
EnumMap<ConnectionCredentialProperty, String> getConnectionCredentials(
3153
ServiceIdentityInfoDpo serviceIdentity, AuthenticationParametersDpo authenticationParameters);
3254
}

polaris-core/src/main/java/org/apache/polaris/core/credentials/connection/ConnectionCredentialProperty.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121

2222
import org.apache.iceberg.aws.AwsProperties;
2323

24+
/**
25+
* A subset of Iceberg catalog properties recognized by Polaris.
26+
*
27+
* <p>Most of these properties are meant to initialize Catalog objects for accessing the remote
28+
* Catalog service.
29+
*/
2430
public enum ConnectionCredentialProperty {
2531
AWS_ACCESS_KEY_ID(String.class, AwsProperties.REST_ACCESS_KEY_ID, "the aws access key id"),
2632
AWS_SECRET_ACCESS_KEY(

polaris-core/src/main/java/org/apache/polaris/core/credentials/connection/PolarisConnectionCredsVendor.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,39 @@
1919

2020
package org.apache.polaris.core.credentials.connection;
2121

22+
import jakarta.annotation.Nonnull;
2223
import java.util.EnumMap;
2324
import org.apache.polaris.core.connection.AuthenticationParametersDpo;
2425
import org.apache.polaris.core.identity.dpo.ServiceIdentityInfoDpo;
2526

27+
/**
28+
* Generates credentials Polaris uses to connect to external catalog services such as AWS Glue or
29+
* other federated endpoints. Implementations combine service-managed identity metadata (such as an
30+
* IAM user or role, defined in {@link ServiceIdentityInfoDpo}) with user-provided authentication
31+
* parameters (such as a role ARN or external ID, defined in {@link AuthenticationParametersDpo}) to
32+
* construct a credential map consumable by Polaris.
33+
*
34+
* <p>This interface allows pluggable behavior for different authentication mechanisms and service
35+
* vendors. Implementations can support service-specific credential provisioning or caching
36+
* strategies as needed.
37+
*/
2638
public interface PolarisConnectionCredsVendor {
39+
40+
/**
41+
* Retrieve credential values required to authenticate a remote connection.
42+
*
43+
* <p>The returned credentials are derived using the combination of Polaris-managed service
44+
* identity and user-specified connection authentication parameters. Implementations may look up
45+
* the service identity credential from a secret store or local config, and use it in conjunction
46+
* with user-supplied data to produce scoped credentials for accessing remote services.
47+
*
48+
* @param serviceIdentity Polaris-managed identity metadata, including a reference to the backing
49+
* credential (e.g., a secret ARN or ID)
50+
* @param authenticationParameters Authentication configuration supplied by the Polaris user
51+
* @return A map from {@link ConnectionCredentialProperty} to the resolved credential value, used
52+
* by downstream systems to establish the connection
53+
*/
54+
@Nonnull
2755
EnumMap<ConnectionCredentialProperty, String> getConnectionCredentials(
2856
ServiceIdentityInfoDpo serviceIdentity, AuthenticationParametersDpo authenticationParameters);
2957
}

polaris-core/src/main/java/org/apache/polaris/core/identity/dpo/AwsIamServiceIdentityInfoDpo.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@
3030
import org.apache.polaris.core.identity.ServiceIdentityType;
3131
import org.apache.polaris.core.secrets.ServiceSecretReference;
3232

33+
/**
34+
* Persistence-layer representation of an AWS IAM service identity used by Polaris.
35+
*
36+
* <p>This class models an AWS IAM identity (either a user or role) and extends {@link
37+
* ServiceIdentityInfoDpo}. It is typically used internally to store both the identity metadata
38+
* (such as the IAM ARN) and a reference to the actual credential (e.g., via {@link
39+
* ServiceSecretReference}).
40+
*
41+
* <p>Instances of this class are convertible to the public API model {@link
42+
* AwsIamServiceIdentityInfo}.
43+
*/
3344
public class AwsIamServiceIdentityInfoDpo extends ServiceIdentityInfoDpo {
3445

3546
// Technically, it should be ^arn:(aws|aws-cn|aws-us-gov):iam::(\d{12}):(user|role)/.+$,

polaris-core/src/main/java/org/apache/polaris/core/identity/dpo/ServiceIdentityInfoDpo.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public ServiceSecretReference getIdentityInfoReference() {
6868
return identityInfoReference;
6969
}
7070

71+
/**
72+
* Converts this persistence object to the corresponding API model. During the conversion, some
73+
* fields will be dropped, e.g. the reference to the service identity's credential
74+
*/
7175
public abstract @Nonnull ServiceIdentityInfo asServiceIdentityInfoModel();
7276

7377
@Override

polaris-core/src/main/java/org/apache/polaris/core/identity/mutation/EntityMutationEngine.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,21 @@
2121

2222
import org.apache.polaris.core.entity.PolarisBaseEntity;
2323

24+
/**
25+
* Engine responsible for applying a sequence of {@link EntityMutator} transformations to a {@link
26+
* PolarisBaseEntity}.
27+
*
28+
* <p>This abstraction allows Polaris to customize or enrich entities during runtime or persistence,
29+
* based on configured or contextual logic (e.g., injecting service identity info, computing derived
30+
* fields).
31+
*/
2432
public interface EntityMutationEngine {
33+
/**
34+
* Applies all registered entity mutators to the provided entity, in order.
35+
*
36+
* @param entity The original Polaris entity to mutate.
37+
* @return A new or modified instance of {@link PolarisBaseEntity} after all mutations are
38+
* applied.
39+
*/
2540
PolarisBaseEntity applyMutations(PolarisBaseEntity entity);
2641
}

service/common/src/main/java/org/apache/polaris/service/identity/mutation/EntityMutator.java renamed to polaris-core/src/main/java/org/apache/polaris/core/identity/mutation/EntityMutator.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,23 @@
1717
* under the License.
1818
*/
1919

20-
package org.apache.polaris.service.identity.mutation;
20+
package org.apache.polaris.core.identity.mutation;
2121

2222
import org.apache.polaris.core.entity.PolarisBaseEntity;
2323

24+
/**
25+
* A transformation hook that mutates a Polaris entity.
26+
*
27+
* <p>Implementations of this interface apply custom logic to modify or enrich a {@link
28+
* PolarisBaseEntity}.
29+
*/
2430
public interface EntityMutator {
31+
32+
/**
33+
* Applies the mutation logic to the given entity.
34+
*
35+
* @param entity the entity to mutate
36+
* @return the mutated entity
37+
*/
2538
PolarisBaseEntity apply(PolarisBaseEntity entity);
2639
}

polaris-core/src/main/java/org/apache/polaris/core/identity/registry/DefaultServiceIdentityRegistry.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,27 @@
2727
import org.apache.polaris.core.identity.dpo.ServiceIdentityInfoDpo;
2828
import org.apache.polaris.core.identity.resolved.ResolvedServiceIdentity;
2929

30+
/**
31+
* Default implementation of {@link ServiceIdentityRegistry} that resolves service identities from
32+
* statically configured values (typically defined via Quarkus server configuration).
33+
*
34+
* <p>This implementation supports both multi-tenant (e.g., SaaS) and self-managed (single-tenant)
35+
* Polaris deployments:
36+
*
37+
* <ul>
38+
* <li>In multi-tenant mode, each tenant (realm) can have its own set of service identities
39+
* defined in the configuration. The same identity will consistently be assigned for each
40+
* {@link ServiceIdentityType} within a given tenant.
41+
* <li>In single-tenant or self-managed deployments, a single set of service identities can be
42+
* defined and used system-wide.
43+
* </ul>
44+
*/
3045
public class DefaultServiceIdentityRegistry implements ServiceIdentityRegistry {
3146

47+
/** Map of service identity types to their resolved identities. */
3248
private final EnumMap<ServiceIdentityType, ResolvedServiceIdentity> resolvedServiceIdentities;
49+
50+
/** Map of identity info references (URNs) to their resolved service identities. */
3351
private final Map<String, ResolvedServiceIdentity> referenceToResolvedServiceIdentity;
3452

3553
public DefaultServiceIdentityRegistry(

polaris-core/src/main/java/org/apache/polaris/core/identity/registry/ServiceIdentityRegistry.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,34 @@
2323
import org.apache.polaris.core.identity.dpo.ServiceIdentityInfoDpo;
2424
import org.apache.polaris.core.identity.resolved.ResolvedServiceIdentity;
2525

26+
/**
27+
* A registry interface for managing and resolving service identities in Polaris.
28+
*
29+
* <p>In a multi-tenant Polaris deployment, each catalog or tenant may be associated with a distinct
30+
* service identity that represents the Polaris service itself when accessing external systems
31+
* (e.g., cloud services like AWS or GCP). This registry provides a central mechanism to manage
32+
* those identities and resolve them at runtime.
33+
*
34+
* <p>The registry helps abstract the configuration and retrieval of service-managed credentials
35+
* from the logic that uses them. It ensures a consistent and secure way to handle identity
36+
* resolution across different deployment models, including SaaS and self-managed environments.
37+
*/
2638
public interface ServiceIdentityRegistry {
39+
/**
40+
* Assigns a new {@link ServiceIdentityInfoDpo} for the given service identity type. Typically
41+
* used during entity creation to associate a default or generated identity.
42+
*
43+
* @param serviceIdentityType The type of service identity (e.g., AWS_IAM).
44+
* @return A new {@link ServiceIdentityInfoDpo} representing the assigned service identity.
45+
*/
2746
ServiceIdentityInfoDpo assignServiceIdentity(ServiceIdentityType serviceIdentityType);
2847

2948
/**
30-
* Resolves the service identity based on the provided service identity information.
49+
* Resolves the given service identity by retrieving the actual credential or secret referenced by
50+
* it, typically from a secret manager or internal credential store.
3151
*
32-
* @param serviceIdentityInfo The service identity information to resolve.
33-
* @return The resolved service identity.
52+
* @param serviceIdentityInfo The service identity metadata to resolve.
53+
* @return A {@link ResolvedServiceIdentity} including credentials and other resolved data.
3454
*/
3555
ResolvedServiceIdentity resolveServiceIdentity(ServiceIdentityInfoDpo serviceIdentityInfo);
3656
}

polaris-core/src/main/java/org/apache/polaris/core/identity/registry/ServiceIdentityRegistryFactory.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@
2121

2222
import org.apache.polaris.core.context.RealmContext;
2323

24+
/**
25+
* Factory for creating {@link ServiceIdentityRegistry} instances.
26+
*
27+
* <p>Each {@link ServiceIdentityRegistry} instance is associated with a {@link RealmContext} and is
28+
* responsible for managing the service identities for the user in that realm.
29+
*/
2430
public interface ServiceIdentityRegistryFactory {
2531
ServiceIdentityRegistry getOrCreateServiceIdentityRegistry(RealmContext realmContext);
2632
}

polaris-core/src/main/java/org/apache/polaris/core/identity/resolved/ResolvedAwsIamServiceIdentity.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,29 @@
3131
import software.amazon.awssdk.services.sts.StsClient;
3232
import software.amazon.awssdk.services.sts.StsClientBuilder;
3333

34+
/**
35+
* Represents a fully resolved AWS IAM service identity, including the associated IAM ARN and
36+
* credentials. This class is used internally by Polaris to access AWS services on behalf of a
37+
* configured service identity.
38+
*
39+
* <p>It contains AWS credentials (access key, secret, and optional session token) and provides a
40+
* lazily initialized {@link StsClient} for performing role assumptions or identity verification.
41+
*
42+
* <p>The resolved identity can be converted back into its persisted DPO form using {@link
43+
* #asServiceIdentityInfoDpo()}.
44+
*/
3445
public class ResolvedAwsIamServiceIdentity extends ResolvedServiceIdentity {
46+
47+
/** IAM role or user ARN representing the Polaris service identity. */
3548
private final String iamArn;
49+
50+
/** AWS access key ID of the AWS credential associated with the identity. */
3651
private final String accessKeyId;
52+
53+
/** AWS secret access key of the AWS credential associated with the identity. */
3754
private final String secretAccessKey;
55+
56+
/** The AWS session token of the AWS credential associated with the identity. */
3857
private final String sessionToken;
3958

4059
public ResolvedAwsIamServiceIdentity(
@@ -77,6 +96,7 @@ public ServiceIdentityInfoDpo asServiceIdentityInfoDpo() {
7796
return new AwsIamServiceIdentityInfoDpo(getIdentityInfoReference(), getIamArn());
7897
}
7998

99+
/** Returns a memoized supplier for creating an STS client using the resolved credentials. */
80100
public Supplier<StsClient> stsClientSupplier() {
81101
return Suppliers.memoize(
82102
() -> {

polaris-core/src/main/java/org/apache/polaris/core/identity/resolved/ResolvedServiceIdentity.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,6 @@ public void setIdentityInfoReference(@NotNull ServiceSecretReference identityInf
5757
this.identityInfoReference = identityInfoReference;
5858
}
5959

60+
/** Converts this resolved identity into its corresponding persisted form (DPO). */
6061
public abstract @Nonnull ServiceIdentityInfoDpo asServiceIdentityInfoDpo();
6162
}

0 commit comments

Comments
 (0)