Core, OpenApi: Add X-Iceberg-Client-Capabilities header#16394
Core, OpenApi: Add X-Iceberg-Client-Capabilities header#16394singhpk234 wants to merge 1 commit into
Conversation
Introduces a new HTTP header that lets REST clients advertise their supported capabilities to the catalog server on every request. * New ClientCapability enum (vended-credentials, remote-signing, scan-planning) as the single source of truth for supported capabilities, with javadoc describing the protocol each capability implies. * HTTPClient sets X-Iceberg-Client-Capabilities statically in build() alongside X-Client-Version and X-Client-Git-Commit-Short, so the header is included on every request and overrides any user-supplied header.* property. * OpenAPI client-capabilities parameter component documents the defined values without an enum constraint, allowing new capabilities to be added without schema changes. The header is optional; servers must not fail if it is absent.
eb2cb6f to
b453c26
Compare
steveloughran
left a comment
There was a problem hiding this comment.
commented as someone who has read far too many RFCs.
| - `scan-planning`: The client supports server-side scan planning. | ||
|
|
||
|
|
||
| Clients should include all capabilities they support. Servers must |
There was a problem hiding this comment.
capitalisation; clarify "fail"
Clients SHOULD include all capabilities they support. Servers MUST
treat this header as optional and SHALL NOT reject the request if it is absent.
| treat this header as optional and must not fail if it is absent. | ||
|
|
||
|
|
||
| Client SDKs that support this header should set it statically and |
|
|
||
| Client SDKs that support this header should set it statically and | ||
| include it on every request. Clients that do not yet support this | ||
| header statically can configure it via client side headers. |
| summary: Create a namespace | ||
| parameters: | ||
| - $ref: '#/components/parameters/idempotency-key' | ||
| - $ref: '#/components/parameters/client-capabilities' |
There was a problem hiding this comment.
Is there a reason why we are adding client capabilities header to /v1/{prefix}/namespaces?
read-restrictions, vended-credentials and remote-signing are not capabilities related to namespace maintenance requests. Would it make more sense to leave it out until capability negotiation is needed for namespaces?
| Defined capability values: | ||
|
|
||
| - `vended-credentials`: The client supports receiving and using | ||
| storage credentials vended by the catalog server. | ||
|
|
||
| - `remote-signing`: The client supports delegating request signing | ||
| to a remote signing service provided by the catalog server. | ||
|
|
||
| - `scan-planning`: The client supports server-side scan planning. |
There was a problem hiding this comment.
I wonder if these capability values should include a major compatibility version, since values like read-restrictions may evolve in ways that older clients cannot safely consume. Would read-restrictions.v1 make more sense, so that incompatible future semantics can be represented as read-restrictions.v2?
This would allow us to introduce a new column mask subtype in read-restrictions without worrying about breaking the existing capability header contract, by simply introducing a new capability version.
Summary
Introduces a new
X-Iceberg-Client-CapabilitiesHTTP header that lets REST clientsadvertise the capabilities they support to the catalog server. The header is
informational, sent on every catalog request, and is intended as a forward-compatibility
mechanism — not a security mechanism.
This was brought up at the Read Restrictions community sync on May 12, 2026
(recording); a dev list thread is being raised
in parallel for broader discussion.
Motivation
Iceberg's REST protocol keeps evolving — server-side scan planning, vended
credentials, remote signing, and the in-flight fine-grained access control
proposal (#13879) are all features that catalogs may return but older clients
can't handle. Today there's no standard way for a client to declare "I
understand X" to the server. This PR introduces a single, generic mechanism
for the client to declare its capability set up front.
The header pattern mirrors
X-Client-VersionandX-Client-Git-Commit-Short(already added on every request via
HTTPClient.baseHeaders) — it is a stableSDK-attribute hint, not a per-request preference.
Design notes
Forward-compat hint, not security. The header is informational — clients
can trivially spoof its value, so servers MUST NOT base trust or
authorization decisions on it. Trust establishment (mTLS, OAuth, etc.) is
out of scope. The parameter description in the spec calls this out
explicitly so it can't be missed.
enum:constraint on the schema. Mirrors the existingX-Iceberg-Access-Delegationparameter. Adding a new capability is aone-line spec edit. Generated clients can validate values; servers get a
machine-readable closed list of recognized tokens.
Independent of
X-Iceberg-Access-Delegation. Despite token overlap(
vended-credentials,remote-signingappear in both), the headers carrydifferent semantics:
data-accessis a per-request preference ("I wantthis for this call");
client-capabilitiesis a static SDK attribute("I am built to handle this").
Excluded from
/v1/oauth/tokens. OAuth token endpoints may be servedby external IdPs (Okta, Auth0, etc.) where Iceberg-specific headers are
noise. Mirrors how
X-Iceberg-Access-Delegationis handled.SDK overrides user config. The Java SDK's static value overrides any
user-configured
header.X-Iceberg-Client-Capabilitiesproperty — samepattern as the existing
X-Client-Version/X-Client-Git-Commit-Shortheaders. Pinned by an explicit test.
Future work
read-restrictionsto the enum once [SPEC] Add finer grained read restrictions as part of loadTable #13879 (FGAC) lands. The framingin that PR's review (catalogs MUST NOT return read-restrictions to
clients that don't advertise the capability) depends on this header being
available.
the same capability set.
Changes from the prior draft: