Access-delegation fallback to remote-signing is rejected with HTTP 400 instead of returning the table without delegation
- Dominant language
- Java
- Stars
- 2.1k
- Forks
- 522
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 137
Description
### Describe the bug
When a client offers both delegation mechanisms (`X-Iceberg-Access-Delegation: vended-credentials,remote-signing`) and Polaris cannot vend credentials for the catalog, `DefaultAccessDelegationModeResolver` intentionally degrades to `REMOTE_SIGNING`; its unit tests (`AccessDelegationModeResolverTest`) assert exactly this fallback.
Remote signing is not implemented, and `IcebergCatalogHandler.resolveAccessDelegationModes` then rejects the resolved mode with a `Preconditions.checkArgument`, so the request fails with `400 Unsupported access delegation mode: REMOTE_SIGNING`.
The Iceberg REST spec describes the header as an optional signal: "The server may choose to supply access via any or none of the requested mechanisms" (iceberg-rest-catalog-open-api.yaml, X-Iceberg-Access-Delegation).
The correct response is the normal LoadTableResult without `storage-credentials`, not an error. The resolver and the handler disagree on what the REMOTE_SIGNING fallback means.
Affected operations: loadTable, createTable, updateTable, registerTable (all call `resolveAccessDelegationModes`).
Triggering conditions (any one of them):
- S3 catalog with `stsUnavailable: true` (the documented on-prem / S3-compatible flow)
- external catalog with `ALLOW_EXTERNAL_CATALOG_CREDENTIAL_VENDING=false`
- federated catalog with `ALLOW_FEDERATED_CATALOGS_CREDENTIAL_VENDING=false`
- realm with `SKIP_CREDENTIAL_SUBSCOPING_INDIRECTION=true`
### To Reproduce
1. Create an S3 catalog with `stsUnavailable: true` (e.g. the RustFS quickstart with that flag set in the storage config)
2. Create a namespace `ns` and a table `t`
3. curl -i -H "Authorization: Bearer $TOKEN" \
-H "X-Iceberg-Access-Delegation: vended-credentials,remote-signing" \
"http://localhost:8181/api/catalog/v1//namespaces/ns/tables/t"
### Actual Behavior
```
HTTP/1.1 400
"error":{"type":"IllegalArgumentException","message":"Unsupported access delegation mode: REMOTE_SIGNING"}}
```
The same request without the header, or with only `vended-credentials`, behaves as documented (the latter fails with "no credentials are available", which is expected for a catalog that cannot vend).
### Expected Behavior
HTTP/1.1 200 with the table metadata and no delegated access: no `storage-credentials`, no vended config entries, and no `client.refresh-credentials-endpoint`. In other words, the same response as for a request that did not send the header.
### Additional context
Related finding while verifying the fix: the degraded response also advertised `client.refresh-credentials-endpoint`, because the adapter derives it from the requested header before the mode is resolved. A response without vended credentials should not advertise a refresh endpoint; this belongs to the same fix.
Open design point for maintainers: a request for `remote-signing` alone cannot be satisfied in any form the client offered, so keeping the 400 for that single-mode case until remote signing exists seems reasonable.
A strict reading of the spec would also allow falling back to no delegation there. Happy to follow either.
Not a duplicate of #32 / #3091 (implement remote signing), #2351 (registerTable honoring delegation), #5050 (explicit no-vending mode for Azure). Fix with handler unit tests and an integration test against an S3 catalog without STS is ready; PR to follow.
### System information
Polaris main @ 715cf86ff6 (1.8.0-SNAPSHOT), Iceberg 1.11.0. Backend-independent; reproduced with the in-memory and Relational JDBC metastores against an S3-compatible store without STS.
Contributor guide
Research direction
Start with IcebergCatalogHandler.resolveAccessDelegationModes, DefaultAccessDelegationModeResolver, and AccessDelegationModeResolverTest to trace the fallback. Run the handler unit tests and the S3 integration scenario described in the issue. Done means multi-mode requests return the normal table response without delegated credentials or a refresh endpoint, while the single remote-signing case follows the maintainers' decision.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100