Skip to content

Conversation

dimas-b
Copy link
Contributor

@dimas-b dimas-b commented Sep 29, 2025

This is a follow-up change to #2672 striving to improve user-facing error reporting for S3 storage systems without STS.

  • Add property to AccessConfig to indicate whether the backing storage integration can produce credentials.

  • Add a check to IcebergCatalogHandler (leading to 400) that storage credentials are vended when requested and the backend is capable of vending credentials in principle.

  • Update PolarisStorageIntegrationProviderImpl to indicate that FILE storage does not support credential vending (requesitng redential vending with FILE storage does not produce any credentials and does not flag an error, which matches current Polaris behaviour).

  • Only those S3 systems where STS is not available (or disabled / not permitted) are affected.

  • Other storage integrations are not affected by this PR.

tableIdentifier, tableMetadata, actions, refreshCredentialsEndpoint);
Map<String, String> credentialConfig = accessConfig.credentials();
if (!credentialConfig.isEmpty() && delegationModes.contains(VENDED_CREDENTIALS)) {
if (delegationModes.contains(VENDED_CREDENTIALS)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks @dimas-b for the change. But I think this is not the right place to check. SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION is mainly for POC or test env, where we allow Polaris to skip credential vending no matter what clients ask.

I believe the right place to check is in AwsCredentialsStorageIntegration::getSubscopedCreds(). Clients ask for credential vending, but this storage doesn't have the capability to do so.

Copy link
Contributor Author

@dimas-b dimas-b Sep 30, 2025

Choose a reason for hiding this comment

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

AwsCredentialsStorageIntegration.getSubscopedCreds() may be called when STS is disabled (so no credentials will be vended). It's a valid use case for non-AWS S3 storage. Clients still need non-credential config from the "storage integration" code (e.g. endpoints).

Copy link
Contributor

@flyrain flyrain Sep 30, 2025

Choose a reason for hiding this comment

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

We should put the check within if (shouldUseSts(storageConfig)) { ... }, sorry, the method shouldUseSts() itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@flyrain : could you propose pseudo-code (or java example) for this check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated. PTAL.

dimas-b added a commit to dimas-b/polaris that referenced this pull request Sep 30, 2025
This is follow-up bugfix for apache#2589

The bugfix part apache#2711 is extracted here since apache#2711 proved to be
non-trivial and may require extra time.

* Use the `delegationModes` method parameter as intended (as opposed
  to a local constant).
dimas-b added a commit that referenced this pull request Sep 30, 2025
…2713)

This is follow-up bugfix for #2589

The bugfix part #2711 is extracted here since #2711 proved to be
non-trivial and may require extra time.

* Use the `delegationModes` method parameter as intended (as opposed
  to a local constant).
@dimas-b dimas-b force-pushed the enforce-vended-creds-presence branch from 049867d to 68ccb0e Compare September 30, 2025 04:39
"warehouse": test_catalog.name,
"credential": f"{test_principal.principal.client_id}:{test_principal.credentials.client_secret.get_secret_value()}",
"scope": "PRINCIPAL_ROLE:ALL",
"header.X-Iceberg-Access-Delegation": "vended-credentials",
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

@singhpk234 singhpk234 left a comment

Choose a reason for hiding this comment

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

Thank you @dimas-b !

CHANGELOG.md Outdated
- The EclipseLink Persistence implementation has been deprecated since 1.0.0 and will be completely removed
in 1.3.0 or in 2.0.0 (whichever happens earlier).
- Client requests for vended credentials will fail by default if no credentials are available (they used to return
no credentials). This can happen with FILE and S3 storage that does not have STS. Clients should normally be updated
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
no credentials). This can happen with FILE and S3 storage that does not have STS. Clients should normally be updated
no credentials). This can happen with FILE and S3 compatible storage that does not have STS. Clients should normally be updated

Copy link
Contributor Author

@dimas-b dimas-b Sep 30, 2025

Choose a reason for hiding this comment

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

AWS S3 may be used without STS (admin's choice).

How about This can happen with FILE and S3 storage if STS is not available or disabled (not permitted).?

Copy link
Contributor

@singhpk234 singhpk234 Sep 30, 2025

Choose a reason for hiding this comment

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

SG ! for my understanding, when is the case when its actual S3 but we don't credential vending ? is it for case where the client already has credentials to work on storage, but then would they be sending the header ? or we just want admins to have this knob

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Admins sometimes put restrictions on various policies / permissions even in AWS where STS endpoints are available.

Clients should not request vended credentials when they are known to be unavailable. The extra check is basically to make this kind of error more visible, I guess.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A changelog entry is not needed for the reworked changeset... WDYT?

Comment on lines 57 to 62
@Test
@Override
@Disabled // Polaris does not provide credentials for FILE storage
public void testLoadCredentials() {
super.testLoadCredentials();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

should we run these test with the config to allow empty creds on ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is no longer disabled.

@dimas-b
Copy link
Contributor Author

dimas-b commented Sep 30, 2025

It looks like the ripple effects of validating that vended credentials are available at the REST API levels are too wide.

I'll reset this PR and take a different approach (as @flyrain suggested).

@dimas-b dimas-b force-pushed the enforce-vended-creds-presence branch from cc52cad to ee9b6f7 Compare October 1, 2025 02:07
@dimas-b dimas-b changed the title Enforce that credentials are vended when requested Enforce that S3 credentials are vended when requested Oct 1, 2025
@dimas-b
Copy link
Contributor Author

dimas-b commented Oct 1, 2025

Reworked this PR completely. Please review again.

allowedWriteLocations,
refreshCredentialsEndpoint);
refreshCredentialsEndpoint,
credentialsRequired);
Copy link
Contributor

Choose a reason for hiding this comment

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

[non-blocker] I think this implies some extra cache miss for azure and gcp where credentialsRequired does not make any difference.

Do we have some general use-case of the credentialsRequired on gcp and azure, such that we could unify the credential existence check at storageCredentialCache, such that the persistence/credentialVendor just do its best effort to generate an access config, and let the cache api to decide whether the result is valid?

Copy link
Contributor Author

@dimas-b dimas-b Oct 1, 2025

Choose a reason for hiding this comment

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

Good point about cache 🤔 Thx!

Copy link
Contributor Author

@dimas-b dimas-b Oct 1, 2025

Choose a reason for hiding this comment

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

Do we have some general use-case of the credentialsRequired on gcp and azure

My first attempt in this PR was do enforce credential presence close to the REST level, but it proved to have too wide a ripple effect because many use cases (including PyIceberg) request credential vending by default and that breaks on FILE storage.

I'll see if I can refactor the code to maintain cache validity, but still delegate config validation to storage integrations.


if (shouldUseSts(storageConfig)) {
boolean shouldUseSts = shouldUseSts(storageConfig);
Preconditions.checkArgument(
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this error will be wrapped in to an error SubScopedResult and finally be thrown as UnprocessableEntityException in the StorageCredentialCache line 155. Just check if this is intended

Copy link
Contributor Author

Choose a reason for hiding this comment

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

On the java client side it shows up as org.apache.iceberg.exceptions.RESTException: Unable to process: Failed to get subscoped credentials: Credential vending was requested, but STS is not available. Is that reasonable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the REST response it is indeed a 422 with type = UnprocessableEntityException

Copy link
Contributor

@HonahX HonahX Oct 1, 2025

Choose a reason for hiding this comment

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

Sorry to clarify, I think this is ok since 422 implies the same error will occur again if client retries, which is the current case. But in the PR description

Add checks to AwsCredentialsStorageIntegration (leading to 400) that S3 storage credentials are vended when requested.

says this check will lead to 400. So just point out in case it is intended to be 400 : )

Copy link
Contributor Author

@dimas-b dimas-b Oct 2, 2025

Choose a reason for hiding this comment

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

Good catch - thx! I'm reworking the impl. again... it will be 400 / IllegalArgumentException at the REST level.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Re-implemented. PTAL.

@dimas-b dimas-b force-pushed the enforce-vended-creds-presence branch from 11f909f to cc5036f Compare October 2, 2025 02:33
@dimas-b
Copy link
Contributor Author

dimas-b commented Oct 2, 2025

I revamped this PR again 😅 Since there were too many "undo" changes, I squashed and force-pushed. Sorry about losing change history, but I think this revision is has the smallest "diff" so far 😉 Please review again.

@dimas-b dimas-b requested a review from HonahX October 2, 2025 02:36
@dimas-b dimas-b force-pushed the enforce-vended-creds-presence branch from cc5036f to 10b7187 Compare October 2, 2025 14:54
Comment on lines 116 to 117
public void validateCredentials(
@Nonnull AccessConfig accessConfig, boolean credentialsRequired) {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems this is not used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for catching this and sorry about leftovers from previous code revisions 😓 ... removed.

PolarisStorageIntegration<PolarisStorageConfigurationInfo> storageIntegration =
ms.loadPolarisStorageIntegrationInCurrentTxn(callCtx, reloadedEntity.getEntity());

storageIntegration.config();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we could remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed

This is a follow-up change to apache#2672 striving to improve user-facing error reporting for S3 storage systems without STS.

* Add property to `AccessConfig` to indicate whether the backing storage integration can produce credentials.

* Add a check to `IcebergCatalogHandler` (leading to 400) that storage credentials are vended when requested and the backend is capable of vending credentials in principle.

* Update `PolarisStorageIntegrationProviderImpl` to indicate that FILE storage does not support credential vending (requesitng redential vending with FILE storage does not produce any credentials and does not flag an error, which matches current Polaris behaviour).

* Only those S3 systems where STS is not available (or disabled / not permitted) are affected.

* Other storage integrations are not affected by this PR.
@dimas-b dimas-b force-pushed the enforce-vended-creds-presence branch from 10b7187 to 9169873 Compare October 3, 2025 16:55
@dimas-b dimas-b requested a review from HonahX October 3, 2025 17:27
Copy link
Contributor

@HonahX HonahX left a comment

Choose a reason for hiding this comment

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

LGTM! Thanks @dimas-b for adding the enforcement!

Comment on lines +818 to +821
Preconditions.checkArgument(
!accessConfig.supportsCredentialVending() || skipCredIndirection,
"Credential vending was requested for table %s, but no credentials are available",
tableIdentifier);
Copy link
Contributor

Choose a reason for hiding this comment

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

WDYT of moving this check to getAccessConfig /FileIOUtil.refreshAccessConfig in the later refactoring PR: #2736, and we probably do not need the additional supportsCredentialVending field in AccessConfig, just adding an additional arg to let caller decide whether to require the credential to be vended.

But I think that should be in a follow-up and after the 1.2.0 cut to avoid additional noise on the release. If I understand correctly, we do not offer backward compatibility of these inner interface. So we could do this if needed in the next release

Copy link
Contributor Author

@dimas-b dimas-b Oct 3, 2025

Choose a reason for hiding this comment

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

Sounds reasonable to me.

TBH, I do not like AccessConfig.supportsCredentialVending(), but it seemed to be the simplest way to make the check without breaking other things 😅

@github-project-automation github-project-automation bot moved this from PRs In Progress to Ready to merge in Basic Kanban Board Oct 3, 2025
@dimas-b dimas-b merged commit 927bb5e into apache:main Oct 3, 2025
16 of 17 checks passed
@github-project-automation github-project-automation bot moved this from Ready to merge to Done in Basic Kanban Board Oct 3, 2025
@dimas-b dimas-b deleted the enforce-vended-creds-presence branch October 3, 2025 22:05
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.

4 participants