Skip to content

Conversation

@rohangoli
Copy link

@rohangoli rohangoli commented Oct 15, 2025

What changes were proposed in this pull request?

  • Enable support for AssumeRole ARN pattern validation (including URN/ecs role ARNs) and produce valid IAM policy resource JSON for Dell ECS or ObjectScale On-prem S3-compatible IAM.

    • ARN validation:
      • Role ARN validation now accepts both arn: and urn: prefixed role identifiers for supported partitions (aws, aws-us-gov, ecs), and allows vendor namespaces (non-numeric) for the account identifier portion. This allows on-prem vendors that expose URN-style role identifiers (e.g., ECS) to be used.
        Empty strings and the aws-cn partition are rejected with explicit error messages. Invalid formats produce a clear "Invalid role ARN format: ..." exception message, which matches test expectations.
    • Policy JSON generation for ECS-compatible IAM:
      • For ECS partition (on-prem S3-compatible systems), the generated AssumeRole policy uses bucket-level resource ARNs (bucket/*) instead of object ARNs containing path segments. This prevents invalid resource ARNs being included in the policy JSON when targeting systems that don't accept full object ARN formats.
      • For AWS partitions, the policy continues to produce object-level ARNs with path prefixes plus * to scope fine-grained access.
      • ListBucket and GetBucketLocation permissions are included and properly scoped; when listing is allowed but there are no buckets, a minimal ListBucket allow is still added (with empty resources) to avoid an empty policy.
  • Breakdown of Issue - Support Dell ECS On-Premise S3 Object Store with STS support #2743

Why are the changes needed?

  • On Create Table REST API request, ARN ROLE Pattern Validation fails
polaris-1        | 2025-10-14 02:55:14,104 DEBUG [org.apa.pol.ser.adm.api.PolarisCatalogsApi] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) operation=createCatalog createCatalogRequest=class CreateCatalogRequest {
polaris-1        |     catalog: class PolarisCatalog {
polaris-1        |         class Catalog {
polaris-1        |             type: INTERNAL
polaris-1        |             name: quickstart_catalog
polaris-1        |             properties: class CatalogProperties {
polaris-1        |                 {}
polaris-1        |                 defaultBaseLocation: s3://polaris
polaris-1        |             }
polaris-1        |             createTimestamp: null
polaris-1        |             lastUpdateTimestamp: null
polaris-1        |             entityVersion: null
polaris-1        |             storageConfigInfo: class AwsStorageConfigInfo {
polaris-1        |                 class StorageConfigInfo {
polaris-1        |                     storageType: S3
polaris-1        |                     allowedLocations: []
polaris-1        |                 }
polaris-1        |                 roleArn: urn:ecs:iam::otf_dev:role/assumeSameAccountOTF
polaris-1        |                 externalId: null
polaris-1        |                 userArn: null
polaris-1        |                 region: us-east-1
polaris-1        |                 endpoint: https://ecmh2.td.teradata.com
polaris-1        |                 stsEndpoint: https://ecs1.td.teradata.com:4443/sts
polaris-1        |                 stsUnavailable: null
polaris-1        |                 endpointInternal: null
polaris-1        |                 pathStyleAccess: true
polaris-1        |             }
polaris-1        |         }
polaris-1        |     }
polaris-1        | } Invoking catalogs with params
polaris-1        | 2025-10-14 02:55:14,109 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for SUPPORTED_CATALOG_STORAGE_TYPES with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,109 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for SUPPORTED_CATALOG_STORAGE_TYPES with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,110 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_SETTING_S3_ENDPOINTS with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,110 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_SETTING_S3_ENDPOINTS with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,111 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_SETTING_SUB_CATALOG_RBAC_FOR_FEDERATED_CATALOGS with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,111 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_SETTING_SUB_CATALOG_RBAC_FOR_FEDERATED_CATALOGS with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,123 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENTITY_CACHE_WEIGHER_TARGET with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,123 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENTITY_CACHE_WEIGHER_TARGET with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,127 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENTITY_CACHE_SOFT_VALUES with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,127 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENTITY_CACHE_SOFT_VALUES with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,157 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,157 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,161 DEBUG [org.apa.pol.cor.aut.PolarisAuthorizerImpl] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Satisfied privilege CATALOG_CREATE with grantRecord PolarisGrantRec{securableCatalogId=0, securableId=0, granteeCatalogId=0, granteeId=2, privilegeCode=1} from securable entity:name=root_container;id=0;parentId=0;entityVersion=1;type=ROOT;subType=NULL_SUBTYPE;internalProperties={};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[PolarisGrantRec{securableCatalogId=0, securableId=0, granteeCatalogId=0, granteeId=2, privilegeCode=1}] for principalName root and activatedIds [2]
polaris-1        | 2025-10-14 02:55:14,161 DEBUG [org.apa.pol.cor.aut.PolarisAuthorizerImpl] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Satisfied privilege CATALOG_CREATE with grantRecord PolarisGrantRec{securableCatalogId=0, securableId=0, granteeCatalogId=0, granteeId=2, privilegeCode=1} from securable entity:name=root_container;id=0;parentId=0;entityVersion=1;type=ROOT;subType=NULL_SUBTYPE;internalProperties={};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[PolarisGrantRec{securableCatalogId=0, securableId=0, granteeCatalogId=0, granteeId=2, privilegeCode=1}] for principalName root and activatedIds [2]
polaris-1        | 2025-10-14 02:55:14,165 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for STORAGE_CONFIGURATION_MAX_LOCATIONS with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,165 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Get configuration value for STORAGE_CONFIGURATION_MAX_LOCATIONS with realm POLARIS
polaris-1        | 2025-10-14 02:55:14,214 INFO  [org.apa.pol.ser.exc.IcebergExceptionMapper] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Handling runtimeException Invalid role ARN format: urn:ecs:iam::otf_dev:role/assumeSameAccountOTF
polaris-1        | 2025-10-14 02:55:14,214 INFO  [org.apa.pol.ser.exc.IcebergExceptionMapper] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Handling runtimeException Invalid role ARN format: urn:ecs:iam::otf_dev:role/assumeSameAccountOTF
polaris-1        | 2025-10-14 02:55:14,236 DEBUG [org.apa.pol.ser.exc.IcebergExceptionMapper] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Full RuntimeException
polaris-1        | 2025-10-14 02:55:14,236 DEBUG [org.apa.pol.ser.exc.IcebergExceptionMapper] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Full RuntimeException
polaris-1        | 2025-10-14 02:55:14,238 DEBUG [org.apa.pol.ser.exc.IcebergExceptionMapper] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Mapped exception to errorResp: org.jboss.resteasy.reactive.common.jaxrs.ResponseImpl@3c1b2cf1
polaris-1        | 2025-10-14 02:55:14,238 DEBUG [org.apa.pol.ser.exc.IcebergExceptionMapper] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Mapped exception to errorResp: org.jboss.resteasy.reactive.common.jaxrs.ResponseImpl@3c1b2cf1
polaris-1        | 2025-10-14 02:55:14,241 INFO  [io.qua.htt.access-log] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) 172.18.0.3 - root [14/Oct/2025:02:55:14 +0000] "POST /api/management/v1/catalogs HTTP/1.1" 400 140
polaris-1        | 2025-10-14 02:55:14,241 INFO  [io.qua.htt.access-log] [bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) 172.18.0.3 - root [14/Oct/2025:02:55:14 +0000] "POST /api/management/v1/catalogs HTTP/1.1" 400 140
polaris-setup-1  | < HTTP/1.1 400 Bad Request
polaris-setup-1  | < content-length: 140
polaris-setup-1  | < Content-Type: application/json
polaris-setup-1  | < Polaris-Request-Id: bf13f327-48a4-4311-98b7-64beb37dd20c_0000000000000000002
polaris-setup-1  | < 
polaris-setup-1  | { [140 bytes data]
polaris-setup-1  | * Connection #0 to host polaris left intact
polaris-setup-1  | {"error":{"message":"Invalid role ARN format: urn:ecs:iam::otf_dev:role/assumeSameAccountOTF","type":"IllegalArgumentException","code":400}}
polaris-setup-1  | Done.
  • Invalid ARN for Resource - ECS Bucket Resource with Role
polaris-1        | 2025-10-14 04:25:42,188 INFO  [org.apa.pol.ser.adm.PolarisServiceImpl] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Created new catalog class PolarisCatalog {
polaris-1        |     class Catalog {
polaris-1        |         type: INTERNAL
polaris-1        |         name: quickstart_catalog
polaris-1        |         properties: class CatalogProperties {
polaris-1        |             {default-base-location=s3://polaris}
polaris-1        |             defaultBaseLocation: s3://polaris
polaris-1        |         }
polaris-1        |         createTimestamp: 1760415942179
polaris-1        |         lastUpdateTimestamp: 0
polaris-1        |         entityVersion: 1
polaris-1        |         storageConfigInfo: class AwsStorageConfigInfo {
polaris-1        |             class StorageConfigInfo {
polaris-1        |                 storageType: S3
polaris-1        |                 allowedLocations: [s3://polaris]
polaris-1        |             }
polaris-1        |             roleArn: urn:ecs:iam::otf_dev:role/assumeSameAccountOTF
polaris-1        |             externalId: null
polaris-1        |             userArn: null
polaris-1        |             region: us-east-1
polaris-1        |             endpoint: https://ecmh2.td.teradata.com
polaris-1        |             stsEndpoint: https://ecs1.td.teradata.com:4443/sts
polaris-1        |             stsUnavailable: null
polaris-1        |             endpointInternal: null
polaris-1        |             pathStyleAccess: true
polaris-1        |             ignoreSSLVerification: true
polaris-1        |         }
polaris-1        |     }
polaris-1        | }
polaris-1        | 2025-10-14 04:25:42,189 DEBUG [org.apa.pol.ser.adm.api.PolarisCatalogsApi] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) Completed execution of createCatalog API with status code 201
polaris-1        | 2025-10-14 04:25:42,202 INFO  [io.qua.htt.access-log] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000002,POLARIS] [,,,] (executor-thread-1) 172.18.0.4 - root [14/Oct/2025:04:25:42 +0000] "POST /api/management/v1/catalogs HTTP/1.1" 201 481
polaris-setup-1  | < HTTP/1.1 201 Created
polaris-setup-1  | < Content-Type: application/json;charset=UTF-8
polaris-setup-1  | < content-length: 481
polaris-setup-1  | < Polaris-Request-Id: 900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000002
polaris-setup-1  | < 
polaris-setup-1  | { [481 bytes data]
polaris-setup-1  | * Connection #0 to host polaris left intact
polaris-setup-1  | {"type":"INTERNAL","name":"quickstart_catalog","properties":{"default-base-location":"s3://polaris"},"createTimestamp":1760415942179,"lastUpdateTimestamp":0,"entityVersion":1,"storageConfigInfo":{"roleArn":"urn:ecs:iam::otf_dev:role/assumeSameAccountOTF","region":"us-east-1","endpoint":"https://ecmh2.td.teradata.com","stsEndpoint":"https://ecs1.td.teradata.com:4443/sts","pathStyleAccess":true,"ignoreSSLVerification":true,"storageType":"S3","allowedLocations":["s3://polaris"]}}
polaris-setup-1  | Done.
polaris-setup-1  | Extra grants...
polaris-setup-1  |   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
polaris-setup-1  |                                  Dload  Upload   Total   Spent    Left  Speed
polaris-1        | 2025-10-14 04:25:42,218 DEBUG [org.apa.pol.ser.aut.DefaultAuthenticator] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) Resolving principal for credentials: InternalPolarisToken{principalName=root, principalId=1, clientId=root, scope=PRINCIPAL_ROLE:ALL}
polaris-1        | 2025-10-14 04:25:42,220 DEBUG [org.apa.pol.ser.aut.DefaultAuthenticator] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) Resolved principal: PolarisPrincipal{name=root, roles=[service_admin], properties={client_id=root}}
polaris-1        | 2025-10-14 04:25:42,232 DEBUG [org.apa.pol.ser.adm.api.PolarisCatalogsApi] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) operation=addGrantToCatalogRole catalogName=quickstart_catalog catalogRoleName=catalog_admin addGrantRequest=class AddGrantRequest {
polaris-1        |     grant: class CatalogGrant {
polaris-1        |         class GrantResource {
polaris-1        |             type: catalog
polaris-1        |         }
polaris-1        |         privilege: CATALOG_MANAGE_CONTENT
polaris-1        |     }
polaris-1        | } Invoking catalogs with params
polaris-1        | 2025-10-14 04:25:42,234 INFO  [org.apa.pol.ser.adm.PolarisServiceImpl] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) Adding grant class AddGrantRequest {
polaris-1        |     grant: class CatalogGrant {
polaris-1        |         class GrantResource {
polaris-1        |             type: catalog
polaris-1        |         }
polaris-1        |         privilege: CATALOG_MANAGE_CONTENT
polaris-1        |     }
polaris-1        | } to catalogRole catalog_admin in catalog quickstart_catalog
polaris-1        | 2025-10-14 04:25:42,260 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING with realm POLARIS
polaris-1        | 2025-10-14 04:25:42,261 DEBUG [org.apa.pol.cor.aut.PolarisAuthorizerImpl] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) Satisfied privilege CATALOG_MANAGE_GRANTS_ON_SECURABLE with grantRecord PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=2} from securable entity:name=quickstart_catalog;id=3;parentId=0;entityVersion=1;type=CATALOG;subType=NULL_SUBTYPE;internalProperties={catalogType=INTERNAL, storage_configuration_info={"@type":"AwsStorageConfigurationInfo","allowedLocations":["s3://polaris"],"roleARN":"urn:ecs:iam::otf_dev:role/assumeSameAccountOTF","region":"us-east-1","endpoint":"https://ecmh2.td.teradata.com","pathStyleAccess":true,"stsEndpoint":"https://ecs1.td.teradata.com:4443/sts","ignoreSSLVerification":true,"storageType":"S3","fileIoImplClassName":"org.apache.iceberg.aws.s3.S3FileIO"}};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=2}, PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=31}] for principalName root and activatedIds [2, 4]
polaris-1        | 2025-10-14 04:25:42,268 DEBUG [org.apa.pol.ser.adm.api.PolarisCatalogsApi] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) Completed execution of addGrantToCatalogRole API with status code 201
polaris-1        | 2025-10-14 04:25:42,269 INFO  [io.qua.htt.access-log] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000003,POLARIS] [,,,] (executor-thread-1) 172.18.0.4 - root [14/Oct/2025:04:25:42 +0000] "PUT /api/management/v1/catalogs/quickstart_catalog/catalog-roles/catalog_admin/grants HTTP/1.1" 201 -
100    56    0     0  100    56      0    934 --:--:-- --:--:-- --:--:--   949
polaris-setup-1  | Done.
polaris-setup-1 exited with code 0
polaris-1        | 2025-10-14 04:26:08,664 DEBUG [org.apa.pol.ser.cat.api.IcebergRestOAuth2Api] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000004,POLARIS] [,,,] (executor-thread-1) operation=getToken Invoking OAuth2Api with params
polaris-1        | 2025-10-14 04:26:08,665 DEBUG [org.apa.pol.ser.aut.int.ser.DefaultOAuth2ApiService] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000004,POLARIS] [,,,] (executor-thread-1) Found credentials in auth header - treating as client_credentials
polaris-1        | 2025-10-14 04:26:08,668 DEBUG [org.apa.pol.ser.cat.api.IcebergRestOAuth2Api] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000004,POLARIS] [,,,] (executor-thread-1) Completed execution of getToken API with status code 200
polaris-1        | 2025-10-14 04:26:08,670 INFO  [io.qua.htt.access-log] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000004,POLARIS] [,,,] (executor-thread-1) 172.18.0.1 - - [14/Oct/2025:04:26:08 +0000] "POST /api/catalog/v1/oauth/tokens HTTP/1.1" 200 757
polaris-1        | 2025-10-14 04:26:11,072 DEBUG [org.apa.pol.ser.aut.DefaultAuthenticator] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Resolving principal for credentials: InternalPolarisToken{principalName=root, principalId=1, clientId=root, scope=PRINCIPAL_ROLE:ALL}
polaris-1        | 2025-10-14 04:26:11,074 DEBUG [org.apa.pol.ser.aut.DefaultAuthenticator] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Resolved principal: PolarisPrincipal{name=root, roles=[service_admin], properties={client_id=root}}
polaris-1        | 2025-10-14 04:26:11,093 DEBUG [org.apa.pol.ser.cat.api.IcebergRestCatalogApi] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) operation=createNamespace prefix=quickstart_catalog createNamespaceRequest=CreateNamespaceRequest{namespace=minio_polaris_ns, properties=null} Invoking CatalogApi with params
polaris-1        | 2025-10-14 04:26:11,127 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING with realm POLARIS
polaris-1        | 2025-10-14 04:26:11,128 DEBUG [org.apa.pol.cor.aut.PolarisAuthorizerImpl] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Satisfied privilege NAMESPACE_CREATE with grantRecord PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=31} from securable entity:name=quickstart_catalog;id=3;parentId=0;entityVersion=1;type=CATALOG;subType=NULL_SUBTYPE;internalProperties={catalogType=INTERNAL, storage_configuration_info={"@type":"AwsStorageConfigurationInfo","allowedLocations":["s3://polaris"],"roleARN":"urn:ecs:iam::otf_dev:role/assumeSameAccountOTF","region":"us-east-1","endpoint":"https://ecmh2.td.teradata.com","pathStyleAccess":true,"stsEndpoint":"https://ecs1.td.teradata.com:4443/sts","ignoreSSLVerification":true,"storageType":"S3","fileIoImplClassName":"org.apache.iceberg.aws.s3.S3FileIO"}};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=2}, PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=31}, PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=32}] for principalName root and activatedIds [2, 4]
polaris-1        | 2025-10-14 04:26:11,128 INFO  [org.apa.pol.ser.cat.ice.IcebergCatalogHandler] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Initializing non-federated catalog
polaris-1        | 2025-10-14 04:26:11,131 DEBUG [org.apa.pol.ser.con.cat.PolarisCallContextCatalogFactory] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Initializing new BasePolarisCatalog for key: POLARIS/quickstart_catalog
polaris-1        | 2025-10-14 04:26:11,141 DEBUG [org.apa.pol.ser.con.cat.PolarisCallContextCatalogFactory] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Looked up defaultBaseLocation s3://polaris for catalog POLARIS/quickstart_catalog
polaris-1        | 2025-10-14 04:26:11,143 DEBUG [org.apa.pol.ser.cat.val.IcebergPropertiesValidation] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Resolved ioImplClassName org.apache.iceberg.aws.s3.S3FileIO from storageConfiguration AwsStorageConfigurationInfo{allowedLocations=[s3://polaris], roleARN=urn:ecs:iam::otf_dev:role/assumeSameAccountOTF, region=us-east-1, endpoint=https://ecmh2.td.teradata.com, pathStyleAccess=true, stsEndpoint=https://ecs1.td.teradata.com:4443/sts, ignoreSSLVerification=true}
polaris-1        | 2025-10-14 04:26:11,143 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Get configuration value for SUPPORTED_CATALOG_STORAGE_TYPES with realm POLARIS
polaris-1        | 2025-10-14 04:26:11,148 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Creating namespace minio_polaris_ns with metadata {}
polaris-1        | 2025-10-14 04:26:11,151 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Get configuration value for ADD_TRAILING_SLASH_TO_LOCATION with realm POLARIS
polaris-1        | 2025-10-14 04:26:11,152 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_NAMESPACE_LOCATION_OVERLAP with realm POLARIS
polaris-1        | 2025-10-14 04:26:11,153 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Validating no overlap for minio_polaris_ns with sibling tables or namespaces
polaris-1        | 2025-10-14 04:26:11,154 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Get configuration value for OPTIMIZED_SIBLING_CHECK with realm POLARIS
polaris-1        | 2025-10-14 04:26:11,157 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Resolving 0 sibling entities to validate location
polaris-1        | 2025-10-14 04:26:11,162 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_NAMESPACE_CUSTOM_LOCATION with realm POLARIS
polaris-1        | 2025-10-14 04:26:11,163 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Validating namespace minio_polaris_ns given parent catalog quickstart_catalog
polaris-1        | 2025-10-14 04:26:11,171 DEBUG [org.apa.pol.cor.per.res.PolarisResolutionManifest] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Returning resolvedEntities from getPassthroughResolvedPath: [entity:name=quickstart_catalog;id=3;parentId=0;entityVersion=1;type=CATALOG;subType=NULL_SUBTYPE;internalProperties={catalogType=INTERNAL, storage_configuration_info={"@type":"AwsStorageConfigurationInfo","allowedLocations":["s3://polaris"],"roleARN":"urn:ecs:iam::otf_dev:role/assumeSameAccountOTF","region":"us-east-1","endpoint":"https://ecmh2.td.teradata.com","pathStyleAccess":true,"stsEndpoint":"https://ecs1.td.teradata.com:4443/sts","ignoreSSLVerification":true,"storageType":"S3","fileIoImplClassName":"org.apache.iceberg.aws.s3.S3FileIO"}};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=2}, PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=31}, PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=32}], entity:name=minio_polaris_ns;id=5;parentId=3;entityVersion=1;type=NAMESPACE;subType=NULL_SUBTYPE;internalProperties={};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[]]
polaris-1        | 2025-10-14 04:26:11,177 DEBUG [org.apa.pol.ser.cat.api.IcebergRestCatalogApi] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) Completed execution of createNamespace API with status code 200
polaris-1        | 2025-10-14 04:26:11,185 INFO  [io.qua.htt.access-log] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000005,POLARIS] [,,,] (executor-thread-1) 172.18.0.1 - root [14/Oct/2025:04:26:11 +0000] "POST /api/catalog/v1/quickstart_catalog/namespaces/ HTTP/1.1" 200 93
polaris-1        | 2025-10-14 04:26:14,480 DEBUG [org.apa.pol.ser.aut.DefaultAuthenticator] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Resolving principal for credentials: InternalPolarisToken{principalName=root, principalId=1, clientId=root, scope=PRINCIPAL_ROLE:ALL}
polaris-1        | 2025-10-14 04:26:14,484 DEBUG [org.apa.pol.ser.aut.DefaultAuthenticator] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Resolved principal: PolarisPrincipal{name=root, roles=[service_admin], properties={client_id=root}}
polaris-1        | 2025-10-14 04:26:14,500 DEBUG [org.apa.pol.ser.cat.api.IcebergRestCatalogApi] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) operation=createTable prefix=quickstart_catalog namespace=minio_polaris_ns createTableRequest=CreateTableRequest{name=minio_polaris_ns_table01, location=null, properties=null, schema=table {
polaris-1        |   0: id: required string (car model)
polaris-1        |   1: first_name: required string (first name)
polaris-1        | }, partitionSpec=null, writeOrder=null, stageCreate=false} Invoking CatalogApi with params
polaris-1        | 2025-10-14 04:26:14,506 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for ENFORCE_PRINCIPAL_CREDENTIAL_ROTATION_REQUIRED_CHECKING with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,507 DEBUG [org.apa.pol.cor.aut.PolarisAuthorizerImpl] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Satisfied privilege TABLE_CREATE with grantRecord PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=31} from securable entity:name=quickstart_catalog;id=3;parentId=0;entityVersion=1;type=CATALOG;subType=NULL_SUBTYPE;internalProperties={catalogType=INTERNAL, storage_configuration_info={"@type":"AwsStorageConfigurationInfo","allowedLocations":["s3://polaris"],"roleARN":"urn:ecs:iam::otf_dev:role/assumeSameAccountOTF","region":"us-east-1","endpoint":"https://ecmh2.td.teradata.com","pathStyleAccess":true,"stsEndpoint":"https://ecs1.td.teradata.com:4443/sts","ignoreSSLVerification":true,"storageType":"S3","fileIoImplClassName":"org.apache.iceberg.aws.s3.S3FileIO"}};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=2}, PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=31}, PolarisGrantRec{securableCatalogId=0, securableId=3, granteeCatalogId=3, granteeId=4, privilegeCode=32}] for principalName root and activatedIds [2, 4]
polaris-1        | 2025-10-14 04:26:14,507 INFO  [org.apa.pol.ser.cat.ice.IcebergCatalogHandler] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Initializing non-federated catalog
polaris-1        | 2025-10-14 04:26:14,508 DEBUG [org.apa.pol.ser.con.cat.PolarisCallContextCatalogFactory] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Initializing new BasePolarisCatalog for key: POLARIS/quickstart_catalog
polaris-1        | 2025-10-14 04:26:14,508 DEBUG [org.apa.pol.ser.con.cat.PolarisCallContextCatalogFactory] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Looked up defaultBaseLocation s3://polaris for catalog POLARIS/quickstart_catalog
polaris-1        | 2025-10-14 04:26:14,509 DEBUG [org.apa.pol.ser.cat.val.IcebergPropertiesValidation] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Resolved ioImplClassName org.apache.iceberg.aws.s3.S3FileIO from storageConfiguration AwsStorageConfigurationInfo{allowedLocations=[s3://polaris], roleARN=urn:ecs:iam::otf_dev:role/assumeSameAccountOTF, region=us-east-1, endpoint=https://ecmh2.td.teradata.com, pathStyleAccess=true, stsEndpoint=https://ecs1.td.teradata.com:4443/sts, ignoreSSLVerification=true}
polaris-1        | 2025-10-14 04:26:14,509 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for SUPPORTED_CATALOG_STORAGE_TYPES with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,510 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for TABLE_OPERATIONS_MAKE_METADATA_CURRENT_ON_COMMIT with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,511 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) new BasePolarisTableOperations for minio_polaris_ns.minio_polaris_ns_table01
polaris-1        | 2025-10-14 04:26:14,512 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) doRefresh for tableIdentifier minio_polaris_ns.minio_polaris_ns_table01
polaris-1        | 2025-10-14 04:26:14,513 DEBUG [org.apa.pol.cor.per.res.PolarisResolutionManifest] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Returning null for key minio_polaris_ns.minio_polaris_ns_table01 due to size mismatch from getPassthroughResolvedPath resolvedPath: [entity:name=minio_polaris_ns;id=5;parentId=3;entityVersion=1;type=NAMESPACE;subType=NULL_SUBTYPE;internalProperties={};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[]], requestedPath.getEntityNames(): [minio_polaris_ns, minio_polaris_ns_table01]
polaris-1        | 2025-10-14 04:26:14,513 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Refreshing latestLocation: null
polaris-1        | 2025-10-14 04:26:14,521 INFO  [org.apa.ice.BaseMetastoreCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Table properties set at catalog level through catalog properties: {}
polaris-1        | 2025-10-14 04:26:14,521 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for DEFAULT_LOCATION_OBJECT_STORAGE_PREFIX_ENABLED with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,522 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_UNSTRUCTURED_TABLE_LOCATION with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,523 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for ALLOW_TABLE_LOCATION_OVERLAP with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,523 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for OPTIMIZED_SIBLING_CHECK with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,523 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for TABLE_OPERATIONS_MAKE_METADATA_CURRENT_ON_COMMIT with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,523 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) new BasePolarisTableOperations for minio_polaris_ns.minio_polaris_ns_table01
polaris-1        | 2025-10-14 04:26:14,523 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) doRefresh for tableIdentifier minio_polaris_ns.minio_polaris_ns_table01
polaris-1        | 2025-10-14 04:26:14,525 DEBUG [org.apa.pol.cor.per.res.PolarisResolutionManifest] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Returning null for key minio_polaris_ns.minio_polaris_ns_table01 due to size mismatch from getPassthroughResolvedPath resolvedPath: [entity:name=minio_polaris_ns;id=5;parentId=3;entityVersion=1;type=NAMESPACE;subType=NULL_SUBTYPE;internalProperties={};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[]], requestedPath.getEntityNames(): [minio_polaris_ns, minio_polaris_ns_table01]
polaris-1        | 2025-10-14 04:26:14,525 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Refreshing latestLocation: null
polaris-1        | 2025-10-14 04:26:14,526 INFO  [org.apa.ice.BaseMetastoreCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Table properties enforced at catalog level through catalog properties: {}
polaris-1        | 2025-10-14 04:26:14,566 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalog] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) doCommit for table minio_polaris_ns.minio_polaris_ns_table01 with metadataBefore null, metadataAfter org.apache.iceberg.TableMetadata@682f45eb
polaris-1        | 2025-10-14 04:26:14,568 DEBUG [org.apa.pol.cor.per.res.PolarisResolutionManifest] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Returning null for key minio_polaris_ns.minio_polaris_ns_table01 due to size mismatch from getPassthroughResolvedPath resolvedPath: [entity:name=minio_polaris_ns;id=5;parentId=3;entityVersion=1;type=NAMESPACE;subType=NULL_SUBTYPE;internalProperties={};grantRecordsAsGrantee:[];grantRecordsAsSecurable:[]], requestedPath.getEntityNames(): [minio_polaris_ns, minio_polaris_ns_table01]
polaris-1        | 2025-10-14 04:26:14,714 WARN  [org.apa.pol.ser.con.ServiceProducers] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Creating HTTP client with SSL certificate verification disabled. Use only in development!
polaris-1        | 2025-10-14 04:26:14,779 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,786 DEBUG [org.apa.pol.cor.sto.cac.StorageCredentialCache] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) key=StorageCredentialCacheKey{realmId=POLARIS, catalogId=0, storageConfigSerializedStr={"@type":"AwsStorageConfigurationInfo","allowedLocations":["s3://polaris"],"roleARN":"urn:ecs:iam::otf_dev:role/assumeSameAccountOTF","region":"us-east-1","endpoint":"https://ecmh2.td.teradata.com","pathStyleAccess":true,"stsEndpoint":"https://ecs1.td.teradata.com:4443/sts","ignoreSSLVerification":true,"storageType":"S3","fileIoImplClassName":"org.apache.iceberg.aws.s3.S3FileIO"}, allowedListAction=true, allowedReadLocations=[s3://polaris/minio_polaris_ns/minio_polaris_ns_table01], allowedWriteLocations=[s3://polaris/minio_polaris_ns/minio_polaris_ns_table01]} subscopedCredsCache
polaris-1        | 2025-10-14 04:26:14,788 DEBUG [org.apa.pol.cor.sto.cac.StorageCredentialCache] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) StorageCredentialCache::load
polaris-1        | 2025-10-14 04:26:14,790 DEBUG [org.apa.pol.ser.con.DefaultConfigurationStore] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Get configuration value for STORAGE_CREDENTIAL_DURATION_SECONDS with realm POLARIS
polaris-1        | 2025-10-14 04:26:14,839 WARN  [org.apa.pol.ser.con.ServiceProducers] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Creating HTTP client with SSL certificate verification disabled. Use only in development!
polaris-1        | 2025-10-14 04:26:15,486 DEBUG [org.apa.pol.cor.sto.cac.StorageCredentialCache] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) errorMessage=Policy has invalid resource: 'arn:ecs:s3:::polaris/minio_polaris_ns/minio_polaris_ns_table01/*'
polaris-1        |  Please check the statement: {"Action":["s3:PutObject","s3:DeleteObject"],"Resource":"arn:ecs:s3:::polaris\/minio_polaris_ns\/minio_polaris_ns_table01\/*","Effect":"Allow"}
polaris-1        |  (Service: Sts, Status Code: 400, Request ID: 0a00078d:196f956a4f3:4b6bf:0-none) (SDK Attempt Count: 1) Failed to get subscoped credentials
polaris-1        | 2025-10-14 04:26:15,487 DEBUG [org.apa.pol.ser.cat.ice.IcebergCatalogAdapter] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) RuntimeException while operating on catalog. Propagating to caller.: org.apache.iceberg.exceptions.UnprocessableEntityException: Failed to get subscoped credentials: Policy has invalid resource: 'arn:ecs:s3:::polaris/minio_polaris_ns/minio_polaris_ns_table01/*'
polaris-1        |  Please check the statement: {"Action":["s3:PutObject","s3:DeleteObject"],"Resource":"arn:ecs:s3:::polaris\/minio_polaris_ns\/minio_polaris_ns_table01\/*","Effect":"Allow"}
polaris-1        |  (Service: Sts, Status Code: 400, Request ID: 0a00078d:196f956a4f3:4b6bf:0-none) (SDK Attempt Count: 1)
polaris-1        |      at org.apache.polaris.core.storage.cache.StorageCredentialCache.lambda$getOrGenerateSubScopeCreds$2(StorageCredentialCache.java:151)
polaris-1        |      at com.github.benmanes.caffeine.cache.BoundedLocalCache.lambda$doComputeIfAbsent$0(BoundedLocalCache.java:2690)
polaris-1        |      at java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1916)
polaris-1        |      at com.github.benmanes.caffeine.cache.BoundedLocalCache.doComputeIfAbsent(BoundedLocalCache.java:2688)
polaris-1        |      at com.github.benmanes.caffeine.cache.BoundedLocalCache.computeIfAbsent(BoundedLocalCache.java:2670)
polaris-1        |      at com.github.benmanes.caffeine.cache.LocalCache.computeIfAbsent(LocalCache.java:112)
polaris-1        |      at com.github.benmanes.caffeine.cache.LocalManualCache.get(LocalManualCache.java:63)
polaris-1        |      at org.apache.polaris.core.storage.cache.StorageCredentialCache.getOrGenerateSubScopeCreds(StorageCredentialCache.java:153)
polaris-1        |      at org.apache.polaris.core.storage.cache.ServiceProducers_ProducerMethod_storageCredentialCache_hzAWPa00ffa2II6zBfUMmDXk9AQ_ClientProxy.getOrGenerateSubScopeCreds(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.io.FileIOUtil.refreshAccessConfig(FileIOUtil.java:109)
polaris-1        |      at org.apache.polaris.service.catalog.io.DefaultFileIOFactory.lambda$loadFileIO$0(DefaultFileIOFactory.java:102)
polaris-1        |      at java.base/java.util.Optional.map(Optional.java:260)
polaris-1        |      at org.apache.polaris.service.catalog.io.DefaultFileIOFactory.loadFileIO(DefaultFileIOFactory.java:100)
polaris-1        |      at org.apache.polaris.service.catalog.io.DefaultFileIOFactory_ClientProxy.loadFileIO(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalog.loadFileIOForTableLike(IcebergCatalog.java:2040)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalog$BasePolarisTableOperations.doCommit(IcebergCatalog.java:1431)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalog$BasePolarisTableOperations.commit(IcebergCatalog.java:1324)
polaris-1        |      at org.apache.iceberg.BaseMetastoreCatalog$BaseMetastoreCatalogTableBuilder.create(BaseMetastoreCatalog.java:201)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalogHandler.createTableDirect(IcebergCatalogHandler.java:463)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter.lambda$createTable$6(IcebergCatalogAdapter.java:394)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter.withCatalog(IcebergCatalogAdapter.java:209)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter.createTable(IcebergCatalogAdapter.java:378)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter_Subclass.createTable$$superforward(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergRestCatalogEventServiceDelegator_Gj_WCptqTcdHu-fbZfgVkAwPXCI_Delegate_Subclass.createTable(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergRestCatalogEventServiceDelegator.createTable(IcebergRestCatalogEventServiceDelegator.java:217)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter_Subclass.createTable(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.iceberg.IcebergCatalogAdapter_ClientProxy.createTable(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.api.IcebergRestCatalogApi.createTable(IcebergRestCatalogApi.java:193)
polaris-1        |      at org.apache.polaris.service.catalog.api.IcebergRestCatalogApi_Subclass.createTable$$superforward(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.api.IcebergRestCatalogApi_Subclass$$function$$3.apply(Unknown Source)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext$NextAroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:97)
polaris-1        |      at io.smallrye.faulttolerance.FaultToleranceInterceptor.lambda$syncFlow$8(FaultToleranceInterceptor.java:364)
polaris-1        |      at io.smallrye.faulttolerance.core.Future.from(Future.java:85)
polaris-1        |      at io.smallrye.faulttolerance.FaultToleranceInterceptor.lambda$syncFlow$9(FaultToleranceInterceptor.java:364)
polaris-1        |      at io.smallrye.faulttolerance.core.FaultToleranceContext.call(FaultToleranceContext.java:20)
polaris-1        |      at io.smallrye.faulttolerance.core.Invocation.apply(Invocation.java:29)
polaris-1        |      at io.smallrye.faulttolerance.core.metrics.MetricsCollector.apply(MetricsCollector.java:98)
polaris-1        |      at io.smallrye.faulttolerance.FaultToleranceInterceptor.syncFlow(FaultToleranceInterceptor.java:367)
polaris-1        |      at io.smallrye.faulttolerance.FaultToleranceInterceptor.intercept(FaultToleranceInterceptor.java:205)
polaris-1        |      at io.smallrye.faulttolerance.FaultToleranceInterceptor_Bean.intercept(Unknown Source)
polaris-1        |      at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:70)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext$NextAroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:97)
polaris-1        |      at io.quarkus.micrometer.runtime.MicrometerTimedInterceptor.timedMethod(MicrometerTimedInterceptor.java:79)
polaris-1        |      at io.quarkus.micrometer.runtime.MicrometerTimedInterceptor_Bean.intercept(Unknown Source)
polaris-1        |      at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:70)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext$NextAroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:97)
polaris-1        |      at io.quarkus.security.runtime.interceptor.SecurityHandler.handle(SecurityHandler.java:27)
polaris-1        |      at io.quarkus.security.runtime.interceptor.RolesAllowedInterceptor.intercept(RolesAllowedInterceptor.java:29)
polaris-1        |      at io.quarkus.security.runtime.interceptor.RolesAllowedInterceptor_Bean.intercept(Unknown Source)
polaris-1        |      at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:70)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
polaris-1        |      at io.quarkus.resteasy.reactive.server.runtime.StandardSecurityCheckInterceptor.intercept(StandardSecurityCheckInterceptor.java:44)
polaris-1        |      at io.quarkus.resteasy.reactive.server.runtime.StandardSecurityCheckInterceptor_RolesAllowedInterceptor_Bean.intercept(Unknown Source)
polaris-1        |      at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
polaris-1        |      at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
polaris-1        |      at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
polaris-1        |      at org.apache.polaris.service.catalog.api.IcebergRestCatalogApi_Subclass.createTable(Unknown Source)
polaris-1        |      at org.apache.polaris.service.catalog.api.IcebergRestCatalogApi$quarkusrestinvoker$createTable_01f5a1bd6d7815fd3314a553161c943c8cd03101.invoke(Unknown Source)
polaris-1        |      at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
polaris-1        |      at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:183)
polaris-1        |      at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
polaris-1        |      at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:645)
polaris-1        |      at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2651)
polaris-1        |      at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2630)
polaris-1        |      at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1622)
polaris-1        |      at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1589)
polaris-1        |      at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
polaris-1        |      at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
polaris-1        |      at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
polaris-1        |      at java.base/java.lang.Thread.run(Thread.java:1583)
polaris-1        | 
polaris-1        | 2025-10-14 04:26:15,521 INFO  [org.apa.pol.ser.exc.IcebergExceptionMapper] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Handling runtimeException Failed to get subscoped credentials: Policy has invalid resource: 'arn:ecs:s3:::polaris/minio_polaris_ns/minio_polaris_ns_table01/*'
polaris-1        |  Please check the statement: {"Action":["s3:PutObject","s3:DeleteObject"],"Resource":"arn:ecs:s3:::polaris\/minio_polaris_ns\/minio_polaris_ns_table01\/*","Effect":"Allow"}
polaris-1        |  (Service: Sts, Status Code: 400, Request ID: 0a00078d:196f956a4f3:4b6bf:0-none) (SDK Attempt Count: 1)
polaris-1        | 2025-10-14 04:26:15,532 DEBUG [org.apa.pol.ser.exc.IcebergExceptionMapper] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Full RuntimeException
polaris-1        | 2025-10-14 04:26:15,534 DEBUG [org.apa.pol.ser.exc.IcebergExceptionMapper] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) Mapped exception to errorResp: org.jboss.resteasy.reactive.common.jaxrs.ResponseImpl@278d1835
polaris-1        | 2025-10-14 04:26:15,536 INFO  [io.qua.htt.access-log] [900612a0-c9f1-4262-b2a3-74ab5079117c_0000000000000000006,POLARIS] [,,,] (executor-thread-1) 172.18.0.1 - root [14/Oct/2025:04:26:15 +0000] "POST /api/catalog/v1/quickstart_catalog/namespaces/minio_polaris_ns/tables HTTP/1.1" 422 501
polaris-1        | 2025-10-14 04:40:32,165 INFO  [io.quarkus] [,] [,,,] (main) Apache Polaris Server (incubating) stopped in 0.034s
polaris-1 exited with code 143
curl --location 'http://localhost:8181/api/catalog/v1/quickstart_catalog/namespaces/minio_polaris_ns/tables' -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' -H 'Polaris-Realm: POLARIS' --data '{
  "name": "minio_polaris_ns_table01",
  "schema": {
    "type": "struct",
    "fields": [
      {
        "id": 0,
        "name": "id",
        "type": "string",
        "required": true,
        "doc": "car model"
      },
      {
        "id": 1,
        "name": "first_name",
        "type": "string",
        "required": true,
        "doc": "first name"
      }
    ]
  }
}' | jq
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   882  100   501  100   381    470    358  0:00:01  0:00:01 --:--:--   829
{
  "error": {
    "message": "Failed to get subscoped credentials: Policy has invalid resource: 'arn:ecs:s3:::polaris/minio_polaris_ns/minio_polaris_ns_table01/*'\n Please check the statement: {\"Action\":[\"s3:PutObject\",\"s3:DeleteObject\"],\"Resource\":\"arn:ecs:s3:::polaris\\/minio_polaris_ns\\/minio_polaris_ns_table01\\/*\",\"Effect\":\"Allow\"}\n (Service: Sts, Status Code: 400, Request ID: 0a00078d:196f956a4f3:4b6bf:0-none) (SDK Attempt Count: 1)",
    "type": "UnprocessableEntityException",
    "code": 422
  }
}

Does this PR introduce any user-facing change?

  • NO

How was this patch tested?

  • Running full gradle build and test
  • The updated CatalogEntityTest snippets indicate tests that:
    • Exercise invalid ARN inputs (empty, malformed, aws-cn) and expect specific exception messages.
    • Verify urn-style ECS role ARNs are accepted (e.g., "urn:ecs:iam::test-namespace:role/test-role").
    • Cover generation/round-trip serialization of AwsStorageConfigInfo and ensure storage config properties (like endpoint, stsEndpoint, pathStyleAccess) are present or absent in JSON as expected.
  • The code changes align with these tests by:
    • Ensuring the validation messages are explicit and match test expectations.
    • Producing policies that are valid for both AWS and ECS on-prem S3-compatible IAM implementations.

CHANGELOG.md

Copy link
Contributor

@dimas-b dimas-b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution, @rohangoli ! It looks like the current form of this PR might work, but I'm hesitant to approve it as the code does not look elegant. Would you be open to refactoring it?

// not be purely numeric (must start with a letter, underscore or hyphen followed by allowed
// chars).
public static final String ROLE_ARN_PATTERN =
"^(arn|urn):(aws|aws-us-gov|ecs):iam::((\\d{12})|([a-zA-Z_-][a-zA-Z0-9_-]*)):role/.+$";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the ([a-zA-Z_-][a-zA-Z0-9_-]*) part apply only to ECS?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ECS is accepting "May contain lowercase a to z, 0 to 9, dash (-), and underscore (_). Max 128 characters." this part as 12-digit AWS Account Number equivalent

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I was trying to say is that expanding this RegEx to cover all vendors does not seem maintainable. As I commented in another thread, I wonder if we could refactor the code to have ECS-specific login in separate classes 🤔

Matcher matcher = ROLE_ARN_PATTERN_COMPILED.matcher(arn);
checkState(matcher.matches());
return matcher.group(2);
// group(3) is the account identifier (either 12-digit AWS account or vendor namespace)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The getAwsAccountId method name becomes misleading now that the value may not be an AWS accound ID. Please rename.

// that include the path portion (bucket/key/*). For those, scope object permissions
// to
// the whole bucket (bucket/*) and rely on s3:prefix conditions for finer granularity.
if (isEcsPartition) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to avoid if/else statements by using a more OO design. This feels like ECS is not quite the same as AWS. Supporting ECS probably requires a sub-type property in the config and a different storage integration sub-class (with proper refactoring of shared code into a common class).

Copy link
Contributor

@dimas-b dimas-b Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may be worth discussing on the dev ML.

@dimas-b
Copy link
Contributor

dimas-b commented Oct 15, 2025

How can this be tested?

@rohangoli
Copy link
Author

How can this be tested?

This can be tested via installing or deploying Dell ECS / OBS https://github.com/EMCECS/ECS-CommunityEdition/tree/4.1.0.0

@dimas-b
Copy link
Contributor

dimas-b commented Oct 16, 2025

@rohangoli : Thanks for the pointer to the ECS CommunityEdition!

I had a quick look at their README, but it does not seem that there is a docker image for the Community Edition. Install guides appear to refer to building from source (which would be cumbersome for CI). WDYT?

Copy link
Member

@snazy snazy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wondering if it's better to split this class into an abstract class AbstractS3CredentialsStorageIntegration with DefaultS3CredentialsStorageIntegration, AwsCredentialsStorageIntegration, EcsCredentialsStorageIntegration implementations. Or at least move the ECS specific parts into a new class EcsCredentialsStorageIntegration extends AwsCredentialsStorageIntegration?

@dimas-b
Copy link
Contributor

dimas-b commented Oct 17, 2025

I wonder whether it might be worth adding a variant property to AwsStorageConfigInfo. Possible values: AWS, ECS, MinIO, Ozone, etc... For now we may only need ECS (defaulting to AWS) since MinIO does not need any special code.

@snazy
Copy link
Member

snazy commented Oct 23, 2025

How can this be tested?

This can be tested via installing or deploying Dell ECS / OBS https://github.com/EMCECS/ECS-CommunityEdition/tree/4.1.0.0

Hm, looking at the requirements of this, it seems it's not usable in GitHub CI. The CPU, RAM and disk requirements largely exceed the Standard GitHub-hosted runner specs.

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.

3 participants