dimas-b commented on code in PR #2280:
URL: https://github.com/apache/polaris/pull/2280#discussion_r2500660568


##########
runtime/service/src/main/java/org/apache/polaris/service/catalog/io/AccessConfigProvider.java:
##########
@@ -101,4 +120,58 @@ public AccessConfig getAccessConfig(
         storageInfo.get(),
         refreshCredentialsEndpoint);
   }
+
+  /**
+   * Generates a remote signing configuration for accessing table storage at 
explicit locations.
+   *
+   * @param callContext the call context containing realm, principal, and 
security context
+   * @param catalogName the name of the catalog
+   * @param tableIdentifier the table identifier, used for logging and refresh 
endpoint construction
+   * @param resolvedPath the entity hierarchy to search for storage 
configuration
+   * @return {@link AccessConfig} with scoped credentials and metadata; empty 
if no storage config
+   *     found
+   */
+  public AccessConfig getAccessConfigForRemoteSigning(
+      @Nonnull CallContext callContext,
+      @Nonnull String catalogName,
+      @Nonnull TableIdentifier tableIdentifier,
+      @Nonnull PolarisResolvedPathWrapper resolvedPath) {
+    LOGGER
+        .atDebug()
+        .addKeyValue("tableIdentifier", tableIdentifier)
+        .log("Fetching remote signing config for table");
+
+    Optional<PolarisEntity> storageInfo = 
FileIOUtil.findStorageInfoFromHierarchy(resolvedPath);
+    Optional<PolarisStorageConfigurationInfo> configurationInfo =
+        storageInfo
+            .map(PolarisEntity::getInternalPropertiesAsMap)
+            .map(info -> 
info.get(PolarisEntityConstants.getStorageConfigInfoPropertyName()))
+            .map(PolarisStorageConfigurationInfo::deserialize);
+
+    if (configurationInfo.isEmpty()) {
+      LOGGER
+          .atWarn()
+          .addKeyValue("tableIdentifier", tableIdentifier)
+          .log("Table entity has no storage configuration in its hierarchy");
+      return AccessConfig.EMPTY;
+    }
+
+    PolarisStorageIntegration<AwsStorageConfigurationInfo> storageIntegration =
+        
storageIntegrationProvider.getStorageIntegrationForConfig(configurationInfo.get());
+
+    if (!(storageIntegration
+        instanceof AwsCredentialsStorageIntegration 
awsCredentialsStorageIntegration)) {
+      LOGGER
+          .atWarn()
+          .addKeyValue("tableIdentifier", tableIdentifier)
+          .log("Table entity storage integration is not an AWS credentials 
storage integration");
+      return AccessConfig.EMPTY;
+    }
+
+    String prefix = 
prefixParser.catalogNameToPrefix(callContext.getRealmContext(), catalogName);
+    URI signerUri = uriInfo.getBaseUri().resolve("api/");

Review Comment:
   I'm not sure about the `api/` constant... It related to our `@Path` 
annotations in the generated REST API classes, so it's usage is a bit obscure 
here. Could we make it a constant in the `s3-sign-service` module?



##########
polaris-core/src/main/java/org/apache/polaris/core/storage/StorageAccessProperty.java:
##########
@@ -52,6 +54,21 @@ public enum StorageAccessProperty {
       "the endpoint to load vended credentials for a table from the catalog",
       false,
       false),
+  AWS_REMOTE_SIGNING_ENABLED(
+      Boolean.class,
+      S3FileIOProperties.REMOTE_SIGNING_ENABLED,
+      "whether to enable remote signing for S3 requests",
+      false),
+  AWS_REMOTE_SIGNER_URI(
+      String.class,
+      S3V4RestSignerClient.S3_SIGNER_URI,
+      "the base URI for the remote signer service, used for signing S3 
requests",

Review Comment:
   Does this have a reference Iceberg version number where the property becomes 
respected?



##########
polaris-core/src/main/java/org/apache/polaris/core/rest/PolarisResourcePaths.java:
##########
@@ -78,4 +82,15 @@ public String genericTable(TableIdentifier ident) {
         "generic-tables",
         RESTUtil.encodeString(ident.name()));
   }
+
+  public String s3RemoteSigning(TableIdentifier ident) {

Review Comment:
   Is this a `core` concern? I suppose it is only relevant to the REST layer 🤔 



##########
runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogAdapter.java:
##########
@@ -828,6 +830,9 @@ public Response getConfig(
                         .addAll(VIEW_ENDPOINTS)
                         
.addAll(PolarisEndpoints.getSupportedGenericTableEndpoints(realmConfig))
                         
.addAll(PolarisEndpoints.getSupportedPolicyEndpoints(realmConfig))
+                        .addAll(
+                            
PolarisEndpoints.getSupportedRemoteSigningEndpoints(

Review Comment:
   I'm not sure it's worth advertising in `ConfigResponse` because it's not a 
standard endpoint, for which clients might want to check the endpoints list. 
Clients learn about it via `loadTable` responses, I guess 🤔 



##########
runtime/service/src/main/java/org/apache/polaris/service/catalog/iceberg/IcebergCatalogHandler.java:
##########
@@ -801,6 +806,33 @@ private LoadTableResponse.Builder 
buildLoadTableResponseWithDelegationCredential
       return responseBuilder;
     }
 
+    AccessDelegationMode delegationMode = 
selectAccessDelegationMode(delegationModes);
+
+    if (delegationMode == REMOTE_SIGNING) {
+
+      S3RemoteSigningCatalogHandler.throwIfRemoteSigningNotEnabled(
+          callContext.getRealmConfig(), getResolvedCatalogEntity());
+
+      AccessConfig accessConfig =
+          accessConfigProvider.getAccessConfigForRemoteSigning(
+              callContext, catalogName, tableIdentifier, resolvedStoragePath);
+
+      Map<String, String> credentialConfig = accessConfig.credentials();
+
+      if (!credentialConfig.isEmpty()) {
+        responseBuilder.addAllConfig(credentialConfig);
+        responseBuilder.addCredential(

Review Comment:
   Why `addCredential()` when we're remote-signing?



##########
spec/README.md:
##########
@@ -17,14 +17,40 @@
   under the License.
 -->
 
-# Polaris API Specifications
-
-Polaris provides two sets of OpenAPI specifications:
-- `polaris-management-service.yml` - Defines the management APIs for using 
Polaris to create and manage Iceberg catalogs and their principals
-- `polaris-catalog-service.yaml` - Defines the specification for the Polaris 
Catalog API, which encompasses both the Iceberg REST Catalog API
-   and Polaris-native API.
-  - `polaris-catalog-apis` - Contains the specification for Polaris-specific 
Catalog APIs
-  - `iceberg-rest-catalog-open-api.yaml` - Contains the specification for 
Iceberg Rest Catalog API
+# Apache Polaris API Specifications
+
+Apache Polaris provides the following OpenAPI specifications:
+
+- [polaris-management-service.yml](polaris-management-service.yml) - Defines 
the management APIs for using Apache
+  Polaris to create and manage Apache Iceberg catalogs and their principals
+
+- [polaris-catalog-service.yaml](polaris-catalog-service.yaml) - Defines the 
specification for the Apache Polaris 
+  Catalog API, which encompasses both the Apache Iceberg REST Catalog API and 
Apache Polaris-native APIs:
+
+  - [iceberg-rest-catalog-open-api.yaml](iceberg-rest-catalog-open-api.yaml) - 
Contains the specification for 
+    Apache Iceberg Rest Catalog API.
+
+  - [polaris-catalog-apis](polaris-catalog-apis) - This folder contains the 
specifications for Apache 
+    Polaris-specific Catalog APIs:
+
+    - [generic-tables-api.yaml](polaris-catalog-apis/generic-tables-api.yaml) 
- Contains the specification for 
+      the Generic Tables API
+
+    - [notifications-api.yaml](polaris-catalog-apis/notifications-api.yaml) - 
Contains the specification for 
+      the Notifications API
+
+    - [oauth-tokens-api.yaml](polaris-catalog-apis/oauth-tokens-api.yaml) - 
Contains the specification for the 
+      internal OAuth Token endpoint, extracted from the Apache Iceberg REST 
Catalog API.
+
+    - [policy-apis.yaml](polaris-catalog-apis/policy-apis.yaml) - Contains the 
specification for the Policy APIs.
+
+- [s3-sign](s3-sign) - This folder contains the specifications for S3 remote 
signing:
+
+  - [iceberg-s3-signer-open-api.yaml](s3-sign/iceberg-s3-signer-open-api.yaml) 
- Contains the specification of the 

Review Comment:
   nit: maybe clarify that Polaris uses only type definitions from the spec 
file?



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to