docs: add production configuration pages for AWS S3 and Azure Blob storage (#1325) - #4451
Conversation
…orage Adds two new pages under configuring-polaris-for-production that mirror the existing GCS page and walk a system administrator through end-to-end storage backend setup: - configuring-aws-s3-cloud-storage-specific.md: IAM role, trust policy (userArn/externalId), KMS settings, S3-compatible endpoint options (endpoint/pathStyleAccess/stsUnavailable), and Spark/Trino/PyIceberg client wiring. - configuring-azure-blob-cloud-storage-specific.md: multi-tenant app consent flow (tenantId/multiTenantAppName/consentUrl), HNS-aware SAS token scoping, and ADLS Gen2 client wiring. Fields used in the examples match AwsStorageConfigurationInfo and AzureStorageConfigurationInfo. Refs: apache#1325 Signed-off-by: mj006648 <uckdekf@gmail.com>
Add oauth2-server-uri and token-refresh-enabled=false to the Spark spark-sql examples on the AWS S3 and Azure Blob storage pages. These match the property set used by the existing MinIO / RustFS guides, which is the configuration verified end-to-end against a local polaris+minio docker stack while preparing these docs. The oauth2-server-uri is also called out in prose because the Iceberg REST client logs a deprecation warning when the fallback path is used. Refs: apache#1325 Signed-off-by: mj006648 <uckdekf@gmail.com>
Replace the multi-tenant 'consent URL' framing with the service-principal flow that self-hosted Polaris deployments actually use. Polaris loads credentials via DefaultAzureCredential (AzureCredentialsStorageIntegration), so the docs now show 'az ad sp create-for-rbac' with Storage Blob Data Contributor and the three AZURE_* environment variables on the server. multiTenantAppName / consentUrl are still mentioned but described as optional fields for managed deployments, not the primary path. Verified end-to-end against ADLS Gen2 (HNS enabled) with a service principal: catalog creation, CREATE NAMESPACE / TABLE, INSERT, SELECT all succeed through the vended SAS-token path. Refs: apache#1325 Signed-off-by: mj006648 <uckdekf@gmail.com>
…nd PyIceberg S3 page changes informed by additional end-to-end checks: - 'S3-compatible endpoints' is now split into two cases. With STS support (AWS S3, MinIO) Polaris vends short-lived credentials as before. Without STS support (Apache Ozone S3 gateway, Ceph RGW with STS disabled) the client must omit the X-Iceberg-Access-Delegation header and supply its own long-lived credentials. A test against a Ceph RGW deployment without STS produced 'Failed to get subscoped credentials' (STS 400), which is the symptom the new section now warns about. - The Trino example now includes 'iceberg.rest-catalog.vended-credentials-enabled', 'fs.native-s3.enabled', and 's3.region'/'s3.endpoint'/'s3.path-style-access'. Verified end-to-end against the MinIO compose with Trino: SHOW SCHEMAS, CREATE SCHEMA, CREATE TABLE, INSERT, SELECT all succeed. - A real PyIceberg snippet is added showing the required options, including the 'header.X-Iceberg-Access-Delegation' REST header. Verified against the same MinIO compose with pyiceberg 0.11.1. Azure page changes: - A real PyIceberg snippet is added mirroring the S3 example. - The troubleshooting bullet is split: the 'Failed to get subscoped credentials / AuthorizationPermissionMismatch' pattern now points at the data-plane RBAC role assignment, which was reproduced by removing Storage Blob Data Contributor from the service principal and observing the exact error message during INSERT. The pre-existing HNS-ACL bullet is kept for the narrower ACL-mismatch case. Refs: apache#1325 Signed-off-by: mj006648 <uckdekf@gmail.com>
S3 page: - retitle to 'Configuring S3 Storage' since the page also covers MinIO, Ozone, Ceph and similar S3-compatible backends. - drop userArn from the storageConfigInfo example and the surrounding text; the field is not used by AwsStorageConfigurationInfo in current code. - recommend externalId as the default and remove the inline 'if you skip the external ID' guidance, since omitting it is not best practice and knowledgeable users can omit it on their own. - add a one-line note that the bearer token in the catalog-create curl is the Polaris admin OAuth2 token from /v1/oauth/tokens, with a relref to the parent production-config page that explains bootstrapping. - clarify the KMS section: currentKmsKey and allowedKmsKeys are processed independently in AwsCredentialsStorageIntegration, so the write key has to be included in allowedKmsKeys explicitly. IAM action wording fixed accordingly (kms:GenerateDataKey only on currentKmsKey). - reconcile the STS subsection with the page intro: STS-unsupported backends turn off vended credentials entirely, and the client must drop the X-Iceberg-Access-Delegation header rather than fall back to long-lived credentials inside the vending flow. - add a short note that this page covers native Polaris authentication; external identity providers are supported but documented elsewhere. - soften the client-side s3.* block: Polaris returns endpoint / path-style-access / region in the catalog config response, so the block is only needed where Trino requires it to be explicit (e.g. S3-compatible endpoints). Azure page: - recommend storing AZURE_CLIENT_SECRET in a Kubernetes Secret rather than as a plain env in the pod spec, and apply the same to POLARIS_BOOTSTRAP_CREDENTIALS. - rewrite the HNS bullet: HNS is not required by Polaris or Iceberg for table operations themselves; its main effect is that Polaris can downscope vended SAS tokens to the directory level rather than the container level. Atomic-commit framing removed. - add a bullet that the hierarchical field in storageConfigInfo must match the actual HNS state of the storage account, since a mismatch causes runtime access errors. - mark multiTenantAppName and consentUrl as informational only, since current Apache Polaris code does not use them when communicating with Azure APIs. Refs: apache#1325 Signed-off-by: mj006648 <uckdekf@gmail.com>
|
Thanks for the thorough review, @dimas-b! Pushed S3 page
Azure page
Re: L217 (Trino S3 block) — would be glad to drop more of it if Polaris's catalog config response is sufficient end-to-end on the Trino side. I have only verified the Trino path against MinIO with the explicit block in place; I have not tested removing it. |
|
|
||
| ```properties | ||
| s3.endpoint=https://s3.internal.example.com | ||
| s3.path-style-access=true |
There was a problem hiding this comment.
@mj006648 : Do you think this is still necessary?
|
|
||
| If `INSERT` or `SELECT` fails with a 403, the most common causes are: | ||
|
|
||
| - The IAM role's trust policy does not match the `userArn` / `externalId` Polaris is presenting. |
There was a problem hiding this comment.
Did you mean roleArn here?
- Drop the `s3.region` line and the separate `s3.endpoint` / `s3.path-style-access` block from the Trino example. Polaris already vends those keys in the LoadTable response config via StorageAccessProperty (s3.endpoint, s3.path-style-access, client.region), so they are redundant on the client. Keep `fs.native-s3.enabled=true` since it activates Trino's native S3 filesystem and is not something Polaris can vend. - Rewrite the surrounding paragraph to describe the split between what Polaris vends and what the client still has to set. - Replace the residual `userArn` reference in the 403 troubleshooting bullet with `roleArn`, matching what AwsStorageConfigurationInfo exposes to AssumeRoleRequest. Confidence: medium Scope-risk: narrow Signed-off-by: mj006648 <uckdekf@gmail.com>
|
Thanks for the second pass, @dimas-b. Pushed a follow-up. For the Trino block (L220): I traced what Polaris actually vends in the LoadTable response. From So I dropped L261: replaced Diff is +5/-13, docs-only. |
|
@mj006648 : line references to review-based changes are nice and helpful, but replying to GH comments in-thread is even nicer for humans 😉 |
| This page is limited to native Polaris authentication. External identity providers are also | ||
| supported but are not yet covered here; the configuration patterns below remain otherwise the same. | ||
|
|
||
| ## IAM role and trust policy |
There was a problem hiding this comment.
Thanks for adding it! I think there are three different IAM roles involved:
- The IAM role used for starting a new Polaris instance
- The IAM role used for creating a new catalog
- The IAM role used for vended credentials.
This section describes the third one. Would it be possible to describe the other two?
There was a problem hiding this comment.
Thanks @flyrain. Took a shot at this in 0837f0a — added an
overview section naming the three identities and a "Polaris service
identity" section covering IRSA / EC2 / static creds plus the
sts:AssumeRole policy. Also renamed the old section to "Catalog
access role and trust policy" so the labels line up.
Quick check: I read "creating a new catalog" as the IAM role that
gets bound to the catalog at creation time. If you meant the admin
permissions to call the catalogs API, let me know and I'll handle
it separately.
Verification environment used while writing the AWS S3 production configuration page (apache/polaris#4451). Credentials are MinIO-local dummy values, not real secrets. Confidence: high Scope-risk: narrow Not-tested: ./trino-catalog volume is referenced but not committed yet
Summary
Adds production configuration pages for AWS S3 and Azure Blob storage backends, mirroring the existing GCS page. Implements Option 1 of #1325 as agreed with @flyrain. GCS page enhancement and skill.md are intentionally left for follow-up PRs.
Two new pages under
site/content/in-dev/unreleased/configuration/configuring-polaris-for-production/:configuring-aws-s3-cloud-storage-specific.mdconfiguring-azure-blob-cloud-storage-specific.mdEach covers server-side
storageConfigInfofields, client wiring for Spark / Trino / PyIceberg, and a verification SQL snippet.Verified end-to-end while writing this
vended-credentials-enabledand native-S3 properties for Trino, and theheader.X-Iceberg-Access-DelegationREST header for PyIceberg).Failed to get subscoped credentialsSTS 400 — informed the new "Backends without STS support" subsection.Storage Blob Data Contributorremoved: reproducedAuthorizationPermissionMismatch403 — informed the Azure troubleshooting bullet.AWS IAM trust-policy / KMS specifics and HNS directory-ACL behavior are described conservatively based on docs and the corresponding Polaris classes rather than from a live test against those exact features.
Test plan